Changed thread pool completion callback to SilcTaskCallback so that
authorPekka Riikonen <priikone@silcnet.org>
Mon, 9 Jul 2007 17:29:35 +0000 (17:29 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Mon, 9 Jul 2007 17:29:35 +0000 (17:29 +0000)
we can directly give it to destination scheduler.

lib/silcutil/silcthread.c
lib/silcutil/silcthread.h
lib/silcutil/tests/test_silcthread.c

index 8258c9954f852861787f123faa5529c6ad578a1f..23bd1f4ce38421d9733ea429cee5369e6030e8db 100644 (file)
@@ -28,19 +28,12 @@ typedef struct SilcThreadPoolThreadStruct {
   SilcThreadPool tp;               /* The thread pool */
   SilcSchedule schedule;           /* Scheduler, may be NULL */
   SilcThreadPoolFunc run;          /* The function to run in a thread */
-  SilcThreadPoolFunc completion;    /* Completion function */
+  SilcTaskCallback completion;     /* Completion function */
   void *run_context;
   void *completion_context;
   unsigned int stop        : 1;            /* Set to stop the thread */
 } *SilcThreadPoolThread;
 
-/* Completion context */
-typedef struct SilcThreadPoolCompletionStruct {
-  SilcSchedule schedule;           /* Scheduler, may be NULL */
-  SilcThreadPoolFunc completion;    /* Completion function */
-  void *completion_context;
-} *SilcThreadPoolCompletion;
-
 /* Thread pool context */
 struct SilcThreadPoolStruct {
   SilcStack stack;                 /* Stack for memory allocation */
@@ -74,24 +67,17 @@ static void silc_thread_pool_unref(SilcThreadPool tp)
   SILC_LOG_DEBUG(("Thread pool %p refcnt %d -> %d", tp, tp->refcnt + 1,
                  tp->refcnt));
   if (!tp->refcnt) {
+    SilcStack stack = tp->stack;
     silc_mutex_unlock(tp->lock);
     silc_mutex_free(tp->lock);
     silc_cond_free(tp->pool_signal);
-    silc_sfree(tp->stack, tp);
+    silc_sfree(stack, tp);
+    silc_stack_free(stack);
     return;
   }
   silc_mutex_unlock(tp->lock);
 }
 
-/* Thread completion callback */
-
-SILC_TASK_CALLBACK(silc_thread_pool_run_completion)
-{
-  SilcThreadPoolCompletion c = context;
-  c->completion(c->schedule, c->completion_context);
-  silc_free(c);
-}
-
 /* The thread executor.  Each thread in the pool is run here.  They wait
    here for something to do which is given to them by silc_thread_pool_run. */
 
@@ -135,22 +121,16 @@ static void *silc_thread_pool_run_thread(void *context)
        is running. */
     if (t->completion) {
       if (t->schedule) {
-       SilcThreadPoolCompletion c = silc_calloc(1, sizeof(*c));
-       if (c) {
-         SILC_LOG_DEBUG(("Run completion through scheduler %p", t->schedule));
-         c->schedule = t->schedule;
-         c->completion = t->completion;
-         c->completion_context = t->completion_context;
-         silc_schedule_task_add_timeout(c->schedule,
-                                        silc_thread_pool_run_completion, c,
-                                        0, 0);
-         silc_schedule_wakeup(c->schedule);
-       } else {
-         t->completion(NULL, t->completion_context);
+       SILC_LOG_DEBUG(("Run completion through scheduler %p", t->schedule));
+       if (!silc_schedule_task_add_timeout(t->schedule, t->completion,
+                                           t->completion_context, 0, 0)) {
+         SILC_LOG_DEBUG(("Run completion directly"));
+         t->completion(NULL, NULL, 0, 0, t->completion_context);
        }
+       silc_schedule_wakeup(t->schedule);
       } else {
        SILC_LOG_DEBUG(("Run completion directly"));
-       t->completion(NULL, t->completion_context);
+       t->completion(NULL, NULL, 0, 0, t->completion_context);
       }
     }
 
@@ -222,9 +202,14 @@ SilcThreadPool silc_thread_pool_alloc(SilcStack stack,
   if (max_threads < min_threads)
     return NULL;
 
+  if (stack)
+    stack = silc_stack_alloc(0, stack);
+
   tp = silc_scalloc(stack, 1, sizeof(*tp));
-  if (!tp)
+  if (!tp) {
+    silc_stack_free(stack);
     return NULL;
+  }
 
   SILC_LOG_DEBUG(("Starting thread pool %p, min threads %d, max threads %d",
                  tp, min_threads, max_threads));
@@ -236,12 +221,14 @@ SilcThreadPool silc_thread_pool_alloc(SilcStack stack,
 
   if (!silc_mutex_alloc(&tp->lock)) {
     silc_sfree(stack, tp);
+    silc_stack_free(stack);
     return NULL;
   }
 
   if (!silc_cond_alloc(&tp->pool_signal)) {
     silc_mutex_free(tp->lock);
     silc_sfree(stack, tp);
+    silc_stack_free(stack);
     return NULL;
   }
 
@@ -295,7 +282,7 @@ SilcBool silc_thread_pool_run(SilcThreadPool tp,
                              SilcSchedule schedule,
                              SilcThreadPoolFunc run,
                              void *run_context,
-                             SilcThreadPoolFunc completion,
+                             SilcTaskCallback completion,
                              void *completion_context)
 {
   SilcThreadPoolThread t;
index e12ddaa37eff619b1e70cad2634d2194e846800f..c439b38db611f64f1f85ba643b1b3e53f953fd59 100644 (file)
@@ -195,8 +195,8 @@ typedef struct SilcThreadPoolStruct *SilcThreadPool;
  *
  *    A callback function of this type is given as argument to the
  *    silc_thread_pool_run.  The `schedule' is the scheduler and the
- *    `context' is the `run_context' or `completion_context' given as
- *    argument to silc_thread_pool_run.
+ *    `context' is the `run_context' given as argument to
+ *    silc_thread_pool_run.
  *
  ***/
 typedef void (*SilcThreadPoolFunc)(SilcSchedule schedule, void *context);
@@ -213,10 +213,11 @@ typedef void (*SilcThreadPoolFunc)(SilcSchedule schedule, void *context);
  * DESCRIPTION
  *
  *    Allocate thread pool with at least `min_threads' and at most
- *    `max_threads' many threads.  If `stack' is non-NULL all memory is
- *    allocated from the `stack'.  If `start_min_threads' is TRUE this will
+ *    `max_threads' many threads. If `start_min_threads' is TRUE this will
  *    start `min_threads' many threads immediately.  Returns the thread
- *    pool context or NULL on error.
+ *    pool context or NULL on error.  If `stack' is non-NULL memory is
+ *    allocated from `stack'.  When the thread pool is freed the memory
+ *    is returned to `stack'.
  *
  * EXAMPLE
  *
@@ -263,7 +264,7 @@ void silc_thread_pool_free(SilcThreadPool tp, SilcBool wait_unfinished);
  *                                  SilcSchedule schedule,
  *                                  SilcThreadPoolFunc run,
  *                                  void *run_context,
- *                                  SilcThreadPoolFunc completion,
+ *                                  SilcTaskCallback completion,
  *                                  void *completion_context);
  *
  * DESCRIPTION
@@ -287,7 +288,7 @@ SilcBool silc_thread_pool_run(SilcThreadPool tp,
                              SilcSchedule schedule,
                              SilcThreadPoolFunc run,
                              void *run_context,
-                             SilcThreadPoolFunc completion,
+                             SilcTaskCallback completion,
                              void *completion_context);
 
 /****f* silcutil/SilcThreadAPI/silc_thread_pool_set_max_threads
index b2ec10d17cafc9244f45cad283e6908da294004f..6305d7c100b2eede7934e1b81fe12d2cdfa54d87 100644 (file)
@@ -10,7 +10,7 @@ static void func(SilcSchedule schedule, void *context)
   sleep(1);
 }
 
-static void compl(SilcSchedule schedule, void *context)
+SILC_TASK_CALLBACK(compl)
 {
   SILC_LOG_DEBUG(("completion: %d", (int)context));
   if ((int)context == 0xff)