|
|
|
|
@ -2,6 +2,7 @@
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <glib.h>
|
|
|
|
|
#include <pcre.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
|
|
#include "aux.h"
|
|
|
|
|
|
|
|
|
|
@ -15,6 +16,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct detach_thread {
|
|
|
|
|
GThreadFunc func;
|
|
|
|
|
gpointer data;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mutex_t threads_to_join_lock = MUTEX_STATIC_INIT;
|
|
|
|
|
static GSList *threads_to_join;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GList *g_list_link(GList *list, GList *el) {
|
|
|
|
|
el->prev = NULL;
|
|
|
|
|
el->next = list;
|
|
|
|
|
@ -102,3 +115,43 @@ void g_queue_clear(GQueue *q) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void thread_join_me() {
|
|
|
|
|
mutex_lock(&threads_to_join_lock);
|
|
|
|
|
threads_to_join = g_slist_prepend(threads_to_join, g_thread_self());
|
|
|
|
|
mutex_unlock(&threads_to_join_lock);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void threads_join_all() {
|
|
|
|
|
GThread *t;
|
|
|
|
|
|
|
|
|
|
mutex_lock(&threads_to_join_lock);
|
|
|
|
|
while (threads_to_join) {
|
|
|
|
|
t = threads_to_join->data;
|
|
|
|
|
g_thread_join(t);
|
|
|
|
|
threads_to_join = g_slist_delete_link(threads_to_join, threads_to_join);
|
|
|
|
|
}
|
|
|
|
|
mutex_unlock(&threads_to_join_lock);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gpointer thread_detach_func(gpointer d) {
|
|
|
|
|
struct detach_thread *dt = d;
|
|
|
|
|
|
|
|
|
|
dt->func(dt->data);
|
|
|
|
|
g_slice_free1(sizeof(*dt), dt);
|
|
|
|
|
thread_join_me();
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void thread_create_detach(GThreadFunc f, gpointer d) {
|
|
|
|
|
struct detach_thread *dt;
|
|
|
|
|
|
|
|
|
|
dt = g_slice_alloc(sizeof(*dt));
|
|
|
|
|
dt->func = f;
|
|
|
|
|
dt->data = d;
|
|
|
|
|
|
|
|
|
|
if (!g_thread_create(thread_detach_func, dt, TRUE, NULL))
|
|
|
|
|
abort();
|
|
|
|
|
}
|
|
|
|
|
|