X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f Message-ID: <22ca01c3c974$aa833260$0600000a@broadpark.no> From: "Gisle Vanem" To: "Eli Zaretskii" Cc: "djgpp" References: <207a01c3c8c6$26445c80$0600000a AT broadpark DOT no> Subject: Re: pending SIGALRM Date: Tue, 23 Dec 2003 17:49:00 +0100 MIME-Version: 1.0 Content-Type: text/plain; charset="Windows-1252" Content-Transfer-Encoding: 7bit X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 6.00.2800.1158 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165 Reply-To: djgpp AT delorie DOT com > No, it says that "alarm(0)" ``cancels any pending alarm''. Note that > it doesn't say SIGALRM, just ``alarm''. This means that a signal that > was already raised won't be affected. Okay, thank for explaining that. > Clearing __sigprocmask_pending_signals was not implemented, as I'm > not sure we should do that. Do other systems (e.g., GNU/Linux) clear > the pending SIGALRM when `alarm(0)' is called? If they do, we > probably should do that as well. I'm not sure. I just trying to support EINTR for e.g. recvfrom() in the Watt-32 tcp/ip stack. As I understand other stack do (BSD/Linux), they return -1 and sets errno=EINTR on a SIGALRM. My problem is that I need to block the SIGALRM from calling other socket functions again while I'm waiting in my loops. Otherwise this could cause problems (not everything is reentrant). I first tried to catch and re-raise SIGALRM same as other signals (SIGINT, SIGPIPE etc.), but failed in mysterious ways. So I've done it something like this: if (sock_sig_setup() < 0) { errno = EINTR; return -1; } /* .. do the lengthy stuff here .. */ sock_sig_restore(); return rc; } .... static sigset_t old_mask, new_mask; static void block_sigalrm (void) { sigemptyset (&new_mask); sigaddset (&new_mask, SIGALRM); sigprocmask (SIG_SETMASK, &new_mask, &old_mask); } void sock_sig_restore (int sig) { sigset_t pending; if (sigpending(&pending) == 0 && sigismember(&pending,SIGALRM) == 1) && sigprocmask(SIG_UNBLOCK, &new_mask, &old_mask)) ; /* calls the alarm() handler now when it's safe */ else if (sig) ... /* raise() other signals if caught */ } int sock_sig_setup() { int sig; /* sig_catch() longjmp() on a catch */ signal (SIGINT, sig_catch); block_sigalrm(); if ((sig = setjmp(jbuf)) != 0) { sock_sig_restore (sig); return -1; } return 0; } I'm not sure I should use SIG_SETMASK on all signals or only on SIGALRM. Or use the same masking technique for all signals. Is there a benefit doing that instead of catching and reraising the signals (besides portability) ? > The DJGPP implementation only records a single occurrence of any given > signal, so when the signal is unblocked, its handler will be called at > most once. Suites me fine. Wouldn't have to handle multiple blocked signals. --gv