X-Recipient: archive-cygwin AT delorie DOT com DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:from:to:subject:message-id:in-reply-to :references:mime-version:content-type; q=dns; s=default; b=M7N9e 6+cmk3Jrq5BV7c8BLNZYtlo7Nv9V57GLnFDTOvNiea8vmgYM9C4InLlVsOiK5gV+ z/qHyB8sUBHhCZJLknUklu7I0wHqPannJmU+6h+9oIzcRnIyMBWX+mBHoe8RD917 YtlenBhiLVgNaNu01+fXOfZewYmsy2qe1UO0z0= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:from:to:subject:message-id:in-reply-to :references:mime-version:content-type; s=default; bh=0q9fhltjjhs mWBabHGredbGscQ4=; b=sQTQNKjdgn5EpQUmCkbt+EQu5u8gW1EzR1yqc6mGxOi 8Gm8W/KTIRp5bw5hOXPfOt8PtwaYAnwkU+ytoIhF99dI0deqE+73sc1SRKz4mAHi +rvwsLcTkl+EyflpoG5gA51Nz9SKJW43hUEsSAv8OXuSzKSfQ88dryERPCbBX3vg = Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.4 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 X-HELO: mailscanner02.zoner.fi Date: Tue, 24 Feb 2015 15:54:58 +0200 From: Lasse Collin To: cygwin AT cygwin DOT com Subject: Re: Unexpected EINVAL from pthread_join Message-ID: <20150224155458.33ff024a@tukaani.org> In-Reply-To: <20150223140317.GP437@calimero.vinschen.de> References: <20150222225437 DOT 271e929b AT tukaani DOT org> <20150223121445 DOT GL437 AT calimero DOT vinschen DOT de> <20150223125914 DOT GO437 AT calimero DOT vinschen DOT de> <20150223140317 DOT GP437 AT calimero DOT vinschen DOT de> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="MP_/3D_xoh+NL.NtFTWsOHeJHSy" X-Antivirus-Scanner: Clean mail though you should still use an Antivirus Received-SPF: none X-IsSubscribed: yes --MP_/3D_xoh+NL.NtFTWsOHeJHSy Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Content-Disposition: inline On 2015-02-23 Corinna Vinschen wrote: > On second thought, this is not the right way to handle this. The > WAIT_SIGNALED is returned because we're in the main thread and > SA_RESTART is not set, as you assumed above. This leads to the > question why this scenario isn't handled directly in cygwait. > > So what I did now is to apply the below patch to CVS. It adds a flag > cw_sig_restart to cygwait, which also restarts in the main thread if > SA_RESTART is not set, as it's supposed to be for pthread_join. > > I uploaded a new developer snapshot to https://cygwin.com/snapshots/ > Can you please test if it works as desired? The snapshot 20150223 works. (The earlier patch worked too.) Thank you. Many other pthread functions are similar in sense that they must never return EINTR. A bug similar to the one in pthread::join exist in pthread_mutex::lock. If SA_RESTART isn't used, signals can make multiple threads get a lock on the same mutex at the same time. A test program is attached. Adding cw_sig_restart to the cygwait call in pthread_mutex::lock fixes this. -- Lasse Collin | IRC: Larhzu @ IRCnet & Freenode --MP_/3D_xoh+NL.NtFTWsOHeJHSy Content-Type: text/x-c++src Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=mutex-test.c // gcc -std=gnu99 -Wall -Wextra -o mutex-test mutex-test.c #include #include #include #include #define dbg(expr) printf("%s = %d\n", #expr, expr) static pthread_mutex_t mutex; static void sighandler(int sig) { static const char msg[] = "Signal handler\n"; write(STDOUT_FILENO, msg, sizeof(msg) - 1); return; } static void * thr(void *ptr) { printf("Thread started\n"); dbg(pthread_mutex_lock(&mutex)); sleep(5); printf("Thread exiting\n"); return NULL; } extern int main(void) { // Setup a signal handler for SIGALRM. All signals will be // blocked while the signal handler executes. SA_RESTART // isn't used. sigset_t all; dbg(sigfillset(&all)); struct sigaction act = { .sa_handler = &sighandler, .sa_mask = all, .sa_flags = 0, }; dbg(sigaction(SIGALRM, &act, NULL)); // Initialize the mutex. dbg(pthread_mutex_init(&mutex, NULL)); // Create a new thread with all signals blocked. // This ensure that SIGALRM is sent to the main thread. pthread_t thread; sigset_t oldmask; dbg(pthread_sigmask(SIG_SETMASK, &all, &oldmask)); dbg(pthread_create(&thread, NULL, &thr, NULL)); dbg(pthread_sigmask(SIG_SETMASK, &oldmask, NULL)); // Sleep to give the other thread time to lock the mutex. // Then locking the mutex in this thread will block. // SIGALRM should have no effect on pthread_mutex_lock() // and the program should deadlock here. This doesn't // happen if SA_RESTART isn't used and both threads appear // to get the lock. sleep(1); dbg(alarm(1)); dbg(pthread_mutex_lock(&mutex)); dbg(pthread_mutex_unlock(&mutex)); sleep(5); return 0; } --MP_/3D_xoh+NL.NtFTWsOHeJHSy Content-Type: text/plain; charset=us-ascii -- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple --MP_/3D_xoh+NL.NtFTWsOHeJHSy--