Skip to content

Commit 9943e4c

Browse files
committed
fix: prevent unlocked access to av->calls
This was introduced in 891fe60 and missed, because iteration_interval() could not be called without av- >mutex unlocked. Now both audio and video thread can. The fix moves calculating the iteration interval, including idle interval into iterate_common(...) which holds the correct mutex.
1 parent d31ab0c commit 9943e4c

File tree

1 file changed

+19
-8
lines changed

1 file changed

+19
-8
lines changed

toxav/toxav.c

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,10 @@ struct ToxAV {
108108
void *vbcb_user_data;
109109

110110
/* keep track of decode times for audio and video */
111+
112+
/* Must only be accessed from Audio thread */
111113
DecodeTimeStats audio_stats;
114+
/* Must only be accessed from Video thread */
112115
DecodeTimeStats video_stats;
113116
/** ToxAV's own mono_time instance */
114117
Mono_Time *toxav_mono_time;
@@ -253,12 +256,12 @@ Tox *toxav_get_tox(const ToxAV *av)
253256

254257
uint32_t toxav_audio_iteration_interval(const ToxAV *av)
255258
{
256-
return av->calls ? av->audio_stats.interval : IDLE_ITERATION_INTERVAL_MS;
259+
return av->audio_stats.interval;
257260
}
258261

259262
uint32_t toxav_video_iteration_interval(const ToxAV *av)
260263
{
261-
return av->calls ? av->video_stats.interval : IDLE_ITERATION_INTERVAL_MS;
264+
return av->video_stats.interval;
262265
}
263266

264267
uint32_t toxav_iteration_interval(const ToxAV *av)
@@ -276,6 +279,12 @@ uint32_t toxav_iteration_interval(const ToxAV *av)
276279
*/
277280
static void calc_interval(ToxAV *av, DecodeTimeStats *stats, int32_t frame_time, uint64_t start_time)
278281
{
282+
if (av->calls == nullptr) {
283+
// No calls active
284+
stats->interval = IDLE_ITERATION_INTERVAL_MS;
285+
return;
286+
}
287+
279288
stats->interval = frame_time < stats->average ? 0 : (frame_time - stats->average);
280289
stats->total += current_time_monotonic(av->m->mono_time) - start_time;
281290

@@ -295,15 +304,16 @@ static void iterate_common(ToxAV *av, bool audio)
295304
{
296305
pthread_mutex_lock(av->mutex);
297306

298-
if (av->calls == nullptr) {
299-
pthread_mutex_unlock(av->mutex);
300-
return;
301-
}
302-
303307
uint64_t start = current_time_monotonic(av->toxav_mono_time);
304308
// time until the first audio or video frame is over
305309
int32_t frame_time = IDLE_ITERATION_INTERVAL_MS;
306310

311+
DecodeTimeStats *stats = audio ? &av->audio_stats : &av->video_stats;
312+
313+
if (av->calls == nullptr) {
314+
goto EARLY_RETURN;
315+
}
316+
307317
for (ToxAVCall *i = av->calls[av->calls_head]; i; i = i->next) {
308318
if (!i->active) {
309319
continue;
@@ -341,7 +351,8 @@ static void iterate_common(ToxAV *av, bool audio)
341351
}
342352
}
343353

344-
DecodeTimeStats *stats = audio ? &av->audio_stats : &av->video_stats;
354+
EARLY_RETURN:
355+
345356
calc_interval(av, stats, frame_time, start);
346357
pthread_mutex_unlock(av->mutex);
347358
}

0 commit comments

Comments
 (0)