summaryrefslogtreecommitdiff
path: root/libpthread/linuxthreads
diff options
context:
space:
mode:
Diffstat (limited to 'libpthread/linuxthreads')
-rw-r--r--libpthread/linuxthreads/internals.h6
-rw-r--r--libpthread/linuxthreads/manager.c28
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)