OSDN Git Service

2002-11-05 Thomas Pfaff <tpfaff@gmx.net>
authorrbcollins <rbcollins>
Sun, 24 Nov 2002 13:54:14 +0000 (13:54 +0000)
committerrbcollins <rbcollins>
Sun, 24 Nov 2002 13:54:14 +0000 (13:54 +0000)
        * dcrt0.cc (dll_crt0_1): Add call to pthread::initMainThread to
        initialize mainthread when it is safe to call new.
        * init.cc (dll_entry): Change call to store reents in tls key.
        * thread.cc (_reent_clib) : Change call to get reents from tls
        key.
        (_reent_winsup): Ditto.
        (MTinterface::Init): Key handling changed. Remove initialization
        of member variables.
        (MTinterface::fixup_after_fork): Reinitialize mainthread object
        after fork. Reset threadount to 1.
        (pthread::initMainThread): Create mainthread object dynamically.
        and initialize with valid handles.
        (pthread::self): Remove calls to create thread objects.
        (pthread::setTlsSelfPointer): Change call to store thread self
        handle in tls key.
        (pthread::getTlsSelfPointer): New static method.
        (pthread::exit): Remove setTlsSelfPointer call.
        (pthread::initCurrentThread): New method.
        (pthread::thread_init_wrapper): Change call to store thread self
        handle in tls key.
        (pthread::join): Check for a valid joiner.
        (pthreadNull::pthreadNull): Mark Null object as detached.
        (pthreadNull::exit): Terminate thread via ExitThread.
        * thread.h (pthread::initMainThread): Change parameter in function
        call.
        (pthread::getTlsSelfPointer): New static method.
        (pthread::initCurrentThread): New method.
        (MTinterface::reent_key): Remove.
        (MTinterface::thread_self_dwTlsIndex): Ditto..
        (MTinterface::indexallocated): Ditto.
        (MTinterface::mainthread): Ditto.
        (MTinterface::reent_key): New member.
        (MTinterface::thread_self_key): Ditto.
        (MTinterface::MTinterface): Initialize all members.

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

index df099b0..a6eeef1 100644 (file)
@@ -1,3 +1,40 @@
+2002-11-05  Thomas Pfaff  <tpfaff@gmx.net>
+
+       * dcrt0.cc (dll_crt0_1): Add call to pthread::initMainThread to
+       initialize mainthread when it is safe to call new.
+       * init.cc (dll_entry): Change call to store reents in tls key.
+       * thread.cc (_reent_clib) : Change call to get reents from tls
+       key.
+       (_reent_winsup): Ditto.
+       (MTinterface::Init): Key handling changed. Remove initialization
+       of member variables.
+       (MTinterface::fixup_after_fork): Reinitialize mainthread object
+       after fork. Reset threadount to 1.
+       (pthread::initMainThread): Create mainthread object dynamically.
+       and initialize with valid handles.
+       (pthread::self): Remove calls to create thread objects.
+       (pthread::setTlsSelfPointer): Change call to store thread self
+       handle in tls key.
+       (pthread::getTlsSelfPointer): New static method.
+       (pthread::exit): Remove setTlsSelfPointer call.
+       (pthread::initCurrentThread): New method.
+       (pthread::thread_init_wrapper): Change call to store thread self
+       handle in tls key.
+       (pthread::join): Check for a valid joiner.
+       (pthreadNull::pthreadNull): Mark Null object as detached.
+       (pthreadNull::exit): Terminate thread via ExitThread.
+       * thread.h (pthread::initMainThread): Change parameter in function
+       call.
+       (pthread::getTlsSelfPointer): New static method.
+       (pthread::initCurrentThread): New method.
+       (MTinterface::reent_key): Remove.
+       (MTinterface::thread_self_dwTlsIndex): Ditto..
+       (MTinterface::indexallocated): Ditto.
+       (MTinterface::mainthread): Ditto.
+       (MTinterface::reent_key): New member.
+       (MTinterface::thread_self_key): Ditto.
+       (MTinterface::MTinterface): Initialize all members.
+
 2002-11-23  Christopher Faylor  <cgf@redhat.com>
 
        * wait.cc (wait4): Force pending signal delivery before waiting for
index 22899e4..6c6acbd 100644 (file)
@@ -628,6 +628,8 @@ dll_crt0_1 ()
   ProtectHandle (hMainThread);
   cygthread::init ();
 
+  pthread::initMainThread (!user_data->forkee);
+
   /* Initialize debug muto, if DLL is built with --enable-debugging.
      Need to do this before any helper threads start. */
   debug_init ();
index 3114293..f740dce 100644 (file)
@@ -27,12 +27,8 @@ WINAPI dll_entry (HANDLE h, DWORD reason, void *static_load)
     case DLL_PROCESS_DETACH:
       break;
     case DLL_THREAD_ATTACH:
-      if (user_data->threadinterface)
-       {
-         if (!TlsSetValue (user_data->threadinterface->reent_index,
-                           &user_data->threadinterface->reents))
+      if (MT_INTERFACE->reent_key.set (&MT_INTERFACE->reents))
            api_fatal ("thread initialization failed");
-       }
       break;
     case DLL_THREAD_DETACH:
       /* not invoked */;
index e2fc0af..b77a2e5 100644 (file)
@@ -46,35 +46,29 @@ details. */
 
 extern int threadsafe;
 
-#define MT_INTERFACE user_data->threadinterface
-
 struct _reent *
 _reent_clib ()
 {
-  int tmp = GetLastError ();
   struct __reent_t *_r =
-    (struct __reent_t *) TlsGetValue (MT_INTERFACE->reent_index);
+    (struct __reent_t *) MT_INTERFACE->reent_key.get ();
 
 #ifdef _CYG_THREAD_FAILSAFE
   if (_r == 0)
     system_printf ("local thread storage not inited");
 #endif
-
-  SetLastError (tmp);
   return _r->_clib;
 }
 
 struct _winsup_t *
 _reent_winsup ()
 {
-  int tmp = GetLastError ();
-  struct __reent_t *_r;
-  _r = (struct __reent_t *) TlsGetValue (MT_INTERFACE->reent_index);
+  struct __reent_t *_r =
+    (struct __reent_t *) MT_INTERFACE->reent_key.get ();
+
 #ifdef _CYG_THREAD_FAILSAFE
   if (_r == 0)
     system_printf ("local thread storage not inited");
 #endif
-  SetLastError (tmp);
   return _r->_winsup;
 }
 
@@ -166,39 +160,14 @@ ResourceLocks::Delete ()
 void
 MTinterface::Init (int forked)
 {
-
-  reent_index = TlsAlloc ();
   reents._clib = _impure_ptr;
   reents._winsup = &winsup_reent;
-
   winsup_reent._process_logmask = LOG_UPTO (LOG_DEBUG);
 
-  TlsSetValue (reent_index, &reents);
-  // the static reent_data will be used in the main thread
-
-  if (!indexallocated)
-    {
-      thread_self_dwTlsIndex = TlsAlloc ();
-      if (thread_self_dwTlsIndex == TLS_OUT_OF_INDEXES)
-       system_printf
-         ("local storage for thread couldn't be set\nThis means that we are not thread safe!");
-      else
-       indexallocated = (-1);
-    }
+  if (!forked)
+    reent_key.set (&reents);
 
-  concurrency = 0;
-  threadcount = 1; /* 1 current thread when Init occurs.*/
-
-  pthread::initMainThread (&mainthread, myself->hProcess);
   pthread_mutex::initMutex ();
-
-  if (forked)
-    return;
-
-  mutexs = NULL;
-  conds  = NULL;
-  semaphores = NULL;
-
 }
 
 void
@@ -233,40 +202,51 @@ MTinterface::fixup_after_fork (void)
       sem->fixup_after_fork ();
       sem = sem->next;
     }
+
+  pthread::initMainThread (true);
+
+  threadcount = 1;
 }
 
 /* pthread calls */
 
 /* static methods */
 void
-pthread::initMainThread (pthread *mainThread, HANDLE win32_obj_id)
+pthread::initMainThread (bool do_init)
 {
-  mainThread->win32_obj_id = win32_obj_id;
-  mainThread->setThreadIdtoCurrent ();
-  setTlsSelfPointer (mainThread);
+  if (!do_init)
+    return;
+
+  pthread *thread = getTlsSelfPointer ();
+  if (!thread)
+    {
+      thread = new pthread ();
+      if (!thread)
+        api_fatal ("failed to create mainthread object");
+    }
+
+  thread->initCurrentThread ();
 }
 
 pthread *
 pthread::self ()
 {
-  pthread *temp = (pthread *) TlsGetValue (MT_INTERFACE->thread_self_dwTlsIndex);
-  if (temp)
-      return temp;
-  temp = new pthread ();
-  temp->precreate (NULL);
-  if (!temp->magic) {
-      delete temp;
-      return pthreadNull::getNullpthread ();
-  }
-  temp->postcreate ();
-  return temp;
+  pthread *thread = getTlsSelfPointer ();
+  if (thread)
+    return thread;
+  return pthreadNull::getNullpthread ();
 }
 
 void
 pthread::setTlsSelfPointer (pthread *thisThread)
 {
-  /* the OS doesn't check this for <= 64 Tls entries (pre win2k) */
-  TlsSetValue (MT_INTERFACE->thread_self_dwTlsIndex, thisThread);
+  MT_INTERFACE->thread_self_key.set (thisThread);
+}
+
+pthread *
+pthread::getTlsSelfPointer ()
+{
+  return (pthread *) MT_INTERFACE->thread_self_key.get ();
 }
 
 
@@ -384,9 +364,6 @@ pthread::exit (void *value_ptr)
       mutex.UnLock ();
     }
 
-  /* Prevent DLL_THREAD_DETACH Attempting to clean us up */
-  setTlsSelfPointer (0);
-
   if (InterlockedDecrement (&MT_INTERFACE->threadcount) == 0)
     ::exit (0);
   else
@@ -715,6 +692,18 @@ pthread::getThreadId ()
   return thread_id;
 }
 
+void
+pthread::initCurrentThread ()
+{
+  cancel_event = ::CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
+  if (!DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
+                        GetCurrentProcess (), &win32_obj_id,
+                        0, FALSE, DUPLICATE_SAME_ACCESS))
+    win32_obj_id = NULL;
+  setThreadIdtoCurrent ();
+  setTlsSelfPointer (this);
+}
+
 /* static members */
 bool
 pthread_attr::isGoodObject (pthread_attr_t const *attr)
@@ -1411,16 +1400,15 @@ pthread::thread_init_wrapper (void *_arg)
 
   local_winsup._process_logmask = LOG_UPTO (LOG_DEBUG);
 
-  /* This is not checked by the OS !! */
-  if (!TlsSetValue (MT_INTERFACE->reent_index, &local_reent))
-    system_printf ("local storage for thread couldn't be set");
+  MT_INTERFACE->reent_key.set (&local_reent);
 
+  thread->setThreadIdtoCurrent ();
   setTlsSelfPointer (thread);
 
   thread->mutex.Lock ();
   // if thread is detached force cleanup on exit
   if (thread->attr.joinable == PTHREAD_CREATE_DETACHED && thread->joiner == NULL)
-    thread->joiner = pthread::self ();
+    thread->joiner = thread;
   thread->mutex.UnLock ();
 
 #ifdef _CYG_THREAD_FAILSAFE
@@ -1787,6 +1775,9 @@ pthread::join (pthread_t *thread, void **return_val)
 {
    pthread_t joiner = self ();
 
+   if (!isGoodObject (&joiner))
+     return EINVAL;
+
    // Initialize return val with NULL
    if (return_val)
      *return_val = NULL;
@@ -2594,6 +2585,7 @@ pthreadNull::getNullpthread ()
 
 pthreadNull::pthreadNull ()
 {
+  attr.joinable = PTHREAD_CREATE_DETACHED;
   /* Mark ourselves as invalid */
   magic = 0;
 }
@@ -2610,6 +2602,7 @@ pthreadNull::create (void *(*)(void *), pthread_attr *, void *)
 void
 pthreadNull::exit (void *value_ptr)
 {
+  ExitThread (0);
 }
 
 int
index 73e57ed..32175a4 100644 (file)
@@ -344,7 +344,7 @@ public:
   pthread ();
   virtual ~pthread ();
 
-  static void initMainThread(pthread *, HANDLE);
+  static void initMainThread (bool);
   static bool isGoodObject(pthread_t const *);
   static void atforkprepare();
   static void atforkparent();
@@ -387,10 +387,12 @@ private:
   void pop_all_cleanup_handlers (void);
   void precreate (pthread_attr *);
   void postcreate ();
-  void setThreadIdtoCurrent();
-  static void setTlsSelfPointer(pthread *);
+  void setThreadIdtoCurrent ();
+  static void setTlsSelfPointer (pthread *);
+  static pthread *getTlsSelfPointer ();
   void cancel_self ();
   DWORD getThreadId ();
+  void initCurrentThread ();
 };
 
 class pthreadNull : public pthread
@@ -493,17 +495,12 @@ class MTinterface
 {
 public:
   // General
-  DWORD reent_index;
-  DWORD thread_self_dwTlsIndex;
-  /* we may get 0 for the Tls index.. grrr */
-  int indexallocated;
   int concurrency;
   long int threadcount;
 
   // Used for main thread data, and sigproc thread
   struct __reent_t reents;
   struct _winsup_t winsup_reent;
-  pthread mainthread;
 
   callback *pthread_prepare;
   callback *pthread_child;
@@ -514,18 +511,25 @@ public:
   class pthread_cond  * conds;
   class semaphore     * semaphores;
 
+  pthread_key reent_key;
+  pthread_key thread_self_key;
+
   void Init (int);
   void fixup_before_fork (void);
   void fixup_after_fork (void);
 
-  MTinterface ():reent_index (0), indexallocated (0), threadcount (1)
+  MTinterface () :
+    concurrency (0), threadcount (1),
+    pthread_prepare (NULL), pthread_child (NULL), pthread_parent (NULL),
+    mutexs (NULL), conds (NULL), semaphores (NULL),
+    reent_key (NULL), thread_self_key (NULL)
   {
-    pthread_prepare = NULL;
-    pthread_child   = NULL;
-    pthread_parent  = NULL;
   }
 };
 
+#define MT_INTERFACE user_data->threadinterface
+
 extern "C"
 {
 int __pthread_attr_init (pthread_attr_t * attr);