Subject: Re: bug in pthread_mutex_init (cygwin-src-20010813)
From: Robert Collins <[email-masked]>
To: David Lum <[email-masked]>
Cc: [email-masked]
Date: 19 Aug 2001 14:13:45 +1000

On 18 Aug 2001 18:06:51 -0500, David Lum wrote:
> Hi.
> 
> I think there's a problem with pthread_mutex_init in Cygwin-- I looked
> at the source code (from 8/13/01) and it verified my suspicions.
> 
> The implementation of pthread_mutex_init in "winsup/cygwin/thread.cc"
> does this:
> 
> > int
> > __pthread_mutex_init (pthread_mutex_t *mutex,
> >                       const pthread_mutexattr_t *attr)
> > {
> >   if ((((pshared_mutex *)(mutex))->flags & SYS_BASE == SYS_BASE))
> >     // a pshared mutex
> >     return EBUSY;
> >   ...
> > }
> 
> This is bogus!  The pthread specification permits the passed-in mutex
> pointer to refer to completely uninitialized memory.  However, the
> first line of code here accesses a flag from that region of random
> memory.  If the bit happens to be zero, all is well.  But if it
> happens to be 1 then the call fails with EBUSY.

Good catch.
 
> It fails on the second call with the expected EBUSY return code.
> 
> I don't really have any suggestions on how to fix this, since it was
> probably caused by the introduction of "pshared" mutexes (which I do
> not understand).  But I'll bet someone on the list does.

pshared mutexs are mutex shared by several process's. In you have done
win32 programming compare critical  sections(single process only) with
win32 mutexs (multiple process's either by naming or handle passing).

Clean pshared mutexs requires a daemon process, something that is on the
wishlist. So for now its going to stay rather ugly :[. Variants of this
bug will affect pthread_cond_init as well.. and the fix will be similar
:]

Try this David... if it works please confirm via the mailing list and
I'll fixup the cond_init as well.

Index: thread.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/thread.cc,v
retrieving revision 1.42
diff -u -p -r1.42 thread.cc
--- thread.cc	2001/08/04 21:10:52	1.42
+++ thread.cc	2001/08/19 04:10:52
@@ -1848,8 +1848,14 @@ __pthread_mutex_init (pthread_mutex_t *m
 		      const pthread_mutexattr_t *attr)
 {
   if ((((pshared_mutex *)(mutex))->flags & SYS_BASE == SYS_BASE))
-    // a pshared mutex
-    return EBUSY;
+    {
+      // a pshared mutex or random data?
+      pshared_mutex *pmutex=(pshared_mutex *)(mutex);
+      if ((MT_INTERFACE->pshared_mutexs[pmutex->id]) != NULL)
+	return EBUSY;
+      // not a pshared mutex.
+      *mutex = NULL;
+    }
   if (attr && !verifyable_object_isvalid (*attr,
PTHREAD_MUTEXATTR_MAGIC))
     return EINVAL;

PS (referring to your private mail) I prefer all cygwin related matters
to be sent to the mailing list - there's no need to bring something up
publically and privately. This serves serveral purposes - Archival,
openness, mailbox organisation :].

Rob

> 
> 				       -Dave

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/