diff -urp src.old/winsup/cygwin/dcrt0.cc src/winsup/cygwin/dcrt0.cc --- src.old/winsup/cygwin/dcrt0.cc 2002-10-23 20:42:51.000000000 +0200 +++ src/winsup/cygwin/dcrt0.cc 2002-10-31 10:22:17.000000000 +0100 @@ -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 (); diff -urp src.old/winsup/cygwin/init.cc src/winsup/cygwin/init.cc --- src.old/winsup/cygwin/init.cc 2002-10-13 20:31:18.000000000 +0200 +++ src/winsup/cygwin/init.cc 2002-10-28 16:28:58.000000000 +0100 @@ -27,12 +27,8 @@ WINAPI dll_entry (HANDLE h, DWORD reason 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 */; diff -urp src.old/winsup/cygwin/thread.cc src/winsup/cygwin/thread.cc --- src.old/winsup/cygwin/thread.cc 2002-10-21 03:03:32.000000000 +0200 +++ src/winsup/cygwin/thread.cc 2002-11-05 13:16:18.000000000 +0100 @@ -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 * { 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 *), void pthreadNull::exit (void *value_ptr) { + ExitThread (0); } int diff -urp src.old/winsup/cygwin/thread.h src/winsup/cygwin/thread.h --- src.old/winsup/cygwin/thread.h 2002-10-17 23:38:06.000000000 +0200 +++ src/winsup/cygwin/thread.h 2002-11-04 10:08:07.000000000 +0100 @@ -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);