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
This commit is contained in:
Ognyan Tonchev 2013-09-09 11:05:26 +02:00 committed by Sebastian Dröge
parent 23b3f21595
commit 258f63b8ac
2 changed files with 31 additions and 2 deletions

View file

@ -229,8 +229,6 @@ gst_rtsp_thread_pool_class_init (GstRTSPThreadPoolClass * klass)
klass->get_thread = default_get_thread; 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, GST_DEBUG_CATEGORY_INIT (rtsp_thread_pool_debug, "rtspthreadpool", 0,
"GstRTSPThreadPool"); "GstRTSPThreadPool");
@ -503,8 +501,38 @@ gst_rtsp_thread_pool_get_thread (GstRTSPThreadPool * pool,
klass = GST_RTSP_THREAD_POOL_GET_CLASS (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) if (klass->get_thread)
result = klass->get_thread (pool, type, ctx); result = klass->get_thread (pool, type, ctx);
return result; 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;
}
}

View file

@ -169,6 +169,7 @@ gint gst_rtsp_thread_pool_get_max_threads (GstRTSPThreadPool * po
GstRTSPThread * gst_rtsp_thread_pool_get_thread (GstRTSPThreadPool *pool, GstRTSPThread * gst_rtsp_thread_pool_get_thread (GstRTSPThreadPool *pool,
GstRTSPThreadType type, GstRTSPThreadType type,
GstRTSPContext *ctx); GstRTSPContext *ctx);
void gst_rtsp_thread_pool_cleanup (void);
G_END_DECLS G_END_DECLS
#endif /* __GST_RTSP_THREAD_POOL_H__ */ #endif /* __GST_RTSP_THREAD_POOL_H__ */