X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=glib%2Fgthreadpool.c;h=de9cedf00fa3f63f1c92b66352dc5552a75f36b1;hb=14f2376c8a06f0936d734ec6a7e0e836072acf65;hp=ca3c4f936fa33ed115163fe46eb3fb732d399e43;hpb=0d1a92ca3d234a4291ef3ecbf7df2d57442a63e5;p=platform%2Fupstream%2Fglib.git diff --git a/glib/gthreadpool.c b/glib/gthreadpool.c index ca3c4f9..de9cedf 100644 --- a/glib/gthreadpool.c +++ b/glib/gthreadpool.c @@ -1,7 +1,7 @@ /* GLIB - Library of useful routines for C programming * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * - * GAsyncQueue: thread pool implementation. + * GThreadPool: thread pool implementation. * Copyright (C) 2000 Sebastian Wilhelmi; University of Karlsruhe * * This library is free software; you can redistribute it and/or @@ -15,9 +15,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library; if not, see . */ /* @@ -90,7 +88,7 @@ struct _GRealThreadPool { GThreadPool pool; GAsyncQueue *queue; - GCond *cond; + GCond cond; gint max_threads; gint num_threads; gboolean running; @@ -110,9 +108,9 @@ static gint wakeup_thread_serial = 0; /* Here all unused threads are waiting */ static GAsyncQueue *unused_thread_queue = NULL; static gint unused_threads = 0; -static gint max_unused_threads = 0; +static gint max_unused_threads = 2; static gint kill_unused_threads = 0; -static guint max_idle_time = 0; +static guint max_idle_time = 15 * 1000; static void g_thread_pool_queue_push_unlocked (GRealThreadPool *pool, gpointer data); @@ -163,15 +161,11 @@ g_thread_pool_wait_for_new_pool (void) else if (local_max_idle_time > 0) { /* If a maximal idle time is given, wait for the given time. */ - GTimeVal end_time; - - g_get_current_time (&end_time); - g_time_val_add (&end_time, local_max_idle_time * 1000); - DEBUG_MSG (("thread %p waiting in global pool for %f seconds.", g_thread_self (), local_max_idle_time / 1000.0)); - pool = g_async_queue_timed_pop (unused_thread_queue, &end_time); + pool = g_async_queue_timeout_pop (unused_thread_queue, + local_max_idle_time * 1000); } else { @@ -260,17 +254,13 @@ g_thread_pool_wait_for_new_task (GRealThreadPool *pool) /* A thread will wait for new tasks for at most 1/2 * second before going to the global pool. */ - GTimeVal end_time; - - g_get_current_time (&end_time); - g_time_val_add (&end_time, G_USEC_PER_SEC / 2); /* 1/2 second */ - DEBUG_MSG (("thread %p in pool %p waits for up to a 1/2 second for task " "(%d running, %d unprocessed).", g_thread_self (), pool, pool->num_threads, g_async_queue_length_unlocked (pool->queue))); - task = g_async_queue_timed_pop_unlocked (pool->queue, &end_time); + task = g_async_queue_timeout_pop_unlocked (pool->queue, + G_USEC_PER_SEC / 2); } } else @@ -362,7 +352,7 @@ g_thread_pool_thread_proxy (gpointer data) * immediately, inform the waiting thread of a change * of the thread pool state. */ - g_cond_broadcast (pool->cond); + g_cond_broadcast (&pool->cond); } } @@ -411,14 +401,15 @@ g_thread_pool_start_thread (GRealThreadPool *pool, if (!success) { - GError *local_error = NULL; + GThread *thread; /* No thread was found, we have to start a new one */ - if (!g_thread_new ("pool", g_thread_pool_thread_proxy, pool, FALSE, &local_error)) - { - g_propagate_error (error, local_error); - return FALSE; - } + thread = g_thread_try_new ("pool", g_thread_pool_thread_proxy, pool, error); + + if (thread == NULL) + return FALSE; + + g_thread_unref (thread); } /* See comment in g_thread_pool_thread_proxy as to why this is done @@ -462,7 +453,7 @@ g_thread_pool_start_thread (GRealThreadPool *pool, * errors. An error can only occur when @exclusive is set to %TRUE * and not all @max_threads threads could be created. * - * Return value: the new #GThreadPool + * Returns: the new #GThreadPool */ GThreadPool * g_thread_pool_new (GFunc func, @@ -477,7 +468,6 @@ g_thread_pool_new (GFunc func, g_return_val_if_fail (func, NULL); g_return_val_if_fail (!exclusive || max_threads != -1, NULL); g_return_val_if_fail (max_threads >= -1, NULL); - g_return_val_if_fail (g_thread_supported (), NULL); retval = g_new (GRealThreadPool, 1); @@ -485,7 +475,7 @@ g_thread_pool_new (GFunc func, retval->pool.user_data = user_data; retval->pool.exclusive = exclusive; retval->queue = g_async_queue_new (); - retval->cond = NULL; + g_cond_init (&retval->cond); retval->max_threads = max_threads; retval->num_threads = 0; retval->running = TRUE; @@ -541,7 +531,7 @@ g_thread_pool_new (GFunc func, * * Before version 2.32, this function did not return a success status. * - * Return value: %TRUE on success, %FALSE if an error occurred + * Returns: %TRUE on success, %FALSE if an error occurred */ gboolean g_thread_pool_push (GThreadPool *pool, @@ -606,7 +596,7 @@ g_thread_pool_push (GThreadPool *pool, * * Before version 2.32, this function did not return a success status. * - * Return value: %TRUE on success, %FALSE if an error occurred + * Returns: %TRUE on success, %FALSE if an error occurred */ gboolean g_thread_pool_set_max_threads (GThreadPool *pool, @@ -658,7 +648,7 @@ g_thread_pool_set_max_threads (GThreadPool *pool, * * Returns the maximal number of threads for @pool. * - * Return value: the maximal number of threads + * Returns: the maximal number of threads */ gint g_thread_pool_get_max_threads (GThreadPool *pool) @@ -684,7 +674,7 @@ g_thread_pool_get_max_threads (GThreadPool *pool) * * Returns the number of threads currently running in @pool. * - * Return value: the number of threads currently running + * Returns: the number of threads currently running */ guint g_thread_pool_get_num_threads (GThreadPool *pool) @@ -710,7 +700,7 @@ g_thread_pool_get_num_threads (GThreadPool *pool) * * Returns the number of tasks still unprocessed in @pool. * - * Return value: the number of unprocessed tasks + * Returns: the number of unprocessed tasks */ guint g_thread_pool_unprocessed (GThreadPool *pool) @@ -744,8 +734,8 @@ g_thread_pool_unprocessed (GThreadPool *pool) * * If @wait_ is %TRUE, the functions does not return before all * tasks to be processed (dependent on @immediate, whether all - * or only the currently running) are ready. Otherwise the function - * returns immediately. + * or only the currently running) are ready. + * Otherwise the function returns immediately. * * After calling this function @pool must not be used anymore. */ @@ -776,11 +766,9 @@ g_thread_pool_free (GThreadPool *pool, if (wait_) { - real->cond = g_cond_new (); - while (g_async_queue_length_unlocked (real->queue) != -real->num_threads && !(immediate && real->num_threads == 0)) - g_cond_wait (real->cond, _g_async_queue_get_mutex (real->queue)); + g_cond_wait (&real->cond, _g_async_queue_get_mutex (real->queue)); } if (immediate || g_async_queue_length_unlocked (real->queue) == -real->num_threads) @@ -812,9 +800,7 @@ g_thread_pool_free_internal (GRealThreadPool* pool) g_return_if_fail (pool->num_threads == 0); g_async_queue_unref (pool->queue); - - if (pool->cond) - g_cond_free (pool->cond); + g_cond_clear (&pool->cond); g_free (pool); } @@ -830,8 +816,14 @@ g_thread_pool_wakeup_and_stop_all (GRealThreadPool *pool) pool->immediate = TRUE; + /* + * So here we're sending bogus data to the pool threads, which + * should cause them each to wake up, and check the above + * pool->immediate condition. However we don't want that + * data to be sorted (since it'll crash the sorter). + */ for (i = 0; i < pool->num_threads; i++) - g_thread_pool_queue_push_unlocked (pool, GUINT_TO_POINTER (1)); + g_async_queue_push_unlocked (pool->queue, GUINT_TO_POINTER (1)); } /** @@ -841,6 +833,8 @@ g_thread_pool_wakeup_and_stop_all (GRealThreadPool *pool) * Sets the maximal number of unused threads to @max_threads. * If @max_threads is -1, no limit is imposed on the number * of unused threads. + * + * The default value is 2. */ void g_thread_pool_set_max_unused_threads (gint max_threads) @@ -876,7 +870,7 @@ g_thread_pool_set_max_unused_threads (gint max_threads) * * Returns the maximal allowed number of unused threads. * - * Return value: the maximal number of unused threads + * Returns: the maximal number of unused threads */ gint g_thread_pool_get_max_unused_threads (void) @@ -889,7 +883,7 @@ g_thread_pool_get_max_unused_threads (void) * * Returns the number of currently unused threads. * - * Return value: the number of currently unused threads + * Returns: the number of currently unused threads */ guint g_thread_pool_get_num_unused_threads (void) @@ -976,8 +970,7 @@ g_thread_pool_set_sort_function (GThreadPool *pool, * * By setting @interval to 0, idle threads will not be stopped. * - * This function makes use of g_async_queue_timed_pop () using - * @interval. + * The default value is 15000 (15 seconds). * * Since: 2.10 */ @@ -1015,7 +1008,7 @@ g_thread_pool_set_max_idle_time (guint interval) * If this function returns 0, threads waiting in the thread * pool for new work are not stopped. * - * Return value: the maximum @interval (milliseconds) to wait + * Returns: the maximum @interval (milliseconds) to wait * for new tasks in the thread pool before stopping the * thread *