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 */
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. */
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);
}
}
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));
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;
}
SilcSchedule schedule,
SilcThreadPoolFunc run,
void *run_context,
- SilcThreadPoolFunc completion,
+ SilcTaskCallback completion,
void *completion_context)
{
SilcThreadPoolThread t;
*
* 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);
* 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
*
* SilcSchedule schedule,
* SilcThreadPoolFunc run,
* void *run_context,
- * SilcThreadPoolFunc completion,
+ * SilcTaskCallback completion,
* void *completion_context);
*
* DESCRIPTION
SilcSchedule schedule,
SilcThreadPoolFunc run,
void *run_context,
- SilcThreadPoolFunc completion,
+ SilcTaskCallback completion,
void *completion_context);
/****f* silcutil/SilcThreadAPI/silc_thread_pool_set_max_threads