Browse Source

import the helper function pthread_for_each_thread from glibc

Mike Frysinger 18 years ago
parent
commit
2be79fd8f7
2 changed files with 31 additions and 3 deletions
  1. 5 1
      libpthread/linuxthreads/internals.h
  2. 26 2
      libpthread/linuxthreads/manager.c

+ 5 - 1
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;
 };
 

+ 26 - 2
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)