From 64bbfbb6dae9a6f9f5b839b85beb42c3d7f2a790 Mon Sep 17 00:00:00 2001 From: Sebastian Wilhelmi Date: Fri, 1 Sep 2000 13:03:23 +0000 Subject: [PATCH] Include gerror.h before it is used for some g_thread_* functions. 2000-09-01 Sebastian Wilhelmi * glib.h: Include gerror.h before it is used for some g_thread_* functions. * gthread.c, gthreadpool.c, glib.h: Enable error reporting for thread creation, namly for g_thread_create, g_thread_pool_new, g_thread_pool_push and g_thread_pool_set_max_threads. * tests/thread-test.c, tests/threadpool-test.c: Adapted accordingly. * gthread-posix.c (g_thread_create_posix_impl): Use GError to report errors. --- ChangeLog | 10 ++++++++ ChangeLog.pre-2-0 | 10 ++++++++ ChangeLog.pre-2-10 | 10 ++++++++ ChangeLog.pre-2-12 | 10 ++++++++ ChangeLog.pre-2-2 | 10 ++++++++ ChangeLog.pre-2-4 | 10 ++++++++ ChangeLog.pre-2-6 | 10 ++++++++ ChangeLog.pre-2-8 | 10 ++++++++ glib.h | 39 +++++++++++++++++++++++-------- glib/glib.h | 39 +++++++++++++++++++++++-------- glib/gthread.c | 36 ++++++++++++++++++++++++----- glib/gthreadpool.c | 61 ++++++++++++++++++++++++++++++++++++------------- gthread.c | 36 ++++++++++++++++++++++++----- gthread/ChangeLog | 5 ++++ gthread/gthread-posix.c | 22 ++++++++++++++---- gthreadpool.c | 61 ++++++++++++++++++++++++++++++++++++------------- tests/thread-test.c | 8 +++---- tests/threadpool-test.c | 12 +++++----- 18 files changed, 323 insertions(+), 76 deletions(-) diff --git a/ChangeLog b/ChangeLog index 17a9a7a..e24e2e5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,16 @@ g_propagte_error to hand over local errors to the calling function. + * glib.h: Include gerror.h before it is used for some g_thread_* + functions. + + * gthread.c, gthreadpool.c, glib.h: Enable error reporting for + thread creation, namly for g_thread_create, g_thread_pool_new, + g_thread_pool_push and g_thread_pool_set_max_threads. + + * tests/thread-test.c, tests/threadpool-test.c: Adapted + accordingly. + 2000-08-31 Tor Lillqvist * glib.h diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 17a9a7a..e24e2e5 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -4,6 +4,16 @@ g_propagte_error to hand over local errors to the calling function. + * glib.h: Include gerror.h before it is used for some g_thread_* + functions. + + * gthread.c, gthreadpool.c, glib.h: Enable error reporting for + thread creation, namly for g_thread_create, g_thread_pool_new, + g_thread_pool_push and g_thread_pool_set_max_threads. + + * tests/thread-test.c, tests/threadpool-test.c: Adapted + accordingly. + 2000-08-31 Tor Lillqvist * glib.h diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 17a9a7a..e24e2e5 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -4,6 +4,16 @@ g_propagte_error to hand over local errors to the calling function. + * glib.h: Include gerror.h before it is used for some g_thread_* + functions. + + * gthread.c, gthreadpool.c, glib.h: Enable error reporting for + thread creation, namly for g_thread_create, g_thread_pool_new, + g_thread_pool_push and g_thread_pool_set_max_threads. + + * tests/thread-test.c, tests/threadpool-test.c: Adapted + accordingly. + 2000-08-31 Tor Lillqvist * glib.h diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12 index 17a9a7a..e24e2e5 100644 --- a/ChangeLog.pre-2-12 +++ b/ChangeLog.pre-2-12 @@ -4,6 +4,16 @@ g_propagte_error to hand over local errors to the calling function. + * glib.h: Include gerror.h before it is used for some g_thread_* + functions. + + * gthread.c, gthreadpool.c, glib.h: Enable error reporting for + thread creation, namly for g_thread_create, g_thread_pool_new, + g_thread_pool_push and g_thread_pool_set_max_threads. + + * tests/thread-test.c, tests/threadpool-test.c: Adapted + accordingly. + 2000-08-31 Tor Lillqvist * glib.h diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 17a9a7a..e24e2e5 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -4,6 +4,16 @@ g_propagte_error to hand over local errors to the calling function. + * glib.h: Include gerror.h before it is used for some g_thread_* + functions. + + * gthread.c, gthreadpool.c, glib.h: Enable error reporting for + thread creation, namly for g_thread_create, g_thread_pool_new, + g_thread_pool_push and g_thread_pool_set_max_threads. + + * tests/thread-test.c, tests/threadpool-test.c: Adapted + accordingly. + 2000-08-31 Tor Lillqvist * glib.h diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 17a9a7a..e24e2e5 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -4,6 +4,16 @@ g_propagte_error to hand over local errors to the calling function. + * glib.h: Include gerror.h before it is used for some g_thread_* + functions. + + * gthread.c, gthreadpool.c, glib.h: Enable error reporting for + thread creation, namly for g_thread_create, g_thread_pool_new, + g_thread_pool_push and g_thread_pool_set_max_threads. + + * tests/thread-test.c, tests/threadpool-test.c: Adapted + accordingly. + 2000-08-31 Tor Lillqvist * glib.h diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 17a9a7a..e24e2e5 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -4,6 +4,16 @@ g_propagte_error to hand over local errors to the calling function. + * glib.h: Include gerror.h before it is used for some g_thread_* + functions. + + * gthread.c, gthreadpool.c, glib.h: Enable error reporting for + thread creation, namly for g_thread_create, g_thread_pool_new, + g_thread_pool_push and g_thread_pool_set_max_threads. + + * tests/thread-test.c, tests/threadpool-test.c: Adapted + accordingly. + 2000-08-31 Tor Lillqvist * glib.h diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 17a9a7a..e24e2e5 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -4,6 +4,16 @@ g_propagte_error to hand over local errors to the calling function. + * glib.h: Include gerror.h before it is used for some g_thread_* + functions. + + * gthread.c, gthreadpool.c, glib.h: Enable error reporting for + thread creation, namly for g_thread_create, g_thread_pool_new, + g_thread_pool_push and g_thread_pool_set_max_threads. + + * tests/thread-test.c, tests/threadpool-test.c: Adapted + accordingly. + 2000-08-31 Tor Lillqvist * glib.h diff --git a/glib.h b/glib.h index 46aa390..567bf59 100644 --- a/glib.h +++ b/glib.h @@ -941,6 +941,15 @@ struct _GTuples guint len; }; +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ /* IEEE Standard 754 Single Precision Storage Format (gfloat): * @@ -3047,6 +3056,14 @@ gchar * g_win32_error_message (gint error); /* GLib Thread support */ +extern GQuark g_thread_error_quark(); +#define G_THREAD_ERROR g_thread_error_quark() + +typedef enum +{ + G_THREAD_ERROR_AGAIN /* Resource temporarily unavailable */ +} GThreadError; + typedef void (*GThreadFunc) (gpointer value); typedef enum @@ -3099,7 +3116,8 @@ struct _GThreadFunctions gboolean joinable, gboolean bound, GThreadPriority priority, - gpointer thread); + gpointer thread, + GError **error); void (*thread_yield) (void); void (*thread_join) (gpointer thread); void (*thread_exit) (void); @@ -3161,11 +3179,12 @@ GThread* g_thread_create (GThreadFunc thread_func, gulong stack_size, gboolean joinable, gboolean bound, - GThreadPriority priority); + GThreadPriority priority, + GError **error); GThread* g_thread_self (); -void g_thread_join (GThread* thread); -void g_thread_set_priority (GThread* thread, - GThreadPriority priority); +void g_thread_join (GThread *thread); +void g_thread_set_priority (GThread *thread, + GThreadPriority priority); /* GStaticMutexes can be statically initialized with the value * G_STATIC_MUTEX_INIT, and then they can directly be used, that is @@ -3365,20 +3384,23 @@ GThreadPool* g_thread_pool_new (GFunc thread_func, gboolean bound, GThreadPriority priority, gboolean exclusive, - gpointer user_data); + gpointer user_data, + GError **error); /* Push new data into the thread pool. This task is assigned to a thread later * (when the maximal number of threads is reached for that pool) or now * (otherwise). If necessary a new thread will be started. The function * returns immediatly */ void g_thread_pool_push (GThreadPool *pool, - gpointer data); + gpointer data, + GError **error); /* Set the number of threads, which can run concurrently for that pool, -1 * means no limit. 0 means has the effect, that the pool won't process * requests until the limit is set higher again */ void g_thread_pool_set_max_threads (GThreadPool *pool, - gint max_threads); + gint max_threads, + GError **error); gint g_thread_pool_get_max_threads (GThreadPool *pool); /* Get the number of threads assigned to that pool. This number doesn't @@ -3410,6 +3432,5 @@ void g_thread_pool_stop_unused_threads (void); #endif /* __cplusplus */ #include -#include #endif /* __G_LIB_H__ */ diff --git a/glib/glib.h b/glib/glib.h index 46aa390..567bf59 100644 --- a/glib/glib.h +++ b/glib/glib.h @@ -941,6 +941,15 @@ struct _GTuples guint len; }; +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ /* IEEE Standard 754 Single Precision Storage Format (gfloat): * @@ -3047,6 +3056,14 @@ gchar * g_win32_error_message (gint error); /* GLib Thread support */ +extern GQuark g_thread_error_quark(); +#define G_THREAD_ERROR g_thread_error_quark() + +typedef enum +{ + G_THREAD_ERROR_AGAIN /* Resource temporarily unavailable */ +} GThreadError; + typedef void (*GThreadFunc) (gpointer value); typedef enum @@ -3099,7 +3116,8 @@ struct _GThreadFunctions gboolean joinable, gboolean bound, GThreadPriority priority, - gpointer thread); + gpointer thread, + GError **error); void (*thread_yield) (void); void (*thread_join) (gpointer thread); void (*thread_exit) (void); @@ -3161,11 +3179,12 @@ GThread* g_thread_create (GThreadFunc thread_func, gulong stack_size, gboolean joinable, gboolean bound, - GThreadPriority priority); + GThreadPriority priority, + GError **error); GThread* g_thread_self (); -void g_thread_join (GThread* thread); -void g_thread_set_priority (GThread* thread, - GThreadPriority priority); +void g_thread_join (GThread *thread); +void g_thread_set_priority (GThread *thread, + GThreadPriority priority); /* GStaticMutexes can be statically initialized with the value * G_STATIC_MUTEX_INIT, and then they can directly be used, that is @@ -3365,20 +3384,23 @@ GThreadPool* g_thread_pool_new (GFunc thread_func, gboolean bound, GThreadPriority priority, gboolean exclusive, - gpointer user_data); + gpointer user_data, + GError **error); /* Push new data into the thread pool. This task is assigned to a thread later * (when the maximal number of threads is reached for that pool) or now * (otherwise). If necessary a new thread will be started. The function * returns immediatly */ void g_thread_pool_push (GThreadPool *pool, - gpointer data); + gpointer data, + GError **error); /* Set the number of threads, which can run concurrently for that pool, -1 * means no limit. 0 means has the effect, that the pool won't process * requests until the limit is set higher again */ void g_thread_pool_set_max_threads (GThreadPool *pool, - gint max_threads); + gint max_threads, + GError **error); gint g_thread_pool_get_max_threads (GThreadPool *pool); /* Get the number of threads assigned to that pool. This number doesn't @@ -3410,6 +3432,5 @@ void g_thread_pool_stop_unused_threads (void); #endif /* __cplusplus */ #include -#include #endif /* __G_LIB_H__ */ diff --git a/glib/gthread.c b/glib/gthread.c index f644f70..654138f 100644 --- a/glib/gthread.c +++ b/glib/gthread.c @@ -51,6 +51,21 @@ (memcpy (&dest, &src, GLIB_SIZEOF_SYSTEM_THREAD)) #endif /* GLIB_SIZEOF_SYSTEM_THREAD == SIZEOF_VOID_P */ +GQuark +g_thread_error_quark() +{ + static GQuark quark; + G_LOCK_DEFINE_STATIC(lock); + if (!quark) + { + G_LOCK (lock); + if (!quark) + quark = g_quark_from_static_string ("g-thread-error"); + G_UNLOCK (lock); + } + return quark; +} + typedef struct _GRealThread GRealThread; struct _GRealThread { @@ -97,7 +112,7 @@ GThreadFunctions g_thread_functions_for_glib_use = { NULL, /* private_set */ (void(*)(GThreadFunc, gpointer, gulong, gboolean, gboolean, GThreadPriority, - gpointer))g_thread_fail, /* thread_create */ + gpointer, GError**))g_thread_fail, /* thread_create */ NULL, /* thread_yield */ NULL, /* thread_join */ NULL, /* thread_exit */ @@ -381,10 +396,11 @@ g_thread_create (GThreadFunc thread_func, gulong stack_size, gboolean joinable, gboolean bound, - GThreadPriority priority) + GThreadPriority priority, + GError **error) { GRealThread* result = g_new (GRealThread, 1); - + GError *local_error = NULL; g_return_val_if_fail (thread_func, NULL); result->thread.joinable = joinable; @@ -394,10 +410,18 @@ g_thread_create (GThreadFunc thread_func, result->arg = arg; result->private_data = NULL; G_LOCK (g_thread_create); - G_THREAD_UF (thread_create, (g_thread_create_proxy, result, stack_size, - joinable, bound, priority, - &result->system_thread)); + G_THREAD_UF (thread_create, (g_thread_create_proxy, result, + stack_size, joinable, bound, priority, + &result->system_thread, &local_error)); G_UNLOCK (g_thread_create); + + if (local_error) + { + g_propagate_error (error, local_error); + g_free (result); + return NULL; + } + return (GThread*) result; } diff --git a/glib/gthreadpool.c b/glib/gthreadpool.c index d11f635..b281e7c 100644 --- a/glib/gthreadpool.c +++ b/glib/gthreadpool.c @@ -55,7 +55,7 @@ static GCond *inform_cond = NULL; static void g_thread_pool_free_internal (GRealThreadPool* pool); static void g_thread_pool_thread_proxy (gpointer data); -static void g_thread_pool_start_thread (GRealThreadPool* pool); +static void g_thread_pool_start_thread (GRealThreadPool* pool, GError **error); static void g_thread_pool_wakeup_and_stop_all (GRealThreadPool* pool); #define g_thread_should_run(pool, len) \ @@ -162,7 +162,8 @@ g_thread_pool_thread_proxy (gpointer data) } static void -g_thread_pool_start_thread (GRealThreadPool* pool) +g_thread_pool_start_thread (GRealThreadPool *pool, + GError **error) { gboolean success = FALSE; GThreadPriority priority = pool->pool.priority; @@ -206,9 +207,19 @@ g_thread_pool_start_thread (GRealThreadPool* pool) } if (!success) - /* No thread was found, we have to start one new */ - g_thread_create (g_thread_pool_thread_proxy, pool, pool->pool.stack_size, - FALSE, pool->pool.bound, priority); + { + GError *local_error = NULL; + /* No thread was found, we have to start one new */ + g_thread_create (g_thread_pool_thread_proxy, pool, + pool->pool.stack_size, FALSE, + pool->pool.bound, priority, &local_error); + + if (local_error) + { + g_propagate_error (error, local_error); + return; + } + } /* See comment in g_thread_pool_thread_proxy as to why this is done * here and not there */ @@ -222,7 +233,8 @@ g_thread_pool_new (GFunc thread_func, gboolean bound, GThreadPriority priority, gboolean exclusive, - gpointer user_data) + gpointer user_data, + GError **error) { GRealThreadPool *retval; @@ -257,9 +269,17 @@ g_thread_pool_new (GFunc thread_func, if (retval->pool.exclusive) { g_async_queue_lock (retval->queue); - + while (retval->num_threads < retval->max_threads) - g_thread_pool_start_thread (retval); + { + GError *local_error = NULL; + g_thread_pool_start_thread (retval, &local_error); + if (local_error) + { + g_propagate_error (error, local_error); + break; + } + } g_async_queue_unlock (retval->queue); } @@ -269,7 +289,8 @@ g_thread_pool_new (GFunc thread_func, void g_thread_pool_push (GThreadPool *pool, - gpointer data) + gpointer data, + GError **error) { GRealThreadPool *real = (GRealThreadPool*) pool; @@ -284,17 +305,17 @@ g_thread_pool_push (GThreadPool *pool, } if (!pool->exclusive && g_async_queue_length_unlocked (real->queue) >= 0) - { - /* No thread is waiting in the queue */ - g_thread_pool_start_thread (real); - } + /* No thread is waiting in the queue */ + g_thread_pool_start_thread (real, error); + g_async_queue_push_unlocked (real->queue, data); g_async_queue_unlock (real->queue); } void g_thread_pool_set_max_threads (GThreadPool *pool, - gint max_threads) + gint max_threads, + GError **error) { GRealThreadPool *real = (GRealThreadPool*) pool; gint to_start; @@ -314,8 +335,16 @@ g_thread_pool_set_max_threads (GThreadPool *pool, to_start = g_async_queue_length_unlocked (real->queue); for ( ; to_start > 0; to_start--) - g_thread_pool_start_thread (real); - + { + GError *local_error = NULL; + g_thread_pool_start_thread (real, &local_error); + if (local_error) + { + g_propagate_error (error, local_error); + break; + } + } + g_async_queue_unlock (real->queue); } diff --git a/gthread.c b/gthread.c index f644f70..654138f 100644 --- a/gthread.c +++ b/gthread.c @@ -51,6 +51,21 @@ (memcpy (&dest, &src, GLIB_SIZEOF_SYSTEM_THREAD)) #endif /* GLIB_SIZEOF_SYSTEM_THREAD == SIZEOF_VOID_P */ +GQuark +g_thread_error_quark() +{ + static GQuark quark; + G_LOCK_DEFINE_STATIC(lock); + if (!quark) + { + G_LOCK (lock); + if (!quark) + quark = g_quark_from_static_string ("g-thread-error"); + G_UNLOCK (lock); + } + return quark; +} + typedef struct _GRealThread GRealThread; struct _GRealThread { @@ -97,7 +112,7 @@ GThreadFunctions g_thread_functions_for_glib_use = { NULL, /* private_set */ (void(*)(GThreadFunc, gpointer, gulong, gboolean, gboolean, GThreadPriority, - gpointer))g_thread_fail, /* thread_create */ + gpointer, GError**))g_thread_fail, /* thread_create */ NULL, /* thread_yield */ NULL, /* thread_join */ NULL, /* thread_exit */ @@ -381,10 +396,11 @@ g_thread_create (GThreadFunc thread_func, gulong stack_size, gboolean joinable, gboolean bound, - GThreadPriority priority) + GThreadPriority priority, + GError **error) { GRealThread* result = g_new (GRealThread, 1); - + GError *local_error = NULL; g_return_val_if_fail (thread_func, NULL); result->thread.joinable = joinable; @@ -394,10 +410,18 @@ g_thread_create (GThreadFunc thread_func, result->arg = arg; result->private_data = NULL; G_LOCK (g_thread_create); - G_THREAD_UF (thread_create, (g_thread_create_proxy, result, stack_size, - joinable, bound, priority, - &result->system_thread)); + G_THREAD_UF (thread_create, (g_thread_create_proxy, result, + stack_size, joinable, bound, priority, + &result->system_thread, &local_error)); G_UNLOCK (g_thread_create); + + if (local_error) + { + g_propagate_error (error, local_error); + g_free (result); + return NULL; + } + return (GThread*) result; } diff --git a/gthread/ChangeLog b/gthread/ChangeLog index f57db4d..0adc49f 100644 --- a/gthread/ChangeLog +++ b/gthread/ChangeLog @@ -1,3 +1,8 @@ +2000-09-01 Sebastian Wilhelmi + + * gthread-posix.c (g_thread_create_posix_impl): Use GError to + report errors. + 2000-05-13 Tor Lillqvist * makefile.mingw.in: New file, with gthread stuff moved from diff --git a/gthread/gthread-posix.c b/gthread/gthread-posix.c index 2d17dea..4be752d 100644 --- a/gthread/gthread-posix.c +++ b/gthread/gthread-posix.c @@ -232,9 +232,11 @@ g_thread_create_posix_impl (GThreadFunc thread_func, gboolean joinable, gboolean bound, GThreadPriority priority, - gpointer thread) + gpointer thread, + GError **error) { pthread_attr_t attr; + gint ret; g_return_if_fail (thread_func); @@ -274,12 +276,24 @@ g_thread_create_posix_impl (GThreadFunc thread_func, # endif /* G_THREADS_IMPL_DCE */ #endif /* HAVE_PRIORITIES */ - posix_check_for_error (pthread_create (thread, &attr, - (void* (*)(void*))thread_func, - arg)); + ret = pthread_create (thread, &attr, (void* (*)(void*))thread_func, arg); +#ifdef G_THREADS_IMPL_DCE + if (ret == -1) + ret = errno; + else + ret = 0; +#endif /* G_THREADS_IMPL_DCE */ + posix_check_for_error (pthread_attr_destroy (&attr)); + if (ret) + { + g_set_error (error, G_THREAD_ERROR, G_THREAD_ERROR_AGAIN, + "Error creating thread: %s", g_strerror (ret)); + return; + } + #ifdef G_THREADS_IMPL_DCE if (!joinable) posix_check_for_error (pthread_detach (thread)); diff --git a/gthreadpool.c b/gthreadpool.c index d11f635..b281e7c 100644 --- a/gthreadpool.c +++ b/gthreadpool.c @@ -55,7 +55,7 @@ static GCond *inform_cond = NULL; static void g_thread_pool_free_internal (GRealThreadPool* pool); static void g_thread_pool_thread_proxy (gpointer data); -static void g_thread_pool_start_thread (GRealThreadPool* pool); +static void g_thread_pool_start_thread (GRealThreadPool* pool, GError **error); static void g_thread_pool_wakeup_and_stop_all (GRealThreadPool* pool); #define g_thread_should_run(pool, len) \ @@ -162,7 +162,8 @@ g_thread_pool_thread_proxy (gpointer data) } static void -g_thread_pool_start_thread (GRealThreadPool* pool) +g_thread_pool_start_thread (GRealThreadPool *pool, + GError **error) { gboolean success = FALSE; GThreadPriority priority = pool->pool.priority; @@ -206,9 +207,19 @@ g_thread_pool_start_thread (GRealThreadPool* pool) } if (!success) - /* No thread was found, we have to start one new */ - g_thread_create (g_thread_pool_thread_proxy, pool, pool->pool.stack_size, - FALSE, pool->pool.bound, priority); + { + GError *local_error = NULL; + /* No thread was found, we have to start one new */ + g_thread_create (g_thread_pool_thread_proxy, pool, + pool->pool.stack_size, FALSE, + pool->pool.bound, priority, &local_error); + + if (local_error) + { + g_propagate_error (error, local_error); + return; + } + } /* See comment in g_thread_pool_thread_proxy as to why this is done * here and not there */ @@ -222,7 +233,8 @@ g_thread_pool_new (GFunc thread_func, gboolean bound, GThreadPriority priority, gboolean exclusive, - gpointer user_data) + gpointer user_data, + GError **error) { GRealThreadPool *retval; @@ -257,9 +269,17 @@ g_thread_pool_new (GFunc thread_func, if (retval->pool.exclusive) { g_async_queue_lock (retval->queue); - + while (retval->num_threads < retval->max_threads) - g_thread_pool_start_thread (retval); + { + GError *local_error = NULL; + g_thread_pool_start_thread (retval, &local_error); + if (local_error) + { + g_propagate_error (error, local_error); + break; + } + } g_async_queue_unlock (retval->queue); } @@ -269,7 +289,8 @@ g_thread_pool_new (GFunc thread_func, void g_thread_pool_push (GThreadPool *pool, - gpointer data) + gpointer data, + GError **error) { GRealThreadPool *real = (GRealThreadPool*) pool; @@ -284,17 +305,17 @@ g_thread_pool_push (GThreadPool *pool, } if (!pool->exclusive && g_async_queue_length_unlocked (real->queue) >= 0) - { - /* No thread is waiting in the queue */ - g_thread_pool_start_thread (real); - } + /* No thread is waiting in the queue */ + g_thread_pool_start_thread (real, error); + g_async_queue_push_unlocked (real->queue, data); g_async_queue_unlock (real->queue); } void g_thread_pool_set_max_threads (GThreadPool *pool, - gint max_threads) + gint max_threads, + GError **error) { GRealThreadPool *real = (GRealThreadPool*) pool; gint to_start; @@ -314,8 +335,16 @@ g_thread_pool_set_max_threads (GThreadPool *pool, to_start = g_async_queue_length_unlocked (real->queue); for ( ; to_start > 0; to_start--) - g_thread_pool_start_thread (real); - + { + GError *local_error = NULL; + g_thread_pool_start_thread (real, &local_error); + if (local_error) + { + g_propagate_error (error, local_error); + break; + } + } + g_async_queue_unlock (real->queue); } diff --git a/tests/thread-test.c b/tests/thread-test.c index 1d203df..1316982 100644 --- a/tests/thread-test.c +++ b/tests/thread-test.c @@ -27,7 +27,7 @@ test_g_mutex (void) g_assert (G_TRYLOCK (test_g_mutex)); thread = g_thread_create (test_g_mutex_thread, GINT_TO_POINTER (42), - 0, TRUE, TRUE, G_THREAD_PRIORITY_NORMAL); + 0, TRUE, TRUE, G_THREAD_PRIORITY_NORMAL, NULL); g_usleep (G_MICROSEC); test_g_mutex_int = 42; G_UNLOCK (test_g_mutex); @@ -62,7 +62,7 @@ test_g_static_rec_mutex (void) g_assert (g_static_rec_mutex_trylock (&test_g_static_rec_mutex_mutex)); thread = g_thread_create (test_g_static_rec_mutex_thread, GINT_TO_POINTER (42), - 0, TRUE, TRUE, G_THREAD_PRIORITY_NORMAL); + 0, TRUE, TRUE, G_THREAD_PRIORITY_NORMAL, NULL); g_usleep (G_MICROSEC); g_assert (g_static_rec_mutex_trylock (&test_g_static_rec_mutex_mutex)); g_usleep (G_MICROSEC); @@ -136,7 +136,7 @@ test_g_static_private (void) threads[i] = g_thread_create (test_g_static_private_thread, GINT_TO_POINTER (i), 0, TRUE, TRUE, - G_THREAD_PRIORITY_NORMAL); + G_THREAD_PRIORITY_NORMAL, NULL); } for (i = 0; i < THREADS; i++) { @@ -213,7 +213,7 @@ test_g_static_rw_lock () { threads[i] = g_thread_create (test_g_static_rw_lock_thread, 0, 0, TRUE, TRUE, - G_THREAD_PRIORITY_NORMAL); + G_THREAD_PRIORITY_NORMAL, NULL); } g_usleep (G_MICROSEC); test_g_static_rw_lock_run = FALSE; diff --git a/tests/threadpool-test.c b/tests/threadpool-test.c index 9044e4b..6608d5f 100644 --- a/tests/threadpool-test.c +++ b/tests/threadpool-test.c @@ -33,17 +33,17 @@ main (int argc, g_thread_init (NULL); pool1 = g_thread_pool_new (thread_pool_func, 3, 0, FALSE, - G_THREAD_PRIORITY_NORMAL, FALSE, NULL); + G_THREAD_PRIORITY_NORMAL, FALSE, NULL, NULL); pool2 = g_thread_pool_new (thread_pool_func, 5, 0, FALSE, - G_THREAD_PRIORITY_LOW, FALSE, NULL); + G_THREAD_PRIORITY_LOW, FALSE, NULL, NULL); pool3 = g_thread_pool_new (thread_pool_func, 7, 0, FALSE, - G_THREAD_PRIORITY_LOW, TRUE, NULL); + G_THREAD_PRIORITY_LOW, TRUE, NULL, NULL); for (i = 0; i < RUNS; i++) { - g_thread_pool_push (pool1, GUINT_TO_POINTER (1)); - g_thread_pool_push (pool2, GUINT_TO_POINTER (1)); - g_thread_pool_push (pool3, GUINT_TO_POINTER (1)); + g_thread_pool_push (pool1, GUINT_TO_POINTER (1), NULL); + g_thread_pool_push (pool2, GUINT_TO_POINTER (1), NULL); + g_thread_pool_push (pool3, GUINT_TO_POINTER (1), NULL); } g_thread_pool_free (pool1, FALSE, TRUE); -- 2.7.4