Unexpected EINVAL from pthread_join

Corinna Vinschen corinna-cygwin@cygwin.com
Mon Feb 23 15:05:00 GMT 2015

On Feb 23 13:14, Corinna Vinschen wrote:
> On Feb 22 22:54, Lasse Collin wrote:
> > It seems that a signal can cause pthread_join to incorrectly return
> > EINVAL. I debugged it only a little but hopefully someone finds this
> > useful:
> > 
> > In the file thread.cc, function pthread::join, the call to cygwait may
> > return WAIT_SIGNALED if a signal is sent to the process. The switch
> > statement handling the return value assumes that only WAIT_OBJECT_0 and
> > WAIT_CANCELED are possible. The default section of the switch statement
> > has a comment "should never happen" and it returns EINVAL. It might be
> > that the problem occurs only when SA_RESTART isn't used.
> Lasse, I'm sorry, but I can't handle that quickly.  Since you're
> looking into the code and apparently understanding it, maybe you'd
> like to provide patches, too?  Please have a look at
> https://cygwin.com/contrib.html.  Patches <= 10 lines don't even
> need a copyright assignment.

Having said that...

I looked into the Linux man page for pthread_join(1).  It doesn't mention
signals and EINTR at all.  Then I looked into the SUSv4 pages(2) and it
only has this to say:

  The pthread_join() function shall not return an error code of [EINTR].

Searching further on this I found this(3):

  The wait in pthread_join is not broken by a signal. If a thread
  waiting in pthread_join receives a signal that is not masked, if will
  execute the signal handler, and then return to waiting in

Taking that at face value, the following patch should do the right
thing, doesn't it?

Index: thread.cc
RCS file: /cvs/src/src/winsup/cygwin/thread.cc,v
retrieving revision 1.296
diff -u -p -r1.296 thread.cc
--- thread.cc	28 Nov 2014 20:46:13 -0000	1.296
+++ thread.cc	23 Feb 2015 12:58:59 -0000
@@ -2399,6 +2399,7 @@ pthread::join (pthread_t *thread, void *
       (*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
       (*thread)->mutex.unlock ();
       switch (cygwait ((*thread)->win32_obj_id, cw_infinite, cw_sig | cw_cancel))
 	case WAIT_OBJECT_0:
@@ -2413,6 +2414,9 @@ pthread::join (pthread_t *thread, void *
 	  joiner->cancel_self ();
 	  // never reached
+	  debug_printf ("Signal received, restart");
+	  goto restart_on_signal;
 	  // should never happen
 	  return EINVAL;


(1) http://linux.die.net/man/3/pthread_join
(2) http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_join.html
(3) http://osr600doc.sco.com/man/html.PTHREAD/pthread_join.PTHREAD.html

Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://cygwin.com/pipermail/cygwin/attachments/20150223/50d4c7b7/attachment.sig>

More information about the Cygwin mailing list