OSDN Git Service

* include/sys/strace.h: Define _STRACE_SPECIAL.
authorcgf <cgf>
Tue, 23 Feb 2010 05:36:03 +0000 (05:36 +0000)
committercgf <cgf>
Tue, 23 Feb 2010 05:36:03 +0000 (05:36 +0000)
(strace_printf_wrap): Fix NOSTRACE definitions.
(strace_printf_wrap1): Fix NOSTRACE definitions.
(special_printf): Define.
* thread.cc: Perform minor syntax fix in a comment.  Rename
"is_good_initialzer*" to "is_initializer*" throughout.  Use pthread_printf
rather than debug_printf throughout.  Add extra pthread_printf debugging
throughout.
(pthread_mutex::_new_mutex): New constant value.
(pthread_mutex::_unlocked_mutex): Ditto.
(pthread_mutex::_destroyed_mutex): Ditto.
(pthread_mutex::no_owner): Define new function.
(pthread_mutex::can_be_unlocked): Detect no_owner situation.  Handle
PTHREAD_MUTEX_NORMAL as a special case.
(pthread::create_cancel_event): Use C++ boolean values.
(pthread::precreate): Use method to set mutex type.
(pthread_cond::pthread_cond): Ditto.
(pthread_rwlock::pthread_rwlock): Ditto.
(pthread_mutex::pthread_mutex): Set owner to _new_mutex initially.
(pthread_mutex::~pthread_mutex): Reset various elements to make it clearer if
they are incorrectly reused.
(pthread_mutex::lock): Add clarifying comment.
(pthread_mutex::unlock): Attempt to handle various mutex types correctly.  In
particular, reinstate ability to have one thread unlock another thread's mutex
if type == PTHREAD_MUTEX_NORMAL.
(semaphore::_fixup_after_fork): Avoid redundancy.
(pthread_mutex::_fixup_after_fork): Ditto.  Fix debugging statement.
(__pthread_cond_dowait): Accommodate changes to remove previously inexplicable
use can_be_unblocked() as a static function.
* thread.h: Rename "is_good_initialzer*" to "is_initializer*" throughout.
(pthread_mutex): Reorganize.  Make many things private.
(pthread_mutex::no_owner): Define new method.
(pthread_mutex::_new_mutex): Define new constant.
(pthread_mutex::_unlocked_mutex): Ditto.
(pthread_mutex::_destroyed_mutex): Ditto.

winsup/cygwin/ChangeLog
winsup/cygwin/include/sys/strace.h
winsup/cygwin/thread.cc
winsup/cygwin/thread.h

index 2029c2a..8ccb684 100644 (file)
@@ -1,3 +1,43 @@
+2010-02-22  Christopher Faylor  <me+cygwin@cgf.cx>
+
+       * include/sys/strace.h: Define _STRACE_SPECIAL.
+       (strace_printf_wrap): Fix NOSTRACE definitions.
+       (strace_printf_wrap1): Fix NOSTRACE definitions.
+       (special_printf): Define.
+
+       * thread.cc: Perform minor syntax fix in a comment.  Rename
+       "is_good_initialzer*" to "is_initializer*" throughout.  Use
+       pthread_printf rather than debug_printf throughout.  Add extra
+       pthread_printf debugging throughout.
+       (pthread_mutex::_new_mutex): New constant value.
+       (pthread_mutex::_unlocked_mutex): Ditto.
+       (pthread_mutex::_destroyed_mutex): Ditto.
+       (pthread_mutex::no_owner): Define new function.
+       (pthread_mutex::can_be_unlocked): Detect no_owner situation.  Handle
+       PTHREAD_MUTEX_NORMAL as a special case.
+       (pthread::create_cancel_event): Use C++ boolean values.
+       (pthread::precreate): Use method to set mutex type.
+       (pthread_cond::pthread_cond): Ditto.
+       (pthread_rwlock::pthread_rwlock): Ditto.
+       (pthread_mutex::pthread_mutex): Set owner to _new_mutex initially.
+       (pthread_mutex::~pthread_mutex): Reset various elements to make it
+       clearer if they are incorrectly reused.
+       (pthread_mutex::lock): Add clarifying comment.
+       (pthread_mutex::unlock): Attempt to handle various mutex types
+       correctly.  In particular, reinstate ability to have one thread unlock
+       another thread's mutex if type == PTHREAD_MUTEX_NORMAL.
+       (semaphore::_fixup_after_fork): Avoid redundancy.
+       (pthread_mutex::_fixup_after_fork): Ditto.  Fix debugging statement.
+       (__pthread_cond_dowait): Accommodate changes to remove previously
+       inexplicable use can_be_unblocked() as a static function.
+       * thread.h: Rename "is_good_initialzer*" to "is_initializer*"
+       throughout.
+       (pthread_mutex): Reorganize.  Make many things private.
+       (pthread_mutex::no_owner): Define new method.
+       (pthread_mutex::_new_mutex): Define new constant.
+       (pthread_mutex::_unlocked_mutex): Ditto.
+       (pthread_mutex::_destroyed_mutex): Ditto.
+
 2010-02-22  Corinna Vinschen  <corinna@vinschen.de>
 
        * lc_era.h: Redefine lc_era_t to keep
index 5c18714..683cde0 100644 (file)
@@ -64,26 +64,27 @@ extern strace strace;
 
 /* Bitmasks of tracing messages to print.  */
 
-#define _STRACE_ALL     0x00001 // so behaviour of strace=1 is unchanged
-#define _STRACE_FLUSH   0x00002 // flush output buffer after every message
-#define _STRACE_INHERIT  0x00004 // children inherit mask from parent
-#define _STRACE_UHOH    0x00008 // unusual or weird phenomenon
-#define _STRACE_SYSCALL         0x00010 // system calls
-#define _STRACE_STARTUP         0x00020 // argc/envp printout at startup
-#define _STRACE_DEBUG    0x00040 // info to help debugging
-#define _STRACE_PARANOID 0x00080 // paranoid info
-#define _STRACE_TERMIOS         0x00100 // info for debugging termios stuff
-#define _STRACE_SELECT  0x00200 // info on ugly select internals
-#define _STRACE_WM      0x00400 // trace windows messages (enable _strace_wm)
-#define _STRACE_SIGP    0x00800 // trace signal and process handling
-#define _STRACE_MINIMAL         0x01000 // very minimal strace output
-#define _STRACE_PTHREAD         0x02000 // pthread calls
-#define _STRACE_EXITDUMP 0x04000 // dump strace cache on exit
-#define _STRACE_SYSTEM  0x08000 // cache strace messages
-#define _STRACE_NOMUTEX         0x10000 // don't use mutex for synchronization
-#define _STRACE_MALLOC  0x20000 // trace malloc calls
-#define _STRACE_THREAD  0x40000 // cygthread calls
-#define _STRACE_NOTALL  0x80000 // don't include if _STRACE_ALL
+#define _STRACE_ALL     0x000001 // so behaviour of strace=1 is unchanged
+#define _STRACE_FLUSH   0x000002 // flush output buffer after every message
+#define _STRACE_INHERIT  0x000004 // children inherit mask from parent
+#define _STRACE_UHOH    0x000008 // unusual or weird phenomenon
+#define _STRACE_SYSCALL         0x000010 // system calls
+#define _STRACE_STARTUP         0x000020 // argc/envp printout at startup
+#define _STRACE_DEBUG    0x000040 // info to help debugging
+#define _STRACE_PARANOID 0x000080 // paranoid info
+#define _STRACE_TERMIOS         0x000100 // info for debugging termios stuff
+#define _STRACE_SELECT  0x000200 // info on ugly select internals
+#define _STRACE_WM      0x000400 // trace windows messages (enable _strace_wm)
+#define _STRACE_SIGP    0x000800 // trace signal and process handling
+#define _STRACE_MINIMAL         0x001000 // very minimal strace output
+#define _STRACE_PTHREAD         0x002000 // pthread calls
+#define _STRACE_EXITDUMP 0x004000 // dump strace cache on exit
+#define _STRACE_SYSTEM  0x008000 // cache strace messages
+#define _STRACE_NOMUTEX         0x010000 // don't use mutex for synchronization
+#define _STRACE_MALLOC  0x020000 // trace malloc calls
+#define _STRACE_THREAD  0x040000 // cygthread calls
+#define _STRACE_NOTALL  0x080000 // don't include if _STRACE_ALL
+#define _STRACE_SPECIAL         0x100000 // special case, only for debugging - do not check in
 
 #ifdef __cplusplus
 extern "C" {
@@ -99,8 +100,8 @@ void strace_printf (unsigned, const char *func, const char *, ...);
 #ifdef __cplusplus
 
 #ifdef NOSTRACE
-#define define_strace(c, f)
-#define define_strace1(c, f)
+#define strace_printf_wrap(what, fmt, args...)
+#define strace_printf_wrap1(what, fmt, args...)
 #else
 #define strace_printf_wrap(what, fmt, args...) \
    ((void) ({\
@@ -114,6 +115,7 @@ void strace_printf (unsigned, const char *func, const char *, ...);
          strace.prntf((_STRACE_ ## what) | _STRACE_NOTALL, __PRETTY_FUNCTION__, fmt, ## args); \
        0; \
     }))
+#endif /*NOSTRACE*/
 
 #define debug_printf(fmt, args...) strace_printf_wrap(DEBUG, fmt , ## args)
 #define malloc_printf(fmt, args...) strace_printf_wrap1(MALLOC, fmt , ## args)
@@ -126,7 +128,7 @@ void strace_printf (unsigned, const char *func, const char *, ...);
 #define system_printf(fmt, args...) strace_printf_wrap(SYSTEM, fmt , ## args)
 #define termios_printf(fmt, args...) strace_printf_wrap(TERMIOS, fmt , ## args)
 #define thread_printf(fmt, args...) strace_printf_wrap1(THREAD, fmt , ## args)
+#define special_printf(fmt, args...) strace_printf_wrap1(SPECIAL, fmt , ## args)
 #define wm_printf(fmt, args...) strace_printf_wrap(WM, fmt , ## args)
-#endif /*NOSTRACE*/
 #endif /* __cplusplus */
 #endif /* _SYS_STRACE_H */
index 53a4f8c..0a44d69 100644 (file)
@@ -16,7 +16,7 @@ details. */
    the constraints we either pretend to be conformant, or return an error
    code.
 
-   Some caveats: PROCESS_SHARED objects while they pretend to be process
+   Some caveats: PROCESS_SHARED objects, while they pretend to be process
    shared, may not actually work.  Some test cases are needed to determine
    win32's behaviour.  My suspicion is that the win32 handle needs to be
    opened with different flags for proper operation.
@@ -48,6 +48,31 @@ static inline verifyable_object_state
 
 extern int threadsafe;
 
+const pthread_t pthread_mutex::_new_mutex = (pthread_t) 1;
+const pthread_t pthread_mutex::_unlocked_mutex = (pthread_t) 2;
+const pthread_t pthread_mutex::_destroyed_mutex = (pthread_t) 3;
+
+inline bool
+pthread_mutex::no_owner()
+{
+    int res;
+    if (!owner)
+      {
+       debug_printf ("NULL owner value");
+       res = 1;
+      }
+    else if (owner == _destroyed_mutex)
+      {
+       paranoid_printf ("attempt to use destroyed mutex");
+       res = 1;
+      }
+    else if (owner == _new_mutex || owner == _unlocked_mutex)
+      res = 1;
+    else
+      res = 0;
+    return res;
+}
+
 #undef __getreent
 extern "C" struct _reent *
 __getreent ()
@@ -157,7 +182,7 @@ pthread_mutex::is_good_object (pthread_mutex_t const *mutex)
 }
 
 inline bool
-pthread_mutex::is_good_initializer (pthread_mutex_t const *mutex)
+pthread_mutex::is_initializer (pthread_mutex_t const *mutex)
 {
   if (verifyable_object_isvalid (mutex, PTHREAD_MUTEX_MAGIC,
                                 PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP,
@@ -168,7 +193,7 @@ pthread_mutex::is_good_initializer (pthread_mutex_t const *mutex)
 }
 
 inline bool
-pthread_mutex::is_good_initializer_or_object (pthread_mutex_t const *mutex)
+pthread_mutex::is_initializer_or_object (pthread_mutex_t const *mutex)
 {
   if (verifyable_object_isvalid (mutex, PTHREAD_MUTEX_MAGIC,
                                 PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP,
@@ -178,17 +203,17 @@ pthread_mutex::is_good_initializer_or_object (pthread_mutex_t const *mutex)
   return true;
 }
 
+/* FIXME: Accommodate PTHREAD_MUTEX_ERRORCHECK */
 inline bool
-pthread_mutex::can_be_unlocked (pthread_mutex_t const *mutex)
+pthread_mutex::can_be_unlocked ()
 {
   pthread_t self = pthread::self ();
-
-  if (!is_good_object (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
-        && pthread::equal ((*mutex)->owner, self);
+  bool res = type == PTHREAD_MUTEX_NORMAL || no_owner ()
+            || (recursion_counter == 1 && pthread::equal (owner, self));
+  pthread_printf ("recursion_counter %d res %d", recursion_counter, res);
+  return res;
 }
 
 inline bool
@@ -217,7 +242,7 @@ pthread_cond::is_good_object (pthread_cond_t const *cond)
 }
 
 inline bool
-pthread_cond::is_good_initializer (pthread_cond_t const *cond)
+pthread_cond::is_initializer (pthread_cond_t const *cond)
 {
   if (verifyable_object_isvalid (cond, PTHREAD_COND_MAGIC, PTHREAD_COND_INITIALIZER) != VALID_STATIC_OBJECT)
     return false;
@@ -225,7 +250,7 @@ pthread_cond::is_good_initializer (pthread_cond_t const *cond)
 }
 
 inline bool
-pthread_cond::is_good_initializer_or_object (pthread_cond_t const *cond)
+pthread_cond::is_initializer_or_object (pthread_cond_t const *cond)
 {
   if (verifyable_object_isvalid (cond, PTHREAD_COND_MAGIC, PTHREAD_COND_INITIALIZER) == INVALID_OBJECT)
     return false;
@@ -242,7 +267,7 @@ pthread_rwlock::is_good_object (pthread_rwlock_t const *rwlock)
 }
 
 inline bool
-pthread_rwlock::is_good_initializer (pthread_rwlock_t const *rwlock)
+pthread_rwlock::is_initializer (pthread_rwlock_t const *rwlock)
 {
   if (verifyable_object_isvalid (rwlock, PTHREAD_RWLOCK_MAGIC, PTHREAD_RWLOCK_INITIALIZER) != VALID_STATIC_OBJECT)
     return false;
@@ -250,7 +275,7 @@ pthread_rwlock::is_good_initializer (pthread_rwlock_t const *rwlock)
 }
 
 inline bool
-pthread_rwlock::is_good_initializer_or_object (pthread_rwlock_t const *rwlock)
+pthread_rwlock::is_initializer_or_object (pthread_rwlock_t const *rwlock)
 {
   if (verifyable_object_isvalid (rwlock, PTHREAD_RWLOCK_MAGIC, PTHREAD_RWLOCK_INITIALIZER) == INVALID_OBJECT)
     return false;
@@ -367,7 +392,7 @@ pthread::~pthread ()
 bool
 pthread::create_cancel_event ()
 {
-  cancel_event = ::CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
+  cancel_event = ::CreateEvent (&sec_none_nih, true, false, NULL);
   if (!cancel_event)
     {
       system_printf ("couldn't create cancel event, %E");
@@ -402,7 +427,7 @@ pthread::precreate (pthread_attr *newattr)
       return;
     }
   /* Change the mutex type to NORMAL to speed up mutex operations */
-  mutex.type = PTHREAD_MUTEX_NORMAL;
+  mutex.set_type (PTHREAD_MUTEX_NORMAL);
   if (!create_cancel_event ())
     magic = 0;
 }
@@ -957,7 +982,7 @@ pthread_cond::pthread_cond (pthread_condattr *attr) :
    * Change the mutex type to NORMAL.
    * This mutex MUST be of type normal
   */
-  mtx_in.type = PTHREAD_MUTEX_NORMAL;
+  mtx_in.set_type (PTHREAD_MUTEX_NORMAL);
 
   verifyable_mutex_obj = &mtx_out;
   if (!pthread_mutex::is_good_object (&verifyable_mutex_obj))
@@ -967,12 +992,12 @@ pthread_cond::pthread_cond (pthread_condattr *attr) :
       return;
     }
   /* Change the mutex type to NORMAL to speed up mutex operations */
-  mtx_out.type = PTHREAD_MUTEX_NORMAL;
+  mtx_out.set_type (PTHREAD_MUTEX_NORMAL);
 
   sem_wait = ::CreateSemaphore (&sec_none_nih, 0, LONG_MAX, NULL);
   if (!sem_wait)
     {
-      debug_printf ("CreateSemaphore failed. %E");
+      pthread_printf ("CreateSemaphore failed. %E");
       magic = 0;
       return;
     }
@@ -1171,7 +1196,7 @@ pthread_rwlock::pthread_rwlock (pthread_rwlockattr *attr) :
       return;
     }
   /* Change the mutex type to NORMAL to speed up mutex operations */
-  mtx.type = PTHREAD_MUTEX_NORMAL;
+  mtx.set_type (PTHREAD_MUTEX_NORMAL);
 
   verifyable_cond_obj = &cond_readers;
   if (!pthread_cond::is_good_object (&verifyable_cond_obj))
@@ -1523,7 +1548,7 @@ pthread_mutex::pthread_mutex (pthread_mutexattr *attr) :
   verifyable_object (0),       /* set magic to zero initially */
   lock_counter (0),
   win32_obj_id (NULL), recursion_counter (0),
-  condwaits (0), owner (NULL),
+  condwaits (0), owner (_new_mutex),
 #ifdef DEBUGGING
   tid (0),
 #endif
@@ -1548,9 +1573,14 @@ pthread_mutex::pthread_mutex (pthread_mutexattr *attr) :
 pthread_mutex::~pthread_mutex ()
 {
   if (win32_obj_id)
-    CloseHandle (win32_obj_id);
+    {
+      CloseHandle (win32_obj_id);
+      win32_obj_id = NULL;
+    }
 
   mutexes.remove (this);
+  owner = _destroyed_mutex;
+  magic = 0;
 }
 
 int
@@ -1559,9 +1589,10 @@ pthread_mutex::lock ()
   pthread_t self = ::pthread_self ();
   int result = 0;
 
-  if (InterlockedIncrement ((long *)&lock_counter) == 1)
+  if (InterlockedIncrement ((long *) &lock_counter) == 1)
     set_owner (self);
-  else if (type == PTHREAD_MUTEX_NORMAL || !pthread::equal (owner, self))
+  else if (type == PTHREAD_MUTEX_NORMAL /* potentially causes deadlock */
+          || !pthread::equal (owner, self))
     {
       cancelable_wait (win32_obj_id, INFINITE, cw_no_cancel, cw_sig_resume);
       set_owner (self);
@@ -1575,29 +1606,38 @@ pthread_mutex::lock ()
        result = EDEADLK;
     }
 
+  pthread_printf ("mutex %p, self %p, owner %p, lock_counter %d, recursion_counter %d",
+                 this, self, owner, lock_counter, recursion_counter);
   return result;
 }
 
 int
 pthread_mutex::unlock ()
 {
+  int res;
   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 (type == PTHREAD_MUTEX_NORMAL)
+    /* no error checking */;
+  else if (no_owner ())
+    return type == PTHREAD_MUTEX_ERRORCHECK ? EINVAL : 0;
+  else if (!pthread::equal (owner, self))
+    res = EPERM;
   if (recursion_counter > 0 && --recursion_counter == 0)
+    /* Don't try to unlock anything if recursion_counter == 0.
+       This means the mutex was never locked or that we've forked. */
     {
-      owner = NULL;
+      owner = (pthread_t) _unlocked_mutex;
 #ifdef DEBUGGING
       tid = 0;
 #endif
       if (InterlockedDecrement ((long *) &lock_counter))
        ::SetEvent (win32_obj_id); // Another thread is waiting
+      res = 0;
     }
 
-  return 0;
+  pthread_printf ("mutex %p, owner %p, self %p, lock_counter %d, recursion_counter %d, res %d",
+                 this, owner, self, lock_counter, recursion_counter, res);
+  return res;
 }
 
 int
@@ -1636,7 +1676,7 @@ pthread_mutex::destroy ()
 void
 pthread_mutex::_fixup_after_fork ()
 {
-  debug_printf ("mutex %p in _fixup_after_fork", this);
+  pthread_printf ("mutex %p", this);
   if (pshared != PTHREAD_PROCESS_PRIVATE)
     api_fatal ("pthread_mutex::_fixup_after_fork () doesn't understand PROCESS_SHARED mutex's");
 
@@ -1649,7 +1689,7 @@ pthread_mutex::_fixup_after_fork ()
 #endif
   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");
+    api_fatal ("pthread_mutex::_fixup_after_fork () failed to recreate win32 event for mutex");
 }
 
 pthread_mutexattr::pthread_mutexattr ():verifyable_object (PTHREAD_MUTEXATTR_MAGIC),
@@ -2222,7 +2262,7 @@ pthread_getspecific (pthread_key_t key)
 extern "C" int
 pthread_cond_destroy (pthread_cond_t *cond)
 {
-  if (pthread_cond::is_good_initializer (cond))
+  if (pthread_cond::is_initializer (cond))
     return 0;
   if (!pthread_cond::is_good_object (cond))
     return EINVAL;
@@ -2272,7 +2312,7 @@ pthread_cond::init (pthread_cond_t *cond, const pthread_condattr_t *attr)
 extern "C" int
 pthread_cond_broadcast (pthread_cond_t *cond)
 {
-  if (pthread_cond::is_good_initializer (cond))
+  if (pthread_cond::is_initializer (cond))
     return 0;
   if (!pthread_cond::is_good_object (cond))
     return EINVAL;
@@ -2285,7 +2325,7 @@ pthread_cond_broadcast (pthread_cond_t *cond)
 extern "C" int
 pthread_cond_signal (pthread_cond_t *cond)
 {
-  if (pthread_cond::is_good_initializer (cond))
+  if (pthread_cond::is_initializer (cond))
     return 0;
   if (!pthread_cond::is_good_object (cond))
     return EINVAL;
@@ -2301,10 +2341,10 @@ __pthread_cond_dowait (pthread_cond_t *cond, pthread_mutex_t *mutex,
 {
   if (!pthread_mutex::is_good_object (mutex))
     return EINVAL;
-  if (!pthread_mutex::can_be_unlocked (mutex))
+  if (!(*mutex)->can_be_unlocked ())
     return EPERM;
 
-  if (pthread_cond::is_good_initializer (cond))
+  if (pthread_cond::is_initializer (cond))
     pthread_cond::init (cond, NULL);
   if (!pthread_cond::is_good_object (cond))
     return EINVAL;
@@ -2405,7 +2445,7 @@ pthread_condattr_destroy (pthread_condattr_t *condattr)
 extern "C" int
 pthread_rwlock_destroy (pthread_rwlock_t *rwlock)
 {
-  if (pthread_rwlock::is_good_initializer (rwlock))
+  if (pthread_rwlock::is_initializer (rwlock))
     return 0;
   if (!pthread_rwlock::is_good_object (rwlock))
     return EINVAL;
@@ -2457,7 +2497,7 @@ pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
 {
   pthread_testcancel ();
 
-  if (pthread_rwlock::is_good_initializer (rwlock))
+  if (pthread_rwlock::is_initializer (rwlock))
     pthread_rwlock::init (rwlock, NULL);
   if (!pthread_rwlock::is_good_object (rwlock))
     return EINVAL;
@@ -2468,7 +2508,7 @@ pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
 extern "C" int
 pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
 {
-  if (pthread_rwlock::is_good_initializer (rwlock))
+  if (pthread_rwlock::is_initializer (rwlock))
     pthread_rwlock::init (rwlock, NULL);
   if (!pthread_rwlock::is_good_object (rwlock))
     return EINVAL;
@@ -2481,7 +2521,7 @@ pthread_rwlock_wrlock (pthread_rwlock_t *rwlock)
 {
   pthread_testcancel ();
 
-  if (pthread_rwlock::is_good_initializer (rwlock))
+  if (pthread_rwlock::is_initializer (rwlock))
     pthread_rwlock::init (rwlock, NULL);
   if (!pthread_rwlock::is_good_object (rwlock))
     return EINVAL;
@@ -2492,7 +2532,7 @@ pthread_rwlock_wrlock (pthread_rwlock_t *rwlock)
 extern "C" int
 pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock)
 {
-  if (pthread_rwlock::is_good_initializer (rwlock))
+  if (pthread_rwlock::is_initializer (rwlock))
     pthread_rwlock::init (rwlock, NULL);
   if (!pthread_rwlock::is_good_object (rwlock))
     return EINVAL;
@@ -2503,7 +2543,7 @@ pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock)
 extern "C" int
 pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
 {
-  if (pthread_rwlock::is_good_initializer (rwlock))
+  if (pthread_rwlock::is_initializer (rwlock))
     return 0;
   if (!pthread_rwlock::is_good_object (rwlock))
     return EINVAL;
@@ -2623,7 +2663,7 @@ pthread_mutex::init (pthread_mutex_t *mutex,
     return EINVAL;
 
   mutex_initialization_lock.lock ();
-  if (initializer == NULL || pthread_mutex::is_good_initializer (mutex))
+  if (initializer == NULL || pthread_mutex::is_initializer (mutex))
     {
       pthread_mutex_t new_mutex = new pthread_mutex (attr ? (*attr) : NULL);
       if (!is_good_object (&new_mutex))
@@ -2654,6 +2694,7 @@ pthread_mutex::init (pthread_mutex_t *mutex,
       *mutex = new_mutex;
     }
   mutex_initialization_lock.unlock ();
+  pthread_printf ("*mutex %p, attr %p, initializer %p", *mutex, attr, initializer);
 
   return 0;
 }
@@ -2675,7 +2716,7 @@ pthread_mutex_getprioceiling (const pthread_mutex_t *mutex,
 extern "C" int
 pthread_mutex_lock (pthread_mutex_t *mutex)
 {
-  if (pthread_mutex::is_good_initializer (mutex))
+  if (pthread_mutex::is_initializer (mutex))
     pthread_mutex::init (mutex, NULL, *mutex);
   if (!pthread_mutex::is_good_object (mutex))
     return EINVAL;
@@ -2685,7 +2726,7 @@ pthread_mutex_lock (pthread_mutex_t *mutex)
 extern "C" int
 pthread_mutex_trylock (pthread_mutex_t *mutex)
 {
-  if (pthread_mutex::is_good_initializer (mutex))
+  if (pthread_mutex::is_initializer (mutex))
     pthread_mutex::init (mutex, NULL, *mutex);
   if (!pthread_mutex::is_good_object (mutex))
     return EINVAL;
@@ -2695,7 +2736,7 @@ pthread_mutex_trylock (pthread_mutex_t *mutex)
 extern "C" int
 pthread_mutex_unlock (pthread_mutex_t *mutex)
 {
-  if (pthread_mutex::is_good_initializer (mutex))
+  if (pthread_mutex::is_initializer (mutex))
     return EPERM;
   if (!pthread_mutex::is_good_object (mutex))
     return EINVAL;
@@ -2707,7 +2748,7 @@ pthread_mutex_destroy (pthread_mutex_t *mutex)
 {
   int rv;
 
-  if (pthread_mutex::is_good_initializer (mutex))
+  if (pthread_mutex::is_initializer (mutex))
     return 0;
   if (!pthread_mutex::is_good_object (mutex))
     return EINVAL;
@@ -2980,7 +3021,7 @@ semaphore::_timedwait (const struct timespec *abstime)
       set_errno (ETIMEDOUT);
       return -1;
     default:
-      debug_printf ("cancelable_wait failed. %E");
+      pthread_printf ("cancelable_wait failed. %E");
       __seterrno ();
       return -1;
     }
@@ -2999,7 +3040,7 @@ semaphore::_wait ()
       set_errno (EINTR);
       return -1;
     default:
-      debug_printf ("cancelable_wait failed. %E");
+      pthread_printf ("cancelable_wait failed. %E");
       break;
     }
   return 0;
@@ -3010,7 +3051,7 @@ semaphore::_fixup_after_fork ()
 {
   if (shared == PTHREAD_PROCESS_PRIVATE)
     {
-      debug_printf ("sem %x in _fixup_after_fork", this);
+      pthread_printf ("sem %x", this);
       /* FIXME: duplicate code here and in the constructor. */
       this->win32_obj_id = ::CreateSemaphore (&sec_none_nih, currentvalue,
                                              LONG_MAX, NULL);
index 17f3b59..62bd1b9 100644 (file)
@@ -267,52 +267,35 @@ public:
 class pthread_mutex: public verifyable_object
 {
 public:
-  static bool is_good_object (pthread_mutex_t const *);
-  static bool is_good_initializer (pthread_mutex_t const *);
-  static bool is_good_initializer_or_object (pthread_mutex_t const *);
-  static bool is_good_initializer_or_bad_object (pthread_mutex_t const *);
-  static bool can_be_unlocked (pthread_mutex_t const *);
   static void init_mutex ();
   static int init (pthread_mutex_t *, const pthread_mutexattr_t *attr,
                   const pthread_mutex_t);
-
-  unsigned long lock_counter;
-  HANDLE win32_obj_id;
-  unsigned int recursion_counter;
-  LONG condwaits;
-  pthread_t owner;
-#ifdef DEBUGGING
-  DWORD tid;           /* the thread id of the owner */
-#endif
-  int type;
-  int pshared;
+  static bool is_good_object (pthread_mutex_t const *);
+  static bool is_initializer (pthread_mutex_t const *);
+  static bool is_initializer_or_object (pthread_mutex_t const *);
+  static bool is_initializer_or_bad_object (pthread_mutex_t const *);
 
   int lock ();
   int trylock ();
   int unlock ();
   int destroy ();
-  void set_owner (pthread_t self)
-  {
-    recursion_counter = 1;
-    owner = self;
-#ifdef DEBUGGING
-    tid = GetCurrentThreadId ();
-#endif
-  }
+  void set_type (int in_type) {type = in_type;}
 
   int lock_recursive ()
   {
-    if (UINT_MAX == recursion_counter)
+    if (recursion_counter == UINT_MAX)
       return EAGAIN;
-    ++recursion_counter;
+    recursion_counter++;
     return 0;
   }
 
+  bool can_be_unlocked ();
+
   pthread_mutex (pthread_mutexattr * = NULL);
   pthread_mutex (pthread_mutex_t *, pthread_mutexattr *);
   ~pthread_mutex ();
 
-  class pthread_mutex * next;
+  class pthread_mutex *next;
   static void fixup_after_fork ()
   {
     mutexes.fixup_after_fork ();
@@ -320,10 +303,35 @@ public:
   }
 
 private:
+  unsigned long lock_counter;
+  HANDLE win32_obj_id;
+  unsigned int recursion_counter;
+  LONG condwaits;
+  pthread_t owner;
+#ifdef DEBUGGING
+  DWORD tid;           /* the thread id of the owner */
+#endif
+  int type;
+  int pshared;
+
+  void set_owner (pthread_t self)
+  {
+    recursion_counter = 1;
+    owner = self;
+#ifdef DEBUGGING
+    tid = GetCurrentThreadId ();
+#endif
+  }
+  static const pthread_t _new_mutex;
+  static const pthread_t _unlocked_mutex;
+  static const pthread_t _destroyed_mutex;
+
+  bool no_owner ();
   void _fixup_after_fork ();
 
   static List<pthread_mutex> mutexes;
   static fast_mutex mutex_initialization_lock;
+  friend class pthread_cond;
 };
 
 #define WAIT_CANCELED   (WAIT_OBJECT_0 + 1)
@@ -467,9 +475,9 @@ class pthread_cond: public verifyable_object
 {
 public:
   static bool is_good_object (pthread_cond_t const *);
-  static bool is_good_initializer (pthread_cond_t const *);
-  static bool is_good_initializer_or_object (pthread_cond_t const *);
-  static bool is_good_initializer_or_bad_object (pthread_cond_t const *);
+  static bool is_initializer (pthread_cond_t const *);
+  static bool is_initializer_or_object (pthread_cond_t const *);
+  static bool is_initializer_or_bad_object (pthread_cond_t const *);
   static void init_mutex ();
   static int init (pthread_cond_t *, const pthread_condattr_t *);
 
@@ -518,9 +526,9 @@ class pthread_rwlock: public verifyable_object
 {
 public:
   static bool is_good_object (pthread_rwlock_t const *);
-  static bool is_good_initializer (pthread_rwlock_t const *);
-  static bool is_good_initializer_or_object (pthread_rwlock_t const *);
-  static bool is_good_initializer_or_bad_object (pthread_rwlock_t const *);
+  static bool is_initializer (pthread_rwlock_t const *);
+  static bool is_initializer_or_object (pthread_rwlock_t const *);
+  static bool is_initializer_or_bad_object (pthread_rwlock_t const *);
   static void init_mutex ();
   static int init (pthread_rwlock_t *, const pthread_rwlockattr_t *);