From: Ognyan Tonchev Date: Mon, 9 Sep 2013 09:05:26 +0000 (+0200) Subject: thread-pool: Add cleanup to wait for the threadpool to finish X-Git-Tag: 1.19.3~495^2~979 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=258f63b8ac9a39e313b025f014e504dd56e8bb20;p=platform%2Fupstream%2Fgstreamer.git thread-pool: Add cleanup to wait for the threadpool to finish 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 --- diff --git a/gst/rtsp-server/rtsp-thread-pool.c b/gst/rtsp-server/rtsp-thread-pool.c index 87a035f..5907acc 100644 --- a/gst/rtsp-server/rtsp-thread-pool.c +++ b/gst/rtsp-server/rtsp-thread-pool.c @@ -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; + } +} diff --git a/gst/rtsp-server/rtsp-thread-pool.h b/gst/rtsp-server/rtsp-thread-pool.h index 148e73f..8165125 100644 --- a/gst/rtsp-server/rtsp-thread-pool.h +++ b/gst/rtsp-server/rtsp-thread-pool.h @@ -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__ */