diff options
author | Robert Collins <rbtcollins@hotmail.com> | 2001-09-12 03:18:05 +0000 |
---|---|---|
committer | Robert Collins <rbtcollins@hotmail.com> | 2001-09-12 03:18:05 +0000 |
commit | 8e4d9692605463b1ad6786d11a731c3f3ab3da87 (patch) | |
tree | 227520d8b8315c5fbfd0592bbbc5788eb12078b2 /winsup | |
parent | 101f820da27a0aa142df153e35d2890209b49456 (diff) | |
download | newlib-8e4d9692605463b1ad6786d11a731c3f3ab3da87.zip newlib-8e4d9692605463b1ad6786d11a731c3f3ab3da87.tar.gz newlib-8e4d9692605463b1ad6786d11a731c3f3ab3da87.tar.bz2 |
Wed Sep 12 13:03:00 2001 Robert Collins <rbtcollins@hotmail.com>
* autoload.cc (LoadDLLfuncEx): Auto load TryEnterCriticalSection - its a
n NT only call.
* thread.cc (pthread_cond::TimedWait): Use critical sections for NT.
(pthread_cond::fixup_after_fork): Don't detect bad apps.
(pthread_mutex::pthread_mutex): Use critical sections for NT.
(pthread_mutex::~pthread_mutex): Ditto.
(pthread_mutex::Lock): Ditto.
(pthread_mutex::TryLock): Ditto.
(pthread_mutex::UnLock): Ditto.
(pthread_mutex::fixup_after_fork): Ditto. Also do not detect bad apps.
(__pthread_mutex_trylock): Move WIN32 specific test into the class metho
d.
(__pthread_mutex_destroy): Prevent dereferencing passed pointer without
valid address.
* thread.h (pthread_mutex): Use critical sections for NT.
Diffstat (limited to 'winsup')
-rw-r--r-- | winsup/cygwin/ChangeLog | 15 | ||||
-rw-r--r-- | winsup/cygwin/autoload.cc | 1 | ||||
-rw-r--r-- | winsup/cygwin/thread.cc | 82 | ||||
-rw-r--r-- | winsup/cygwin/thread.h | 1 |
4 files changed, 82 insertions, 17 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index d5868b3..538803b 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,18 @@ +Wed Sep 12 13:03:00 2001 Robert Collins <rbtcollins@hotmail.com> + + * autoload.cc (LoadDLLfuncEx): Auto load TryEnterCriticalSection - its an NT only call. + * thread.cc (pthread_cond::TimedWait): Use critical sections for NT. + (pthread_cond::fixup_after_fork): Don't detect bad apps. + (pthread_mutex::pthread_mutex): Use critical sections for NT. + (pthread_mutex::~pthread_mutex): Ditto. + (pthread_mutex::Lock): Ditto. + (pthread_mutex::TryLock): Ditto. + (pthread_mutex::UnLock): Ditto. + (pthread_mutex::fixup_after_fork): Ditto. Also do not detect bad apps. + (__pthread_mutex_trylock): Move WIN32 specific test into the class method. + (__pthread_mutex_destroy): Prevent dereferencing passed pointer without valid address. + * thread.h (pthread_mutex): Use critical sections for NT. + Tue Sep 11 21:55:37 2001 Christopher Faylor <cgf@cygnus.com> * sigproc.h (sigframe::unregister): Return true/false whether this diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index bcbaac3..253b56e 100644 --- a/winsup/cygwin/autoload.cc +++ b/winsup/cygwin/autoload.cc @@ -478,6 +478,7 @@ LoadDLLfuncEx (CancelIo, 4, kernel32, 1) LoadDLLfuncEx (Process32First, 8, kernel32, 1) LoadDLLfuncEx (Process32Next, 8, kernel32, 1) LoadDLLfuncEx (CreateToolhelp32Snapshot, 8, kernel32, 1) +LoadDLLfunc (TryEnterCriticalSection, 4, kernel32) LoadDLLfuncEx (waveOutGetNumDevs, 0, winmm, 1) LoadDLLfuncEx (waveOutOpen, 24, winmm, 1) diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index 609bb07..d3a26de 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -506,8 +506,19 @@ pthread_cond::TimedWait (DWORD dwMilliseconds) rv = WaitForSingleObject (win32_obj_id, dwMilliseconds); } else + { + LeaveCriticalSection (&mutex->criticalsection); + rv = WaitForSingleObject (win32_obj_id, dwMilliseconds); +#if 0 + /* we need to use native win32 mutex's here, because the cygwin ones now use + * critical sections, which are faster, but introduce a race _here_. Until then + * The NT variant of the code is redundant. + */ + rv = SignalObjectAndWait (mutex->win32_obj_id, win32_obj_id, dwMilliseconds, false); +#endif + } switch (rv) { case WAIT_FAILED: @@ -532,8 +543,13 @@ pthread_cond::fixup_after_fork () this->win32_obj_id =::CreateEvent (&sec_none_nih, false, false, NULL); if (!win32_obj_id) api_fatal("failed to create new win32 mutex\n"); +#if DETECT_BAD_APPS if (waiting) api_fatal("Forked() while a condition variable has waiting threads.\nReport to cygwin@cygwin.com\n"); +#else + waiting = 0; + mutex = NULL; +#endif } @@ -604,11 +620,14 @@ pthread_mutex::pthread_mutex (pthread_mutexattr *attr):verifyable_object (PTHREA magic = 0; return; } - - this->win32_obj_id =::CreateMutex (&sec_none_nih, false, NULL); - - if (!win32_obj_id) - magic = 0; + if (iswinnt) + InitializeCriticalSection (&criticalsection); + else + { + this->win32_obj_id =::CreateMutex (&sec_none_nih, false, NULL); + if (!win32_obj_id) + magic = 0; + } condwaits = 0; pshared = PTHREAD_PROCESS_PRIVATE; /* threadsafe addition is easy */ @@ -617,18 +636,25 @@ pthread_mutex::pthread_mutex (pthread_mutexattr *attr):verifyable_object (PTHREA pthread_mutex::~pthread_mutex () { - if (win32_obj_id) - CloseHandle (win32_obj_id); - win32_obj_id = NULL; + if (iswinnt) + DeleteCriticalSection (&criticalsection); + else + { + if (win32_obj_id) + CloseHandle (win32_obj_id); + win32_obj_id = NULL; + } /* I'm not 100% sure the next bit is threadsafe. I think it is... */ if (MT_INTERFACE->mutexs == this) - InterlockedExchangePointer (&MT_INTERFACE->mutexs, this->next); + /* TODO: printf an error if the return value != this */ + InterlockedExchangePointer (&MT_INTERFACE->mutexs, next); else { pthread_mutex *tempmutex = MT_INTERFACE->mutexs; while (tempmutex->next && tempmutex->next != this) tempmutex = tempmutex->next; /* but there may be a race between the loop above and this statement */ + /* TODO: printf an error if the return value != this */ InterlockedExchangePointer (&tempmutex->next, this->next); } } @@ -636,19 +662,33 @@ pthread_mutex::~pthread_mutex () int pthread_mutex::Lock () { + if (iswinnt) + { + EnterCriticalSection (&criticalsection); + return 0; + } + /* FIXME: Return 0 on success */ return WaitForSingleObject (win32_obj_id, INFINITE); } +/* returns non-zero on failure */ int pthread_mutex::TryLock () { - return WaitForSingleObject (win32_obj_id, 0); + if (iswinnt) + return (!TryEnterCriticalSection (&criticalsection)); + return (WaitForSingleObject (win32_obj_id, 0) == WAIT_TIMEOUT); } int pthread_mutex::UnLock () { - return ReleaseMutex (win32_obj_id); + if (iswinnt) + { + LeaveCriticalSection (&criticalsection); + return 0; + } + return (!ReleaseMutex (win32_obj_id)); } void @@ -658,12 +698,20 @@ pthread_mutex::fixup_after_fork () if (pshared != PTHREAD_PROCESS_PRIVATE) api_fatal("pthread_mutex::fixup_after_fork () doesn'tunderstand PROCESS_SHARED mutex's\n"); /* FIXME: duplicate code here and in the constructor. */ - this->win32_obj_id =::CreateMutex (&sec_none_nih, false, NULL); - - if (!win32_obj_id) - api_fatal("pthread_mutex::fixup_after_fork() failed to create new win32 mutex\n"); + if (iswinnt) + InitializeCriticalSection(&criticalsection); + else + { + win32_obj_id =::CreateMutex (&sec_none_nih, false, NULL); + if (!win32_obj_id) + api_fatal("pthread_mutex::fixup_after_fork() failed to create new win32 mutex\n"); + } +#if DETECT_BAD_APPS if (condwaits) api_fatal("Forked() while a mutex has condition variables waiting on it.\nReport to cygwin@cygwin.com\n"); +#else + condwaits = 0; +#endif } pthread_mutexattr::pthread_mutexattr ():verifyable_object (PTHREAD_MUTEXATTR_MAGIC), @@ -1908,7 +1956,7 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) __pthread_mutex_init (mutex, NULL); if (!verifyable_object_isvalid (*themutex, PTHREAD_MUTEX_MAGIC)) return EINVAL; - if ((*themutex)->TryLock () == WAIT_TIMEOUT) + if ((*themutex)->TryLock ()) return EBUSY; return 0; } @@ -1927,7 +1975,7 @@ __pthread_mutex_unlock (pthread_mutex_t *mutex) int __pthread_mutex_destroy (pthread_mutex_t *mutex) { - if (*mutex == PTHREAD_MUTEX_INITIALIZER) + if (check_valid_pointer (mutex) && (*mutex == PTHREAD_MUTEX_INITIALIZER)) return 0; if (!verifyable_object_isvalid (*mutex, PTHREAD_MUTEX_MAGIC)) return EINVAL; diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h index 6bcf3c2..68b29a9 100644 --- a/winsup/cygwin/thread.h +++ b/winsup/cygwin/thread.h @@ -267,6 +267,7 @@ public: class pthread_mutex:public verifyable_object { public: + CRITICAL_SECTION criticalsection; HANDLE win32_obj_id; LONG condwaits; int pshared; |