From f05b7507aa28c1a320d839d5c65a72210050dc4d Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Thu, 12 Oct 2023 15:42:23 -0400 Subject: [PATCH] [mod_conference] Avoid a race in member->read_impl access The conference output loop accesses the member's read_impl while resampling. The output loop also spawns off the input loop thread, which is where the member->read_impl is actually initialised. This results in an uncommon race where the output loop sometimes gets an uninitialised member->read_impl and bails with logs something like this: 2023-10-12 18:19:01.436844 [DEBUG] conference_loop.c:1340 Setup timer soft success interval: 20 samples: 960 from codec L16 2023-10-12 18:19:01.436844 [DEBUG] conference_loop.c:1497 Outbound conference channel answered, setting CFLAG_ANSWERED 2023-10-12 18:19:01.436844 [NOTICE] switch_core_media.c:15852 Activating write resampler 2023-10-12 18:19:01.436844 [DEBUG] switch_core_media.c:16097 Engaging Write Buffer at 1920 bytes to accommodate 0->1920 2023-10-12 18:19:01.436844 [ERR] switch_core_media.c:16112 Write Buffer 0 bytes Failed! As a solution, we initialise the member->read_impl even before we start up the input loop, so that this race can never happen. --- src/mod/applications/mod_conference/conference_loop.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mod/applications/mod_conference/conference_loop.c b/src/mod/applications/mod_conference/conference_loop.c index 8f112f5453..f9b7894d0e 100644 --- a/src/mod/applications/mod_conference/conference_loop.c +++ b/src/mod/applications/mod_conference/conference_loop.c @@ -1316,15 +1316,15 @@ void conference_loop_output(conference_member_t *member) uint32_t flush_len; uint32_t low_count, bytes; call_list_t *call_list, *cp; - switch_codec_implementation_t read_impl = { 0 }, real_read_impl = { 0 }; + switch_codec_implementation_t real_read_impl = { 0 }; int sanity; - switch_core_session_get_read_impl(member->session, &read_impl); + switch_core_session_get_read_impl(member->session, &member->read_impl); switch_core_session_get_real_read_impl(member->session, &real_read_impl); channel = switch_core_session_get_channel(member->session); - interval = read_impl.microseconds_per_packet / 1000; + interval = member->read_impl.microseconds_per_packet / 1000; samples = switch_samples_per_packet(member->conference->rate, interval); //csamples = samples; tsamples = real_read_impl.samples_per_packet;