]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
htsp server: fix race for bytes_out updating
authorJaroslav Kysela <perex@perex.cz>
Tue, 5 Jan 2016 08:13:45 +0000 (09:13 +0100)
committerJaroslav Kysela <perex@perex.cz>
Tue, 5 Jan 2016 09:20:13 +0000 (10:20 +0100)
==12303== Invalid read of size 8
==12303==    at 0x455120: atomic_add_u64 (atomic.h:40)
==12303==    by 0x455120: subscription_add_bytes_out (subscriptions.c:1032)
==12303==    by 0x461524: htsp_stream_deliver (htsp_server.c:3702)
==12303==    by 0x461524: htsp_streaming_input (htsp_server.c:4085)
==12303==    by 0x507E53: _process_msg (timeshift_writer.c:340)
==12303==    by 0x507E53: timeshift_writer (timeshift_writer.c:395)
==12303==    by 0x439BB6: thread_wrapper (wrappers.c:177)
==12303==    by 0x61380A3: start_thread (pthread_create.c:309)
==12303==    by 0x693C04C: clone (clone.S:111)
==12303==  Address 0x1d04cc08 is 200 bytes inside a block of size 416 free'd
==12303==    at 0x4C29E90: free (vg_replace_malloc.c:473)
==12303==    by 0x454051: subscription_unsubscribe (subscriptions.c:647)
==12303==    by 0x4599F6: htsp_subscription_destroy (htsp_server.c:346)
==12303==    by 0x45C6FD: htsp_method_unsubscribe (htsp_server.c:2419)
==12303==    by 0x45E512: htsp_read_loop (htsp_server.c:3046)
==12303==    by 0x45E512: htsp_serve (htsp_server.c:3182)
==12303==    by 0x43D67C: tcp_server_start (tcp.c:644)
==12303==    by 0x439BB6: thread_wrapper (wrappers.c:177)
==12303==    by 0x61380A3: start_thread (pthread_create.c:309)
==12303==    by 0x693C04C: clone (clone.S:111)

src/htsp_server.c

index c7549822712b9a994ef7c1807d1eebea3f77b474..28619524c3c766be96be1b51c25c4ceb32c952de 100644 (file)
@@ -186,6 +186,8 @@ typedef struct htsp_subscription {
   int hs_sid;  /* Subscription ID (set by client) */
 
   th_subscription_t *hs_s; // Temporary
+  int                hs_s_bytes_out;
+  gtimer_t           hs_s_bytes_out_timer;
 
   streaming_target_t hs_input;
   profile_chain_t    hs_prch;
@@ -340,10 +342,15 @@ htsp_flush_queue(htsp_connection_t *htsp, htsp_msg_q_t *hmq, int dead)
 static void
 htsp_subscription_destroy(htsp_connection_t *htsp, htsp_subscription_t *hs)
 {
+  th_subscription_t *ts = hs->hs_s;
+
+  hs->hs_s = NULL;
+  gtimer_disarm(&hs->hs_s_bytes_out_timer);
+
   LIST_REMOVE(hs, hs_link);
   LIST_INSERT_HEAD(&htsp->htsp_dead_subscriptions, hs, hs_link);
 
-  subscription_unsubscribe(hs->hs_s, UNSUBSCRIBE_FINAL);
+  subscription_unsubscribe(ts, UNSUBSCRIBE_FINAL);
 
   if(hs->hs_prch.prch_st != NULL)
     profile_chain_close(&hs->hs_prch);
@@ -2278,6 +2285,16 @@ htsp_method_getTicket(htsp_connection_t *htsp, htsmsg_t *in)
   return out;
 }
 
+/*
+ *
+ */
+static void _bytes_out_cb(void *aux)
+{
+  htsp_subscription_t *hs = aux;
+  if (hs->hs_s)
+    subscription_add_bytes_out(hs->hs_s, atomic_exchange(&hs->hs_s_bytes_out, 0));
+}
+
 /**
  * Request subscription for a channel
  */
@@ -2388,6 +2405,8 @@ htsp_method_subscribe(htsp_connection_t *htsp, htsmsg_t *in)
                                              htsp->htsp_granted_access->aa_representative,
                                              htsp->htsp_clientname,
                                              NULL);
+  if (hs->hs_s)
+    gtimer_arm_ms(&hs->hs_s_bytes_out_timer, _bytes_out_cb, hs, 200);
   return NULL;
 }
 
@@ -3699,7 +3718,7 @@ htsp_stream_deliver(htsp_subscription_t *hs, th_pkt_t *pkt)
   payloadlen = pktbuf_len(pkt->pkt_payload);
   htsmsg_add_binptr(m, "payload", pktbuf_ptr(pkt->pkt_payload), payloadlen);
   htsp_send_subscription(htsp, m, pkt->pkt_payload, hs, payloadlen);
-  subscription_add_bytes_out(hs->hs_s, payloadlen);
+  atomic_add(&hs->hs_s_bytes_out, payloadlen);
 
   if(hs->hs_last_report != dispatch_clock) {