Browse Source

libobs: Fix potential race condition on shutdown

If the remove_connection call of obs_encoder_stop_internal took too
long, obs_encoder_destroy could get called before that function
completed, causing a race condition.
jp9000 6 years ago
parent
commit
131fb7b460
2 changed files with 9 additions and 5 deletions
  1. 2 0
      libobs/obs-encoder.c
  2. 7 5
      libobs/obs-video-gpu-encode.c

+ 2 - 0
libobs/obs-encoder.c

@@ -271,11 +271,13 @@ void obs_encoder_destroy(obs_encoder_t *encoder)
 
 		obs_context_data_remove(&encoder->context);
 
+		pthread_mutex_lock(&encoder->init_mutex);
 		pthread_mutex_lock(&encoder->callbacks_mutex);
 		destroy = encoder->callbacks.num == 0;
 		if (!destroy)
 			encoder->destroy_on_stop = true;
 		pthread_mutex_unlock(&encoder->callbacks_mutex);
+		pthread_mutex_unlock(&encoder->init_mutex);
 
 		if (destroy)
 			obs_encoder_actually_destroy(encoder);

+ 7 - 5
libobs/obs-video-gpu-encode.c

@@ -106,11 +106,6 @@ static void *gpu_encode_thread(void *unused)
 			encoder->cur_pts += encoder->timebase_num;
 		}
 
-		for (size_t i = 0; i < encoders.num; i++)
-			obs_encoder_release(encoders.array[i]);
-
-		da_resize(encoders, 0);
-
 		/* -------------- */
 
 		pthread_mutex_lock(&video->gpu_encoder_mutex);
@@ -131,7 +126,14 @@ static void *gpu_encode_thread(void *unused)
 
 		pthread_mutex_unlock(&video->gpu_encoder_mutex);
 
+		/* -------------- */
+
 		os_event_signal(video->gpu_encode_inactive);
+
+		for (size_t i = 0; i < encoders.num; i++)
+			obs_encoder_release(encoders.array[i]);
+
+		da_resize(encoders, 0);
 	}
 
 	da_free(encoders);