diff options
Diffstat (limited to 'libpthread')
-rw-r--r-- | libpthread/linuxthreads/internals.h | 6 | ||||
-rw-r--r-- | libpthread/linuxthreads/manager.c | 28 |
2 files changed, 31 insertions, 3 deletions
diff --git a/libpthread/linuxthreads/internals.h b/libpthread/linuxthreads/internals.h index 194b41789..6bb80cd9e 100644 --- a/libpthread/linuxthreads/internals.h +++ b/libpthread/linuxthreads/internals.h @@ -201,7 +201,7 @@ struct pthread_request { pthread_descr req_thread; /* Thread doing the request */ enum { /* Request kind */ REQ_CREATE, REQ_FREE, REQ_PROCESS_EXIT, REQ_MAIN_THREAD_EXIT, - REQ_POST, REQ_DEBUG, REQ_KICK + REQ_POST, REQ_DEBUG, REQ_KICK, REQ_FOR_EACH_THREAD } req_kind; union { /* Arguments for request */ struct { /* For REQ_CREATE: */ @@ -217,6 +217,10 @@ struct pthread_request { int code; /* exit status */ } exit; void * post; /* For REQ_POST: the semaphore */ + struct { /* For REQ_FOR_EACH_THREAD: callback */ + void (*fn)(void *, pthread_descr); + void *arg; + } for_each; } req_args; }; diff --git a/libpthread/linuxthreads/manager.c b/libpthread/linuxthreads/manager.c index 204344aef..585789e22 100644 --- a/libpthread/linuxthreads/manager.c +++ b/libpthread/linuxthreads/manager.c @@ -107,13 +107,18 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr, int report_events, td_thr_events_t *event_maskp); static void pthread_handle_free(pthread_t th_id); -static void pthread_handle_exit(pthread_descr issuing_thread, int exitcode); +static void pthread_handle_exit(pthread_descr issuing_thread, int exitcode) + __attribute__ ((noreturn)); static void pthread_reap_children(void); static void pthread_kill_all_threads(int sig, int main_thread_also); +static void pthread_for_each_thread(void *arg, + void (*fn)(void *, pthread_descr)); /* The server thread managing requests for thread creation and termination */ -int __pthread_manager(void *arg) +int +__attribute__ ((noreturn)) +__pthread_manager(void *arg) { int reqfd = (int) (long int) arg; #ifdef USE_SELECT @@ -248,6 +253,11 @@ int __pthread_manager(void *arg) /* This is just a prod to get the manager to reap some threads right away, avoiding a potential delay at shutdown. */ break; + case REQ_FOR_EACH_THREAD: + pthread_for_each_thread(request.req_args.for_each.arg, + request.req_args.for_each.fn); + restart(request.req_thread); + break; } } } @@ -839,6 +849,20 @@ static void pthread_kill_all_threads(int sig, int main_thread_also) } } +static void pthread_for_each_thread(void *arg, + void (*fn)(void *, pthread_descr)) +{ + pthread_descr th; + + for (th = __pthread_main_thread->p_nextlive; + th != __pthread_main_thread; + th = th->p_nextlive) { + fn(arg, th); + } + + fn(arg, __pthread_main_thread); +} + /* Process-wide exit() */ static void pthread_handle_exit(pthread_descr issuing_thread, int exitcode) |