OSDN Git Service

* cygthread.h (cygthread::terminate): Declare new function.
authorcgf <cgf>
Sun, 29 Sep 2002 02:19:35 +0000 (02:19 +0000)
committercgf <cgf>
Sun, 29 Sep 2002 02:19:35 +0000 (02:19 +0000)
(cygthread::initialized): Change to 'int'.
* cygthread.cc (cygthread::stub): Exit thread if initialized < 0.
(cygthread::new): Ditto.
(cygthread::runner): Ditto.  Set initialized using xor to preserve sign.
(cygthread::terminate): New function.
* dcrt0.cc (do_exit): Call cygthread::terminate.

winsup/cygwin/ChangeLog
winsup/cygwin/cygthread.cc
winsup/cygwin/cygthread.h
winsup/cygwin/dcrt0.cc
winsup/cygwin/thread.h

index 591dcfc..005dea3 100644 (file)
@@ -1,3 +1,14 @@
+2002-09-28  Christopher Faylor  <cgf@redhat.com>
+
+       * cygthread.h (cygthread::terminate): Declare new function.
+       (cygthread::initialized): Change to 'int'.
+       * cygthread.cc (cygthread::stub): Exit thread if initialized < 0.
+       (cygthread::new): Ditto.
+       (cygthread::runner): Ditto.  Set initialized using xor to preserve
+       sign.
+       (cygthread::terminate): New function.
+       * dcrt0.cc (do_exit): Call cygthread::terminate.
+
 2002-09-27  Robert Collins <rbtcollins@hotmail.com>
 
        * thread.cc (pthread_key::run_destructor): Run_destructor is not
index b81c4c1..b2a6224 100644 (file)
@@ -19,7 +19,7 @@ static cygthread NO_COPY threads[6];
 #define NTHREADS (sizeof (threads) / sizeof (threads[0]))
 
 DWORD NO_COPY cygthread::main_thread_id;
-bool NO_COPY cygthread::initialized;
+int NO_COPY cygthread::initialized;
 
 /* Initial stub called by cygthread constructor. Performs initial
    per-thread initialization and loops waiting for new thread functions
@@ -68,7 +68,10 @@ cygthread::stub (VOID *arg)
 #endif
       SetEvent (info->ev);
       info->__name = NULL;
-      SuspendThread (info->h);
+      if (initialized < 0)
+       ExitThread (0);
+      else
+       SuspendThread (info->h);
     }
 }
 
@@ -78,9 +81,14 @@ DWORD WINAPI
 cygthread::runner (VOID *arg)
 {
   for (unsigned i = 0; i < NTHREADS; i++)
-    threads[i].h = CreateThread (&sec_none_nih, 0, cygthread::stub, &threads[i],
-                                CREATE_SUSPENDED, &threads[i].avail);
-  cygthread::initialized = true;
+    if (!initialized)
+      threads[i].h = CreateThread (&sec_none_nih, 0, cygthread::stub,
+                                  &threads[i], CREATE_SUSPENDED,
+                                  &threads[i].avail);
+    else
+      return 0;
+
+  initialized ^= 1;
   return 0;
 }
 
@@ -127,7 +135,10 @@ new (size_t)
 
   for (;;)
     {
-      bool was_initialized = initialized;
+      int was_initialized = initialized;
+      if (was_initialized < 0)
+       ExitThread (0);
+
       /* Search the threads array for an empty slot to use */
       for (info = threads + NTHREADS - 1; info >= threads; info--)
        if ((id = (DWORD) InterlockedExchange ((LPLONG) &info->avail, 0)))
@@ -140,6 +151,9 @@ new (size_t)
            return info;
          }
 
+      if (was_initialized < 0)
+       ExitThread (0);
+
       if (!was_initialized)
        Sleep (0); /* thread_runner is not finished yet. */
       else
@@ -259,3 +273,12 @@ cygthread::detach ()
        }
     }
 }
+
+void
+cygthread::terminate ()
+{
+  initialized = -1;
+  for (cygthread *info = threads + NTHREADS - 1; info >= threads; info--)
+    if (!(DWORD) InterlockedExchange ((LPLONG) &info->avail, 0) && info->id)
+      SetEvent (info->ev);
+}
index 37f7c65..b55aec9 100644 (file)
@@ -17,7 +17,7 @@ class cygthread
   VOID *arg;
   bool is_freerange;
   static DWORD main_thread_id;
-  static bool initialized;
+  static int initialized;
   static DWORD WINAPI runner (VOID *);
   static DWORD WINAPI free_runner (VOID *);
   static DWORD WINAPI stub (VOID *);
@@ -33,6 +33,7 @@ class cygthread
   void * operator new (size_t);
   static void * freerange ();
   void exit_thread ();
+  static void terminate ();
 };
 
 #define cygself NULL
index 701fb14..58fb823 100644 (file)
@@ -1024,6 +1024,7 @@ do_exit (int status)
   window_terminate ();
   events_terminate ();
   shared_terminate ();
+  cygthread::terminate ();
 
   minimal_printf ("winpid %d, exit %d", GetCurrentProcessId (), n);
   myself->exit (n);
index 4be0bf1..0ac429e 100644 (file)
@@ -159,8 +159,8 @@ class verifyable_object
 public:
   long magic;
 
-    verifyable_object (long);
-   ~verifyable_object ();
+  verifyable_object (long);
+  virtual ~verifyable_object ();
 };
 
 typedef enum
@@ -197,7 +197,7 @@ public:
   void *get () const;
 
   pthread_key (void (*)(void *));
-   ~pthread_key ();
+  ~pthread_key ();
   static void fixup_before_fork();
   static void fixup_after_fork();
 
@@ -225,23 +225,23 @@ template <class ListNode> void
 List<ListNode>::Insert (ListNode *aNode)
 {
   if (!aNode)
-    return;
+  return;
   aNode->next = (ListNode *) InterlockedExchangePointer (&head, aNode);
 }
 template <class ListNode> ListNode *
 List<ListNode>::Remove ( ListNode *aNode)
 {
   if (!aNode)
-    return NULL;
+  return NULL;
   if (!head)
-    return NULL;
+  return NULL;
   if (aNode == head)
-    return Pop ();
+  return Pop ();
   ListNode *resultPrev = head;
   while (resultPrev && resultPrev->next && !(aNode == resultPrev->next))
-    resultPrev = resultPrev->next;
+  resultPrev = resultPrev->next;
   if (resultPrev)
-    return (ListNode *)InterlockedExchangePointer (&resultPrev->next, resultPrev->next->next);
+  return (ListNode *)InterlockedExchangePointer (&resultPrev->next, resultPrev->next->next);
   return NULL;
 }
 template <class ListNode> ListNode *
@@ -255,10 +255,10 @@ List<ListNode>::forEach (void (*callback)(ListNode *))
 {
   ListNode *aNode = head;
   while (aNode) 
-    {
-      callback (aNode);
-      aNode = aNode->next;
-    }
+  {
+    callback (aNode);
+    aNode = aNode->next;
+  }
 }
 
 class pthread_attr:public verifyable_object
@@ -271,8 +271,8 @@ public:
   struct sched_param schedparam;
   size_t stacksize;
 
-    pthread_attr ();
-   ~pthread_attr ();
+  pthread_attr ();
+  ~pthread_attr ();
 };
 
 class pthread_mutexattr:public verifyable_object
@@ -281,8 +281,8 @@ public:
   static bool isGoodObject(pthread_mutexattr_t const *);
   int pshared;
   int mutextype;
-    pthread_mutexattr ();
-   ~pthread_mutexattr ();
+  pthread_mutexattr ();
+  ~pthread_mutexattr ();
 };
 
 class pthread_mutex:public verifyable_object
@@ -327,80 +327,80 @@ public:
   LONG *sigtodo;
   virtual void create (void *(*)(void *), pthread_attr *, void *);
 
-   pthread ();
-   virtual ~pthread ();
+  pthread ();
+  virtual ~pthread ();
 
-   static void initMainThread(pthread *, HANDLE);
-   static bool isGoodObject(pthread_t const *);
-   static void atforkprepare();
-   static void atforkparent();
-   static void atforkchild();
+  static void initMainThread(pthread *, HANDLE);
+  static bool isGoodObject(pthread_t const *);
+  static void atforkprepare();
+  static void atforkparent();
+  static void atforkchild();
 
-   /* API calls */
-   static int cancel (pthread_t);
-   static int join (pthread_t * thread, void **return_val);
-   static int detach (pthread_t * thread);
-   static int create (pthread_t * thread, const pthread_attr_t * attr,
+  /* API calls */
+  static int cancel (pthread_t);
+  static int join (pthread_t * thread, void **return_val);
+  static int detach (pthread_t * thread);
+  static int create (pthread_t * thread, const pthread_attr_t * attr,
                              void *(*start_routine) (void *), void *arg);
-   static int once (pthread_once_t *, void (*)(void));
-   static int atfork(void (*)(void), void (*)(void), void (*)(void));
-   static int suspend (pthread_t * thread);
-   static int resume (pthread_t * thread);
+  static int once (pthread_once_t *, void (*)(void));
+  static int atfork(void (*)(void), void (*)(void), void (*)(void));
+  static int suspend (pthread_t * thread);
+  static int resume (pthread_t * thread);
 
-   virtual void exit (void *value_ptr);
+  virtual void exit (void *value_ptr);
 
-   virtual int cancel ();
-   
-   virtual void testcancel ();
-   static void static_cancel_self ();
+  virtual int cancel ();
+  
+  virtual void testcancel ();
+  static void static_cancel_self ();
 
-   virtual int setcancelstate (int state, int *oldstate);
-   virtual int setcanceltype (int type, int *oldtype);
+  virtual int setcancelstate (int state, int *oldstate);
+  virtual int setcanceltype (int type, int *oldtype);
 
-   virtual void push_cleanup_handler (__pthread_cleanup_handler *handler);
-   virtual void pop_cleanup_handler (int const execute);
+  virtual void push_cleanup_handler (__pthread_cleanup_handler *handler);
+  virtual void pop_cleanup_handler (int const execute);
 
-   static pthread* self ();
-   static void *thread_init_wrapper (void *);
+  static pthread* self ();
+  static void *thread_init_wrapper (void *);
 
-   virtual unsigned long getsequence_np();
+  virtual unsigned long getsequence_np();
 
 private:
-    DWORD thread_id;
-    __pthread_cleanup_handler *cleanup_stack;
-    pthread_mutex mutex;
-
-    void pop_all_cleanup_handlers (void);
-    void precreate (pthread_attr *);
-    void postcreate ();
-    void setThreadIdtoCurrent();
-    static void setTlsSelfPointer(pthread *);
-    void cancel_self ();
-    DWORD getThreadId ();
+  DWORD thread_id;
+  __pthread_cleanup_handler *cleanup_stack;
+  pthread_mutex mutex;
+
+  void pop_all_cleanup_handlers (void);
+  void precreate (pthread_attr *);
+  void postcreate ();
+  void setThreadIdtoCurrent();
+  static void setTlsSelfPointer(pthread *);
+  void cancel_self ();
+  DWORD getThreadId ();
 };
 
 class pthreadNull : public pthread
 {
   public:
-    static pthread *getNullpthread();
-    ~pthreadNull();
-
-    /* From pthread These should never get called
-     * as the ojbect is not verifyable
-     */
-    void create (void *(*)(void *), pthread_attr *, void *);
-    void exit (void *value_ptr);
-    int cancel ();
-    void testcancel ();
-    int setcancelstate (int state, int *oldstate);
-    int setcanceltype (int type, int *oldtype);
-    void push_cleanup_handler (__pthread_cleanup_handler *handler);
-    void pop_cleanup_handler (int const execute);
-    unsigned long getsequence_np();
+  static pthread *getNullpthread();
+  ~pthreadNull();
+
+  /* From pthread These should never get called
+  * as the ojbect is not verifyable
+  */
+  void create (void *(*)(void *), pthread_attr *, void *);
+  void exit (void *value_ptr);
+  int cancel ();
+  void testcancel ();
+  int setcancelstate (int state, int *oldstate);
+  int setcanceltype (int type, int *oldtype);
+  void push_cleanup_handler (__pthread_cleanup_handler *handler);
+  void pop_cleanup_handler (int const execute);
+  unsigned long getsequence_np();
 
   private:
-    pthreadNull ();
-    static pthreadNull _instance;
+  pthreadNull ();
+  static pthreadNull _instance;
 };
 
 class pthread_condattr:public verifyable_object
@@ -432,8 +432,8 @@ public:
   void Signal ();
   void fixup_after_fork ();
 
-    pthread_cond (pthread_condattr *);
-   ~pthread_cond ();
+  pthread_cond (pthread_condattr *);
+  ~pthread_cond ();
 };
 
 class pthread_once
@@ -464,8 +464,8 @@ public:
   int TryWait ();
   void fixup_after_fork ();
 
-    semaphore (int, unsigned int);
-   ~semaphore ();
+  semaphore (int, unsigned int);
+  ~semaphore ();
 };
 
 class callback
@@ -505,11 +505,11 @@ public:
   void fixup_after_fork (void);
 
   MTinterface ():reent_index (0), indexallocated (0), threadcount (1)
-    {
-      pthread_prepare = NULL;
-      pthread_child   = NULL;
-      pthread_parent  = NULL;
-    }
+  {
+    pthread_prepare = NULL;
+    pthread_child   = NULL;
+    pthread_parent  = NULL;
+  }
 };
 
 extern "C"