* dcrt0.cc (_dll_crt0): Set _main_tls as early as possible.
* thread.cc (pthread_mutex::can_be_unlocked): Remove check for MUTEX_OWNER_ANONYMOUS since it is racy and unsafe. (pthread::init_mainthread): Initialize thread directly from _my_tls. (pthread::self): Ditto. (pthread::get_tls_self_pointer): Delete. (pthread_mutex::pthread_mutex): Use an event rather than a semaphore. (pthread_mutex::lock): Rename from _<func>. Derive self directly. (pthread_mutex::tryunlock): Ditto. (pthread_mutex::destroy): Ditto. (pthread_mutex::unlock): Ditto. Accommodate change from semaphore to event. (pthread_mutex::_fixup_after_fork): Accommodate change from semaphore to event. (pthread_mutex::init): Don't attempt to initialize a semaphore unless it is in an initialized state. Do this check under mutex_initialization_lock.lock * thread.h (fast_mutex::init): Use event rather than semaphore. (fast_mutex::lock): Ditto. (pthread_mutex::_lock): Delete. (pthread_mutex::_unlock): Ditto. (pthread_mutex::_trylock): Ditto. (pthread_mutex::_destroy): Ditto. (pthread_mutex::get_pthread_self): Ditto. (pthread_mutex::get_tls_self_pointer): Ditto. (pthread_mutex::lock): Un-inline. (pthread_mutex::unlock): Ditto. (pthread_mutex::trylock): Ditto. (pthread_mutex::destroy): Ditto.
This commit is contained in:
parent
161387a725
commit
3700578ee8
|
@ -1,3 +1,35 @@
|
|||
2010-02-10 Christopher Faylor <me+cygwin@cgf.cx>
|
||||
|
||||
* dcrt0.cc (_dll_crt0): Set _main_tls as early as possible.
|
||||
* thread.cc (pthread_mutex::can_be_unlocked): Remove check for
|
||||
MUTEX_OWNER_ANONYMOUS since it is racy and unsafe.
|
||||
(pthread::init_mainthread): Initialize thread directly from _my_tls.
|
||||
(pthread::self): Ditto.
|
||||
(pthread::get_tls_self_pointer): Delete.
|
||||
(pthread_mutex::pthread_mutex): Use an event rather than a semaphore.
|
||||
(pthread_mutex::lock): Rename from _<func>. Derive self directly.
|
||||
(pthread_mutex::tryunlock): Ditto.
|
||||
(pthread_mutex::destroy): Ditto.
|
||||
(pthread_mutex::unlock): Ditto. Accommodate change from semaphore to
|
||||
event.
|
||||
(pthread_mutex::_fixup_after_fork): Accommodate change from semaphore
|
||||
to event.
|
||||
(pthread_mutex::init): Don't attempt to initialize a semaphore unless
|
||||
it is in an initialized state. Do this check under
|
||||
mutex_initialization_lock.lock
|
||||
* thread.h (fast_mutex::init): Use event rather than semaphore.
|
||||
(fast_mutex::lock): Ditto.
|
||||
(pthread_mutex::_lock): Delete.
|
||||
(pthread_mutex::_unlock): Ditto.
|
||||
(pthread_mutex::_trylock): Ditto.
|
||||
(pthread_mutex::_destroy): Ditto.
|
||||
(pthread_mutex::get_pthread_self): Ditto.
|
||||
(pthread_mutex::get_tls_self_pointer): Ditto.
|
||||
(pthread_mutex::lock): Un-inline.
|
||||
(pthread_mutex::unlock): Ditto.
|
||||
(pthread_mutex::trylock): Ditto.
|
||||
(pthread_mutex::destroy): Ditto.
|
||||
|
||||
2010-02-09 Christopher Faylor <me+cygwin@cgf.cx>
|
||||
|
||||
* cygtls.h (struct _cygtls): Remove unneeded elements.
|
||||
|
|
|
@ -955,11 +955,16 @@ _dll_crt0 ()
|
|||
{
|
||||
main_environ = user_data->envptr;
|
||||
if (in_forkee)
|
||||
fork_info->alloc_stack ();
|
||||
{
|
||||
fork_info->alloc_stack ();
|
||||
_main_tls = &_my_tls;
|
||||
}
|
||||
else
|
||||
__sinit (_impure_ptr);
|
||||
{
|
||||
_main_tls = &_my_tls;
|
||||
__sinit (_impure_ptr);
|
||||
}
|
||||
|
||||
_main_tls = &_my_tls;
|
||||
_main_tls->call ((DWORD (*) (void *, void *)) dll_crt0_1, NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* thread.cc: Locking and threading module functions
|
||||
|
||||
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||
2006, 2007, 2008 Red Hat, Inc.
|
||||
2006, 2007, 2008, 2009, 2010 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -187,9 +187,8 @@ pthread_mutex::can_be_unlocked (pthread_mutex_t const *mutex)
|
|||
return false;
|
||||
/* Check if the mutex is owned by the current thread and can be unlocked.
|
||||
* Also check for the ANONYMOUS owner to cover NORMAL mutexes as well. */
|
||||
return ((*mutex)->recursion_counter == 1
|
||||
&& ((*mutex)->owner == MUTEX_OWNER_ANONYMOUS
|
||||
|| pthread::equal ((*mutex)->owner, self)));
|
||||
return (*mutex)->recursion_counter == 1
|
||||
&& pthread::equal ((*mutex)->owner, self);
|
||||
}
|
||||
|
||||
inline bool
|
||||
|
@ -302,7 +301,7 @@ MTinterface::fixup_after_fork ()
|
|||
void
|
||||
pthread::init_mainthread ()
|
||||
{
|
||||
pthread *thread = get_tls_self_pointer ();
|
||||
pthread *thread = _my_tls.tid;
|
||||
if (!thread)
|
||||
{
|
||||
thread = new pthread ();
|
||||
|
@ -325,7 +324,7 @@ pthread::init_mainthread ()
|
|||
pthread *
|
||||
pthread::self ()
|
||||
{
|
||||
pthread *thread = get_tls_self_pointer ();
|
||||
pthread *thread = _my_tls.tid;
|
||||
if (!thread)
|
||||
{
|
||||
thread = pthread_null::get_null_pthread ();
|
||||
|
@ -334,12 +333,6 @@ pthread::self ()
|
|||
return thread;
|
||||
}
|
||||
|
||||
pthread *
|
||||
pthread::get_tls_self_pointer ()
|
||||
{
|
||||
return _my_tls.tid;
|
||||
}
|
||||
|
||||
void
|
||||
pthread::set_tls_self_pointer (pthread *thread)
|
||||
{
|
||||
|
@ -1561,7 +1554,7 @@ pthread_mutex::pthread_mutex (pthread_mutexattr *attr) :
|
|||
type (PTHREAD_MUTEX_ERRORCHECK),
|
||||
pshared (PTHREAD_PROCESS_PRIVATE)
|
||||
{
|
||||
win32_obj_id = ::CreateSemaphore (&sec_none_nih, 0, LONG_MAX, NULL);
|
||||
win32_obj_id = ::CreateEvent (&sec_none_nih, false, false, NULL);
|
||||
if (!win32_obj_id)
|
||||
{
|
||||
magic = 0;
|
||||
|
@ -1592,8 +1585,9 @@ pthread_mutex::~pthread_mutex ()
|
|||
}
|
||||
|
||||
int
|
||||
pthread_mutex::_lock (pthread_t self)
|
||||
pthread_mutex::lock ()
|
||||
{
|
||||
pthread_t self = ::pthread_self ();
|
||||
int result = 0;
|
||||
|
||||
if (InterlockedIncrement ((long *)&lock_counter) == 1)
|
||||
|
@ -1616,8 +1610,31 @@ pthread_mutex::_lock (pthread_t self)
|
|||
}
|
||||
|
||||
int
|
||||
pthread_mutex::_trylock (pthread_t self)
|
||||
pthread_mutex::unlock ()
|
||||
{
|
||||
pthread_t self = ::pthread_self ();
|
||||
if (!pthread::equal (owner, self))
|
||||
return EPERM;
|
||||
|
||||
/* Don't try to unlock anything if recursion_counter == 0 initially.
|
||||
That means that we've forked. */
|
||||
if (recursion_counter > 0 && --recursion_counter == 0)
|
||||
{
|
||||
owner = NULL;
|
||||
#ifdef DEBUGGING
|
||||
tid = 0;
|
||||
#endif
|
||||
if (InterlockedDecrement ((long *) &lock_counter))
|
||||
::SetEvent (win32_obj_id); // Another thread may be waiting
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pthread_mutex::trylock ()
|
||||
{
|
||||
pthread_t self = ::pthread_self ();
|
||||
int result = 0;
|
||||
|
||||
if (InterlockedCompareExchange ((long *) &lock_counter, 1, 0) == 0)
|
||||
|
@ -1631,31 +1648,9 @@ pthread_mutex::_trylock (pthread_t self)
|
|||
}
|
||||
|
||||
int
|
||||
pthread_mutex::_unlock (pthread_t self)
|
||||
pthread_mutex::destroy ()
|
||||
{
|
||||
if (!pthread::equal (owner, self))
|
||||
return EPERM;
|
||||
|
||||
/* Don't try to unlock anything if recursion_counter == 0 initially.
|
||||
That means that we've forked. */
|
||||
if (recursion_counter > 0 && --recursion_counter == 0)
|
||||
{
|
||||
owner = NULL;
|
||||
#ifdef DEBUGGING
|
||||
tid = 0;
|
||||
#endif
|
||||
if (InterlockedDecrement ((long *) &lock_counter))
|
||||
// Another thread is waiting
|
||||
::ReleaseSemaphore (win32_obj_id, 1, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pthread_mutex::_destroy (pthread_t self)
|
||||
{
|
||||
if (condwaits || _trylock (self))
|
||||
if (condwaits || trylock ())
|
||||
// Do not destroy a condwaited or locked mutex
|
||||
return EBUSY;
|
||||
else if (recursion_counter > 1)
|
||||
|
@ -1683,7 +1678,7 @@ pthread_mutex::_fixup_after_fork ()
|
|||
#ifdef DEBUGGING
|
||||
tid = 0xffffffff; /* Don't know the tid after a fork */
|
||||
#endif
|
||||
win32_obj_id = ::CreateSemaphore (&sec_none_nih, 0, LONG_MAX, NULL);
|
||||
win32_obj_id = ::CreateEvent (&sec_none_nih, false, false, NULL);
|
||||
if (!win32_obj_id)
|
||||
api_fatal ("pthread_mutex::_fixup_after_fork () failed to recreate win32 semaphore for mutex");
|
||||
}
|
||||
|
@ -2665,40 +2660,40 @@ pthread_mutex::init (pthread_mutex_t *mutex,
|
|||
const pthread_mutexattr_t *attr,
|
||||
const pthread_mutex_t initializer)
|
||||
{
|
||||
pthread_mutex_t new_mutex;
|
||||
|
||||
if (attr && !pthread_mutexattr::is_good_object (attr))
|
||||
return EINVAL;
|
||||
|
||||
mutex_initialization_lock.lock ();
|
||||
|
||||
new_mutex = new pthread_mutex (attr ? (*attr) : NULL);
|
||||
if (!is_good_object (&new_mutex))
|
||||
if (pthread_mutex::is_good_initializer (mutex))
|
||||
{
|
||||
delete new_mutex;
|
||||
mutex_initialization_lock.unlock ();
|
||||
return EAGAIN;
|
||||
}
|
||||
pthread_mutex_t new_mutex = new pthread_mutex (attr ? (*attr) : NULL);
|
||||
if (!is_good_object (&new_mutex))
|
||||
{
|
||||
delete new_mutex;
|
||||
mutex_initialization_lock.unlock ();
|
||||
return EAGAIN;
|
||||
}
|
||||
|
||||
if (!attr && initializer)
|
||||
{
|
||||
if (initializer == PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
|
||||
new_mutex->type = PTHREAD_MUTEX_RECURSIVE;
|
||||
else if (initializer == PTHREAD_NORMAL_MUTEX_INITIALIZER_NP)
|
||||
new_mutex->type = PTHREAD_MUTEX_NORMAL;
|
||||
else if (initializer == PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP)
|
||||
new_mutex->type = PTHREAD_MUTEX_ERRORCHECK;
|
||||
}
|
||||
if (!attr && initializer)
|
||||
{
|
||||
if (initializer == PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
|
||||
new_mutex->type = PTHREAD_MUTEX_RECURSIVE;
|
||||
else if (initializer == PTHREAD_NORMAL_MUTEX_INITIALIZER_NP)
|
||||
new_mutex->type = PTHREAD_MUTEX_NORMAL;
|
||||
else if (initializer == PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP)
|
||||
new_mutex->type = PTHREAD_MUTEX_ERRORCHECK;
|
||||
}
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
{
|
||||
delete new_mutex;
|
||||
mutex_initialization_lock.unlock ();
|
||||
return EINVAL;
|
||||
}
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
{
|
||||
delete new_mutex;
|
||||
mutex_initialization_lock.unlock ();
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
*mutex = new_mutex;
|
||||
*mutex = new_mutex;
|
||||
}
|
||||
mutex_initialization_lock.unlock ();
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* thread.h: Locking and threading module definitions
|
||||
|
||||
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007,
|
||||
2008, 2009 Red Hat, Inc.
|
||||
2008, 2009, 2010 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -57,10 +57,10 @@ public:
|
|||
bool init ()
|
||||
{
|
||||
lock_counter = 0;
|
||||
win32_obj_id = ::CreateSemaphore (&sec_none_nih, 0, LONG_MAX, NULL);
|
||||
win32_obj_id = ::CreateEvent (&sec_none_nih, false, false, NULL);
|
||||
if (!win32_obj_id)
|
||||
{
|
||||
debug_printf ("CreateSemaphore failed. %E");
|
||||
debug_printf ("CreateEvent failed. %E");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -75,7 +75,7 @@ public:
|
|||
void unlock ()
|
||||
{
|
||||
if (InterlockedDecrement ((long *) &lock_counter))
|
||||
::ReleaseSemaphore (win32_obj_id, 1, NULL);
|
||||
::SetEvent (win32_obj_id);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -285,29 +285,10 @@ public:
|
|||
int type;
|
||||
int pshared;
|
||||
|
||||
pthread_t get_pthread_self () const
|
||||
{
|
||||
return PTHREAD_MUTEX_NORMAL == type ? MUTEX_OWNER_ANONYMOUS :
|
||||
::pthread_self ();
|
||||
}
|
||||
|
||||
int lock ()
|
||||
{
|
||||
return _lock (get_pthread_self ());
|
||||
}
|
||||
int trylock ()
|
||||
{
|
||||
return _trylock (get_pthread_self ());
|
||||
}
|
||||
int unlock ()
|
||||
{
|
||||
return _unlock (get_pthread_self ());
|
||||
}
|
||||
int destroy ()
|
||||
{
|
||||
return _destroy (get_pthread_self ());
|
||||
}
|
||||
|
||||
int lock ();
|
||||
int trylock ();
|
||||
int unlock ();
|
||||
int destroy ();
|
||||
void set_owner (pthread_t self)
|
||||
{
|
||||
recursion_counter = 1;
|
||||
|
@ -337,11 +318,6 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
int _lock (pthread_t self);
|
||||
int _trylock (pthread_t self);
|
||||
int _unlock (pthread_t self);
|
||||
int _destroy (pthread_t self);
|
||||
|
||||
void _fixup_after_fork ();
|
||||
|
||||
static List<pthread_mutex> mutexes;
|
||||
|
@ -446,7 +422,6 @@ private:
|
|||
void precreate (pthread_attr *);
|
||||
void postcreate ();
|
||||
bool create_cancel_event ();
|
||||
static pthread *get_tls_self_pointer ();
|
||||
static void set_tls_self_pointer (pthread *);
|
||||
void cancel_self ();
|
||||
DWORD get_thread_id ();
|
||||
|
|
Loading…
Reference in New Issue