int num_idle;
/*
- * An array of threads that require joining, the array has
- * "max_threads" elements. It contains "num_exited" ids.
+ * An array of threads that require joining.
*/
int num_exited;
- pthread_t exited[1]; /* We alloc more */
+ pthread_t *exited; /* We alloc more */
};
static pthread_mutex_t pthreadpools_mutex = PTHREAD_MUTEX_INITIALIZER;
int pthreadpool_init(unsigned max_threads, struct pthreadpool **presult)
{
struct pthreadpool *pool;
- size_t size;
int ret;
- size = sizeof(struct pthreadpool)
- + (max_threads-1) * sizeof(pthread_t);
-
- pool = (struct pthreadpool *)malloc(size);
+ pool = (struct pthreadpool *)malloc(sizeof(struct pthreadpool));
if (pool == NULL) {
return ENOMEM;
}
pool->jobs = pool->last_job = NULL;
pool->num_threads = 0;
pool->num_exited = 0;
+ pool->exited = NULL;
pool->max_threads = max_threads;
pool->num_idle = 0;
assert(ret == 0);
pool->num_threads = 0;
+
pool->num_exited = 0;
+ free(pool->exited);
+ pool->exited = NULL;
+
pool->num_idle = 0;
while (pool->jobs != NULL) {
pthread_join(pool->exited[i], NULL);
}
pool->num_exited = 0;
+
+ /*
+ * Deliberately not free and NULL pool->exited. That will be
+ * re-used by realloc later.
+ */
}
/*
close(pool->sig_pipe[1]);
pool->sig_pipe[1] = -1;
+ free(pool->exited);
free(pool);
return 0;
*/
static void pthreadpool_server_exit(struct pthreadpool *pool)
{
+ pthread_t *exited;
+
pool->num_threads -= 1;
+
+ exited = (pthread_t *)realloc(
+ pool->exited, sizeof(pthread_t *) * (pool->num_exited + 1));
+
+ if (exited == NULL) {
+ /* lost a thread status */
+ return;
+ }
+ pool->exited = exited;
+
pool->exited[pool->num_exited] = pthread_self();
pool->num_exited += 1;
}
return res;
}
- if (pool->num_threads >= pool->max_threads) {
+ if ((pool->max_threads != 0) &&
+ (pool->num_threads >= pool->max_threads)) {
/*
* No more new threads, we just queue the request
*/
* @param[in] max_threads Maximum parallelism in this pool
* @param[out] presult Pointer to the threadpool returned
* @return success: 0, failure: errno
+ *
+ * max_threads=0 means unlimited parallelism. The caller has to take
+ * care to not overload the system.
*/
int pthreadpool_init(unsigned max_threads, struct pthreadpool **presult);