thread-pool: Add cleanup to wait for the threadpool to finish
authorOgnyan Tonchev <ognyan@axis.com>
Mon, 9 Sep 2013 09:05:26 +0000 (11:05 +0200)
committerSebastian Dröge <slomo@circular-chaos.org>
Mon, 9 Sep 2013 12:36:12 +0000 (14:36 +0200)
Also fix race condition if two threads are asking for the first
thread from the thread pool at once. This would case two internal
GThreadPools to be created.

https://bugzilla.gnome.org/show_bug.cgi?id=707753

gst/rtsp-server/rtsp-thread-pool.c
gst/rtsp-server/rtsp-thread-pool.h

index 87a035f..5907acc 100644 (file)
@@ -229,8 +229,6 @@ gst_rtsp_thread_pool_class_init (GstRTSPThreadPoolClass * klass)
 
   klass->get_thread = default_get_thread;
 
-  klass->pool = g_thread_pool_new ((GFunc) do_loop, klass, -1, FALSE, NULL);
-
   GST_DEBUG_CATEGORY_INIT (rtsp_thread_pool_debug, "rtspthreadpool", 0,
       "GstRTSPThreadPool");
 
@@ -503,8 +501,38 @@ gst_rtsp_thread_pool_get_thread (GstRTSPThreadPool * pool,
 
   klass = GST_RTSP_THREAD_POOL_GET_CLASS (pool);
 
+  /* We want to be thread safe as there might be 2 threads wanting to get new
+   * #GstRTSPThread at the same time
+   */
+  if (G_UNLIKELY (!g_atomic_pointer_get (&klass->pool))) {
+    GThreadPool *t_pool;
+    t_pool = g_thread_pool_new ((GFunc) do_loop, klass, -1, FALSE, NULL);
+    if (!g_atomic_pointer_compare_and_exchange (&klass->pool, NULL, t_pool))
+      g_thread_pool_free (t_pool, FALSE, TRUE);
+  }
+
   if (klass->get_thread)
     result = klass->get_thread (pool, type, ctx);
 
   return result;
 }
+
+/**
+ * gst_rtsp_thread_pool_cleanup:
+ *
+ * Wait for all tasks to be stopped and free all allocated resources. This is
+ * mainly used in test suites to ensure proper cleanup of internal data
+ * structures.
+ */
+void
+gst_rtsp_thread_pool_cleanup (void)
+{
+  GstRTSPThreadPoolClass *klass;
+
+  klass = GST_RTSP_THREAD_POOL_CLASS (
+      g_type_class_peek (gst_rtsp_thread_pool_get_type ()));
+  if (klass->pool != NULL) {
+    g_thread_pool_free (klass->pool, FALSE, TRUE);
+    klass->pool = NULL;
+  }
+}
index 148e73f..8165125 100644 (file)
@@ -169,6 +169,7 @@ gint                gst_rtsp_thread_pool_get_max_threads (GstRTSPThreadPool * po
 GstRTSPThread *     gst_rtsp_thread_pool_get_thread      (GstRTSPThreadPool *pool,
                                                           GstRTSPThreadType type,
                                                           GstRTSPContext *ctx);
+void                gst_rtsp_thread_pool_cleanup         (void);
 G_END_DECLS
 
 #endif /* __GST_RTSP_THREAD_POOL_H__ */