From: Jaroslav Kysela Date: Tue, 5 Jan 2016 08:13:45 +0000 (+0100) Subject: htsp server: fix race for bytes_out updating X-Git-Tag: v4.2.1~1222 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4e1a96a1a1ec08b8b70108a2fff8958a0b53fbeb;p=thirdparty%2Ftvheadend.git htsp server: fix race for bytes_out updating ==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) --- diff --git a/src/htsp_server.c b/src/htsp_server.c index c75498227..28619524c 100644 --- a/src/htsp_server.c +++ b/src/htsp_server.c @@ -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) {