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 pthread_join. 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 (); +restart_on_signal: 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 break; + case WAIT_SIGNALED: + debug_printf ("Signal received, restart"); + goto restart_on_signal; default: // should never happen return EINVAL; Corinna (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
pgpY80Ypfnu1H.pgp
Description: PGP signature