예제 #1
0
파일: gthreadpool.c 프로젝트: 183amir/glib
/**
 * g_thread_pool_push:
 * @pool: a #GThreadPool
 * @data: a new task for @pool
 * @error: return location for error, or %NULL
 *
 * Inserts @data into the list of tasks to be executed by @pool.
 *
 * When the number of currently running threads is lower than the
 * maximal allowed number of threads, a new thread is started (or
 * reused) with the properties given to g_thread_pool_new().
 * Otherwise, @data stays in the queue until a thread in this pool
 * finishes its previous task and processes @data.
 *
 * @error can be %NULL to ignore errors, or non-%NULL to report
 * errors. An error can only occur when a new thread couldn't be
 * created. In that case @data is simply appended to the queue of
 * work to do.
 *
 * Before version 2.32, this function did not return a success status.
 *
 * Returns: %TRUE on success, %FALSE if an error occurred
 */
gboolean
g_thread_pool_push (GThreadPool  *pool,
                    gpointer      data,
                    GError      **error)
{
  GRealThreadPool *real;
  gboolean result;

  real = (GRealThreadPool*) pool;

  g_return_val_if_fail (real, FALSE);
  g_return_val_if_fail (real->running, FALSE);

  result = TRUE;

  g_async_queue_lock (real->queue);

  if (g_async_queue_length_unlocked (real->queue) >= 0)
    {
      /* No thread is waiting in the queue */
      GError *local_error = NULL;

      if (!g_thread_pool_start_thread (real, &local_error))
        {
          g_propagate_error (error, local_error);
          result = FALSE;
        }
    }

  g_thread_pool_queue_push_unlocked (real, data);
  g_async_queue_unlock (real->queue);

  return result;
}
예제 #2
0
파일: gthreadpool.c 프로젝트: 183amir/glib
/**
 * g_thread_pool_new:
 * @func: a function to execute in the threads of the new thread pool
 * @user_data: user data that is handed over to @func every time it
 *     is called
 * @max_threads: the maximal number of threads to execute concurrently
 *     in  the new thread pool, -1 means no limit
 * @exclusive: should this thread pool be exclusive?
 * @error: return location for error, or %NULL
 *
 * This function creates a new thread pool.
 *
 * Whenever you call g_thread_pool_push(), either a new thread is
 * created or an unused one is reused. At most @max_threads threads
 * are running concurrently for this thread pool. @max_threads = -1
 * allows unlimited threads to be created for this thread pool. The
 * newly created or reused thread now executes the function @func
 * with the two arguments. The first one is the parameter to
 * g_thread_pool_push() and the second one is @user_data.
 *
 * The parameter @exclusive determines whether the thread pool owns
 * all threads exclusive or shares them with other thread pools.
 * If @exclusive is %TRUE, @max_threads threads are started
 * immediately and they will run exclusively for this thread pool
 * until it is destroyed by g_thread_pool_free(). If @exclusive is
 * %FALSE, threads are created when needed and shared between all
 * non-exclusive thread pools. This implies that @max_threads may
 * not be -1 for exclusive thread pools. Besides, exclusive thread
 * pools are not affected by g_thread_pool_set_max_idle_time()
 * since their threads are never considered idle and returned to the
 * global pool.
 *
 * @error can be %NULL to ignore errors, or non-%NULL to report
 * errors. An error can only occur when @exclusive is set to %TRUE
 * and not all @max_threads threads could be created.
 * See #GThreadError for possible errors that may occur.
 * Note, even in case of error a valid #GThreadPool is returned.
 *
 * Returns: the new #GThreadPool
 */
GThreadPool *
g_thread_pool_new (GFunc      func,
                   gpointer   user_data,
                   gint       max_threads,
                   gboolean   exclusive,
                   GError   **error)
{
  GRealThreadPool *retval;
  G_LOCK_DEFINE_STATIC (init);

  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);

  retval = g_new (GRealThreadPool, 1);

  retval->pool.func = func;
  retval->pool.user_data = user_data;
  retval->pool.exclusive = exclusive;
  retval->queue = g_async_queue_new ();
  g_cond_init (&retval->cond);
  retval->max_threads = max_threads;
  retval->num_threads = 0;
  retval->running = TRUE;
  retval->immediate = FALSE;
  retval->waiting = FALSE;
  retval->sort_func = NULL;
  retval->sort_user_data = NULL;

  G_LOCK (init);
  if (!unused_thread_queue)
      unused_thread_queue = g_async_queue_new ();
  G_UNLOCK (init);

  if (retval->pool.exclusive)
    {
      g_async_queue_lock (retval->queue);

      while (retval->num_threads < retval->max_threads)
        {
          GError *local_error = NULL;

          if (!g_thread_pool_start_thread (retval, &local_error))
            {
              g_propagate_error (error, local_error);
              break;
            }
        }

      g_async_queue_unlock (retval->queue);
    }

  return (GThreadPool*) retval;
}
예제 #3
0
파일: gthreadpool.c 프로젝트: 183amir/glib
/**
 * g_thread_pool_set_max_threads:
 * @pool: a #GThreadPool
 * @max_threads: a new maximal number of threads for @pool,
 *     or -1 for unlimited
 * @error: return location for error, or %NULL
 *
 * Sets the maximal allowed number of threads for @pool.
 * A value of -1 means that the maximal number of threads
 * is unlimited. If @pool is an exclusive thread pool, setting
 * the maximal number of threads to -1 is not allowed.
 *
 * Setting @max_threads to 0 means stopping all work for @pool.
 * It is effectively frozen until @max_threads is set to a non-zero
 * value again.
 *
 * A thread is never terminated while calling @func, as supplied by
 * g_thread_pool_new(). Instead the maximal number of threads only
 * has effect for the allocation of new threads in g_thread_pool_push().
 * A new thread is allocated, whenever the number of currently
 * running threads in @pool is smaller than the maximal number.
 *
 * @error can be %NULL to ignore errors, or non-%NULL to report
 * errors. An error can only occur when a new thread couldn't be
 * created.
 *
 * Before version 2.32, this function did not return a success status.
 *
 * Returns: %TRUE on success, %FALSE if an error occurred
 */
gboolean
g_thread_pool_set_max_threads (GThreadPool  *pool,
                               gint          max_threads,
                               GError      **error)
{
  GRealThreadPool *real;
  gint to_start;
  gboolean result;

  real = (GRealThreadPool*) pool;

  g_return_val_if_fail (real, FALSE);
  g_return_val_if_fail (real->running, FALSE);
  g_return_val_if_fail (!real->pool.exclusive || max_threads != -1, FALSE);
  g_return_val_if_fail (max_threads >= -1, FALSE);

  result = TRUE;

  g_async_queue_lock (real->queue);

  real->max_threads = max_threads;

  if (pool->exclusive)
    to_start = real->max_threads - real->num_threads;
  else
    to_start = g_async_queue_length_unlocked (real->queue);

  for ( ; to_start > 0; to_start--)
    {
      GError *local_error = NULL;

      if (!g_thread_pool_start_thread (real, &local_error))
        {
          g_propagate_error (error, local_error);
          result = FALSE;
          break;
        }
    }

  g_async_queue_unlock (real->queue);

  return result;
}
/**
 * g_thread_pool_push:
 * @pool: a #GThreadPool
 * @data: a new task for @pool
 * @error: return location for error
 * 
 * Inserts @data into the list of tasks to be executed by @pool. When
 * the number of currently running threads is lower than the maximal
 * allowed number of threads, a new thread is started (or reused) with
 * the properties given to g_thread_pool_new (). Otherwise @data stays
 * in the queue until a thread in this pool finishes its previous task
 * and processes @data. 
 *
 * @error can be %NULL to ignore errors, or non-%NULL to report
 * errors. An error can only occur when a new thread couldn't be
 * created. In that case @data is simply appended to the queue of work
 * to do.  
 **/
void 
g_thread_pool_push (GThreadPool  *pool,
		    gpointer      data,
		    GError      **error)
{
  GRealThreadPool *real;

  real = (GRealThreadPool*) pool;

  g_return_if_fail (real);
  g_return_if_fail (real->running);

  g_async_queue_lock (real->queue);

  if (g_async_queue_length_unlocked (real->queue) >= 0)
    /* No thread is waiting in the queue */
    g_thread_pool_start_thread (real, error);

  g_thread_pool_queue_push_unlocked (real, data);
  g_async_queue_unlock (real->queue);
}