From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mout.kundenserver.de (mout.kundenserver.de [212.227.126.187]) by sourceware.org (Postfix) with ESMTPS id C37A63844079 for ; Fri, 3 Jul 2020 19:22:27 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org C37A63844079 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=cygwin.com Authentication-Results: sourceware.org; spf=fail smtp.mailfrom=corinna-cygwin@cygwin.com Received: from calimero.vinschen.de ([217.91.18.234]) by mrelayeu.kundenserver.de (mreue011 [212.227.15.167]) with ESMTPSA (Nemesis) id 1MWRi7-1jJkHS43AZ-00XuEz for ; Fri, 03 Jul 2020 21:22:26 +0200 Received: by calimero.vinschen.de (Postfix, from userid 500) id 5ABBBA80857; Fri, 3 Jul 2020 21:22:25 +0200 (CEST) Date: Fri, 3 Jul 2020 21:22:25 +0200 From: Corinna Vinschen To: cygwin@cygwin.com Subject: Re: SIGINT lost while program calls PeekMessage Message-ID: <20200703192225.GB3499@calimero.vinschen.de> Reply-To: cygwin@cygwin.com Mail-Followup-To: cygwin@cygwin.com References: <01ea01d6508c$1a340a70$4e9c1f50$@beniston.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <01ea01d6508c$1a340a70$4e9c1f50$@beniston.com> X-Provags-ID: V03:K1:0whFys+1EQIxQDkB6NvRje/vf24M2LG1TFHlEs55XtYrS3CSEs2 KdmWfsPZkIkQuuq0ajy+xAbwJ2xpRfIL+gBV1ZnNLhT/hheFhe39FLH9YdOdXhpWKiRrct0 /Iz+3mEgM2/e5PGIa6lWgAPy5OWN7R+/oxSm0nr1JApUstbxNQmPNl7P4VRjbRqJGcrNsvX XQdFQP01NSeBbTSOPzxeg== X-UI-Out-Filterresults: notjunk:1;V03:K0:0F2aVFGTgt8=:Ao69lGeQWITNQGVoVgENt6 wZ0oEmYyU/b+/K7agf8HyE+M3lQD3HIhHLH3I88WPhGHDRzm2jmVEJpQ19YdSrZ4lohvGwhpn cNYwjN0uChhUXU4CgSvy5llILkijLmZyNLaa0RZq7StfnAWXr86TIQD4EbUKbZ2Sn1orNIx+I kBQLCWgYaztgT+Ol7m/44bs1bJG6bVe4fCItPyrbXwcuhErvxKonNNeAxPGrvjw8vN2hGHaPI 34OaWJTtlrESDWAh0dot3NOUVWSRpv0IH9pHPCp7oeb4Og583A91Cn+yrvRKj6/MwxUb7s38r oE1I6/WV19UhXBcI8vCaht2yp5RtROOigDHxHTTp6wmEBRYZWiffLwGKxRIHqPvJtZnCFg4U+ o+232etiwHIZsiiLqig7p7rPu9bA/nFC+CfRHDuTftef/EzYUhQ+GdlSCCMzG25KCPM9SsAxg D6R+9+QiLng53ZYp+hvpMbNuK7UbgfXSMfoynSf1NfKOCdS+g1JmTJPBcirXIfW3AB2kLtni2 2aGkWBor0zr7cBh5Qgx3mWjhzbvJ8T3k/AWW4NiBY6Y4GodwcAuPD7ZCuQxNONciZ1UJ0YKyT 2jJEN0Rbk2JO51ik7WFrYYiA2kOBj0HX/tnGSpPfLXgdgG22x7l3KM0K/KHuFlMaLU8qmj99+ f/sjCBnrYHoEbGCwT5ptpwsVHlhXvvPKjkEej0noSEJlAOLd2GpFJRqIP5YxccPMNWjYhI30c 6M6fBtqkBKMAYkzJyzYexN9nvRsoo5Z5mnDszn8xHrnxajUGsCPh8JmChlQuiILuuPR4gc1LG 04ppQ0Y6DaM9HQDCFpeQ4Mc3Nhjp4TSsKcK19PolzDV85x4XmsDxw5SoFr4hK2MueumkNCH X-Spam-Status: No, score=-98.9 required=5.0 tests=BAYES_00, GOOD_FROM_CORINNA_CYGWIN, KAM_DMARC_STATUS, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NEUTRAL, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: cygwin@cygwin.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: General Cygwin discussions and problem reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 03 Jul 2020 19:22:29 -0000 On Jul 2 17:16, Jon Beniston wrote: > Hi, > > I have a Cygwin program that: > > - registers a SIGINT handler, via signal(SIGINT,h) > - creates a window, using Win32 CreateWindow > - and is then calling PeekMessage for that window in a loop > > It appears that while PeekMessage is being called, any SIGINTs sent to the > program are lost. Is this to be expected as it's not really supported or a > bug? > > To reproduce: > > - Compile and run the attached example program, and repeatedly press CTRL-C > in the console. > - Only maybe 1 of every 10 or 20 times CTRL-C is pressed, is the signal > handler called. > - Similarly, running 'kill -SIGINT PID' results in most of the signals being > ignored. > - Remove the call to PeekMessage, and the signals are received. The cause of the lost signals is the fact that PeekMessage is called in a very tight busy loop(*). As soon as you ease the pain by adding a usleep(1) practically all signals will arrive(**). The problem is this: Every process has a so-called "wait_sig" thread. This thread waits for signals and when it gets one, it tries to process it. To be able to call a user-space signal handler, the thread supposed to handle this signal (here: the main thread) has to be interruptible. Threads are not interruptible while they are running in a Windows system DLL (like, e.g., kernel32.dll). Since your example code is running very tightly most of its time inside some Windows system DLL function, there's next to no chance to interrupt the thread to inject the signal handler call. Cygwin tries this 100 times per signal. If that fails, the signal gets lost. One way to solve this problem is adding a Cygwin call into the loop, like the aforementioned usleep. When a Cygwin call is performed, the signal handler will be called as soon as the Cygwin call returns to user-space. The bottom line is, Cygwin user space signal handlers and lots of Windows-only calls in a tight loop don't work nicely together. Corinna (*) Which is a no-no. Better use a thread calling GetMessage or MsgWaitForMultipleObjectsEx in a loop. (**) "Practically", because every signal is only queued once yet. That is, if a SIGINT is queued and another SIGINT arrives before the first SIGINT got dequeued, the second signal is ignored. -- Corinna Vinschen Cygwin Maintainer