diff options
author | Robert Collins <rbtcollins@hotmail.com> | 2002-11-24 13:54:14 +0000 |
---|---|---|
committer | Robert Collins <rbtcollins@hotmail.com> | 2002-11-24 13:54:14 +0000 |
commit | f8c8e13b7e16dba8c04adc6912a0610292488656 (patch) | |
tree | d4595038845d61fb3fe6c3d54b255068ca38a90c /winsup/cygwin/thread.cc | |
parent | 4f0de34d3747d689cc741f045072486b0c602f15 (diff) | |
download | cygnal-f8c8e13b7e16dba8c04adc6912a0610292488656.tar.gz cygnal-f8c8e13b7e16dba8c04adc6912a0610292488656.tar.bz2 cygnal-f8c8e13b7e16dba8c04adc6912a0610292488656.zip |
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.
Diffstat (limited to 'winsup/cygwin/thread.cc')
-rw-r--r-- | winsup/cygwin/thread.cc | 115 |
1 files changed, 54 insertions, 61 deletions
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 |