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.
This commit is contained in:
parent
101f820da2
commit
8e4d969260
@ -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>
|
Tue Sep 11 21:55:37 2001 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
* sigproc.h (sigframe::unregister): Return true/false whether this
|
* sigproc.h (sigframe::unregister): Return true/false whether this
|
||||||
|
@ -478,6 +478,7 @@ LoadDLLfuncEx (CancelIo, 4, kernel32, 1)
|
|||||||
LoadDLLfuncEx (Process32First, 8, kernel32, 1)
|
LoadDLLfuncEx (Process32First, 8, kernel32, 1)
|
||||||
LoadDLLfuncEx (Process32Next, 8, kernel32, 1)
|
LoadDLLfuncEx (Process32Next, 8, kernel32, 1)
|
||||||
LoadDLLfuncEx (CreateToolhelp32Snapshot, 8, kernel32, 1)
|
LoadDLLfuncEx (CreateToolhelp32Snapshot, 8, kernel32, 1)
|
||||||
|
LoadDLLfunc (TryEnterCriticalSection, 4, kernel32)
|
||||||
|
|
||||||
LoadDLLfuncEx (waveOutGetNumDevs, 0, winmm, 1)
|
LoadDLLfuncEx (waveOutGetNumDevs, 0, winmm, 1)
|
||||||
LoadDLLfuncEx (waveOutOpen, 24, winmm, 1)
|
LoadDLLfuncEx (waveOutOpen, 24, winmm, 1)
|
||||||
|
@ -506,8 +506,19 @@ pthread_cond::TimedWait (DWORD dwMilliseconds)
|
|||||||
rv = WaitForSingleObject (win32_obj_id, dwMilliseconds);
|
rv = WaitForSingleObject (win32_obj_id, dwMilliseconds);
|
||||||
}
|
}
|
||||||
else
|
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,
|
rv = SignalObjectAndWait (mutex->win32_obj_id, win32_obj_id, dwMilliseconds,
|
||||||
false);
|
false);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
switch (rv)
|
switch (rv)
|
||||||
{
|
{
|
||||||
case WAIT_FAILED:
|
case WAIT_FAILED:
|
||||||
@ -532,8 +543,13 @@ pthread_cond::fixup_after_fork ()
|
|||||||
this->win32_obj_id =::CreateEvent (&sec_none_nih, false, false, NULL);
|
this->win32_obj_id =::CreateEvent (&sec_none_nih, false, false, NULL);
|
||||||
if (!win32_obj_id)
|
if (!win32_obj_id)
|
||||||
api_fatal("failed to create new win32 mutex\n");
|
api_fatal("failed to create new win32 mutex\n");
|
||||||
|
#if DETECT_BAD_APPS
|
||||||
if (waiting)
|
if (waiting)
|
||||||
api_fatal("Forked() while a condition variable has waiting threads.\nReport to cygwin@cygwin.com\n");
|
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;
|
magic = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (iswinnt)
|
||||||
this->win32_obj_id =::CreateMutex (&sec_none_nih, false, NULL);
|
InitializeCriticalSection (&criticalsection);
|
||||||
|
else
|
||||||
if (!win32_obj_id)
|
{
|
||||||
magic = 0;
|
this->win32_obj_id =::CreateMutex (&sec_none_nih, false, NULL);
|
||||||
|
if (!win32_obj_id)
|
||||||
|
magic = 0;
|
||||||
|
}
|
||||||
condwaits = 0;
|
condwaits = 0;
|
||||||
pshared = PTHREAD_PROCESS_PRIVATE;
|
pshared = PTHREAD_PROCESS_PRIVATE;
|
||||||
/* threadsafe addition is easy */
|
/* threadsafe addition is easy */
|
||||||
@ -617,18 +636,25 @@ pthread_mutex::pthread_mutex (pthread_mutexattr *attr):verifyable_object (PTHREA
|
|||||||
|
|
||||||
pthread_mutex::~pthread_mutex ()
|
pthread_mutex::~pthread_mutex ()
|
||||||
{
|
{
|
||||||
if (win32_obj_id)
|
if (iswinnt)
|
||||||
CloseHandle (win32_obj_id);
|
DeleteCriticalSection (&criticalsection);
|
||||||
win32_obj_id = NULL;
|
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... */
|
/* I'm not 100% sure the next bit is threadsafe. I think it is... */
|
||||||
if (MT_INTERFACE->mutexs == this)
|
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
|
else
|
||||||
{
|
{
|
||||||
pthread_mutex *tempmutex = MT_INTERFACE->mutexs;
|
pthread_mutex *tempmutex = MT_INTERFACE->mutexs;
|
||||||
while (tempmutex->next && tempmutex->next != this)
|
while (tempmutex->next && tempmutex->next != this)
|
||||||
tempmutex = tempmutex->next;
|
tempmutex = tempmutex->next;
|
||||||
/* but there may be a race between the loop above and this statement */
|
/* 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);
|
InterlockedExchangePointer (&tempmutex->next, this->next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -636,19 +662,33 @@ pthread_mutex::~pthread_mutex ()
|
|||||||
int
|
int
|
||||||
pthread_mutex::Lock ()
|
pthread_mutex::Lock ()
|
||||||
{
|
{
|
||||||
|
if (iswinnt)
|
||||||
|
{
|
||||||
|
EnterCriticalSection (&criticalsection);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* FIXME: Return 0 on success */
|
||||||
return WaitForSingleObject (win32_obj_id, INFINITE);
|
return WaitForSingleObject (win32_obj_id, INFINITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* returns non-zero on failure */
|
||||||
int
|
int
|
||||||
pthread_mutex::TryLock ()
|
pthread_mutex::TryLock ()
|
||||||
{
|
{
|
||||||
return WaitForSingleObject (win32_obj_id, 0);
|
if (iswinnt)
|
||||||
|
return (!TryEnterCriticalSection (&criticalsection));
|
||||||
|
return (WaitForSingleObject (win32_obj_id, 0) == WAIT_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pthread_mutex::UnLock ()
|
pthread_mutex::UnLock ()
|
||||||
{
|
{
|
||||||
return ReleaseMutex (win32_obj_id);
|
if (iswinnt)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection (&criticalsection);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (!ReleaseMutex (win32_obj_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -658,12 +698,20 @@ pthread_mutex::fixup_after_fork ()
|
|||||||
if (pshared != PTHREAD_PROCESS_PRIVATE)
|
if (pshared != PTHREAD_PROCESS_PRIVATE)
|
||||||
api_fatal("pthread_mutex::fixup_after_fork () doesn'tunderstand PROCESS_SHARED mutex's\n");
|
api_fatal("pthread_mutex::fixup_after_fork () doesn'tunderstand PROCESS_SHARED mutex's\n");
|
||||||
/* FIXME: duplicate code here and in the constructor. */
|
/* FIXME: duplicate code here and in the constructor. */
|
||||||
this->win32_obj_id =::CreateMutex (&sec_none_nih, false, NULL);
|
if (iswinnt)
|
||||||
|
InitializeCriticalSection(&criticalsection);
|
||||||
if (!win32_obj_id)
|
else
|
||||||
api_fatal("pthread_mutex::fixup_after_fork() failed to create new win32 mutex\n");
|
{
|
||||||
|
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)
|
if (condwaits)
|
||||||
api_fatal("Forked() while a mutex has condition variables waiting on it.\nReport to cygwin@cygwin.com\n");
|
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),
|
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);
|
__pthread_mutex_init (mutex, NULL);
|
||||||
if (!verifyable_object_isvalid (*themutex, PTHREAD_MUTEX_MAGIC))
|
if (!verifyable_object_isvalid (*themutex, PTHREAD_MUTEX_MAGIC))
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
if ((*themutex)->TryLock () == WAIT_TIMEOUT)
|
if ((*themutex)->TryLock ())
|
||||||
return EBUSY;
|
return EBUSY;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1927,7 +1975,7 @@ __pthread_mutex_unlock (pthread_mutex_t *mutex)
|
|||||||
int
|
int
|
||||||
__pthread_mutex_destroy (pthread_mutex_t *mutex)
|
__pthread_mutex_destroy (pthread_mutex_t *mutex)
|
||||||
{
|
{
|
||||||
if (*mutex == PTHREAD_MUTEX_INITIALIZER)
|
if (check_valid_pointer (mutex) && (*mutex == PTHREAD_MUTEX_INITIALIZER))
|
||||||
return 0;
|
return 0;
|
||||||
if (!verifyable_object_isvalid (*mutex, PTHREAD_MUTEX_MAGIC))
|
if (!verifyable_object_isvalid (*mutex, PTHREAD_MUTEX_MAGIC))
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
@ -267,6 +267,7 @@ public:
|
|||||||
class pthread_mutex:public verifyable_object
|
class pthread_mutex:public verifyable_object
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
CRITICAL_SECTION criticalsection;
|
||||||
HANDLE win32_obj_id;
|
HANDLE win32_obj_id;
|
||||||
LONG condwaits;
|
LONG condwaits;
|
||||||
int pshared;
|
int pshared;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user