a more robust thread shutdown procedure

git.mgm/mediaproxy-ng/2.1
Richard Fuchs 13 years ago
parent d20d747a63
commit 7e38c7a96f

@ -24,8 +24,10 @@ struct detach_thread {
};
mutex_t threads_to_join_lock = MUTEX_STATIC_INIT;
static GSList *threads_to_join;
static mutex_t threads_lists_lock = MUTEX_STATIC_INIT;
static GList *threads_to_join;
static GList *threads_running;
static cond_t threads_cond = COND_STATIC_INIT;
@ -119,31 +121,58 @@ void g_queue_clear(GQueue *q) {
void thread_join_me() {
static void thread_join_me() {
pthread_t *me;
me = g_slice_alloc(sizeof(*me));
*me = pthread_self();
mutex_lock(&threads_to_join_lock);
threads_to_join = g_slist_prepend(threads_to_join, me);
mutex_unlock(&threads_to_join_lock);
mutex_lock(&threads_lists_lock);
threads_to_join = g_list_prepend(threads_to_join, me);
cond_broadcast(&threads_cond);
mutex_unlock(&threads_lists_lock);
}
void threads_join_all() {
static gint thread_equal(gconstpointer a, gconstpointer b) {
const pthread_t *x = a, *y = b;
return !pthread_equal(*x, *y);
}
void threads_join_all(int wait) {
pthread_t *t;
GList *l;
mutex_lock(&threads_lists_lock);
while (1) {
while (threads_to_join) {
t = threads_to_join->data;
pthread_join(*t, NULL);
threads_to_join = g_list_delete_link(threads_to_join, threads_to_join);
l = g_list_find_custom(threads_running, t, thread_equal);
if (l)
threads_running = g_list_delete_link(threads_running, l);
else
abort();
g_slice_free1(sizeof(*t), t);
}
mutex_lock(&threads_to_join_lock);
while (threads_to_join) {
t = threads_to_join->data;
pthread_join(*t, NULL);
threads_to_join = g_slist_delete_link(threads_to_join, threads_to_join);
g_slice_free1(sizeof(*t), t);
if (!wait)
break;
if (!threads_running)
break;
cond_wait(&threads_cond, &threads_lists_lock);
}
mutex_unlock(&threads_to_join_lock);
mutex_unlock(&threads_lists_lock);
}
static gpointer thread_detach_func(gpointer d) {
static void *thread_detach_func(void *d) {
struct detach_thread *dt = d;
pthread_t *t;
t = g_slice_alloc(sizeof(*t));
*t = pthread_self();
mutex_lock(&threads_lists_lock);
threads_running = g_list_prepend(threads_running, t);
mutex_unlock(&threads_lists_lock);
dt->func(dt->data);
g_slice_free1(sizeof(*dt), dt);
@ -151,7 +180,7 @@ static gpointer thread_detach_func(gpointer d) {
return NULL;
}
int thread_create(void *(*func)(void *), void *arg, int joinable, pthread_t *handle) {
static int thread_create(void *(*func)(void *), void *arg, int joinable, pthread_t *handle) {
pthread_attr_t att;
pthread_t thr;
int ret;
@ -162,9 +191,12 @@ int thread_create(void *(*func)(void *), void *arg, int joinable, pthread_t *han
abort();
ret = pthread_create(&thr, &att, func, arg);
pthread_attr_destroy(&att);
if (!ret && handle)
if (ret)
return ret;
if (handle)
*handle = thr;
return ret;
return 0;
}
void thread_create_detach(void (*f)(void *), void *d) {

@ -169,11 +169,10 @@ typedef pthread_cond_t cond_t;
#define cond_wait(c,m) pthread_cond_wait(c,m)
#define cond_signal(c) pthread_cond_signal(c)
#define cond_broadcast(c) pthread_cond_broadcast(c)
#define COND_STATIC_INIT PTHREAD_COND_INITIALIZER
void thread_join_me();
void threads_join_all();
int thread_create(void *(*)(void *), void *, int, pthread_t *);
void threads_join_all(int);
void thread_create_detach(void (*)(void *), void *);

@ -431,10 +431,10 @@ int main(int argc, char **argv) {
while (!global_shutdown) {
usleep(100000);
threads_join_all();
threads_join_all(0);
}
threads_join_all();
threads_join_all(1);
mylog(LOG_INFO, "Version %s shutting down", MEDIAPROXY_VERSION);

Loading…
Cancel
Save