From f8c8e13b7e16dba8c04adc6912a0610292488656 Mon Sep 17 00:00:00 2001 From: Robert Collins Date: Sun, 24 Nov 2002 13:54:14 +0000 Subject: 2002-11-05 Thomas Pfaff * 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 | 37 ++++++++++++++++ winsup/cygwin/dcrt0.cc | 2 + winsup/cygwin/init.cc | 6 +-- winsup/cygwin/thread.cc | 115 +++++++++++++++++++++++------------------------- winsup/cygwin/thread.h | 28 +++++++----- 5 files changed, 110 insertions(+), 78 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index df099b0a8..a6eeef1da 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,40 @@ +2002-11-05 Thomas Pfaff + + * 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 * wait.cc (wait4): Force pending signal delivery before waiting for diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 22899e452..6c6acbd37 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -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 --git a/winsup/cygwin/init.cc b/winsup/cygwin/init.cc index 311429351..f740dcefe 100644 --- a/winsup/cygwin/init.cc +++ b/winsup/cygwin/init.cc @@ -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 */; diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index e2fc0affd..b77a2e50f 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -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 diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h index 73e57edfa..32175a4ac 100644 --- a/winsup/cygwin/thread.h +++ b/winsup/cygwin/thread.h @@ -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); -- cgit v1.2.3