diff options
author | Eric S. Raymond <esr@thyrsus.com> | 1998-08-24 16:56:14 +0000 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 1998-08-24 16:56:14 +0000 |
commit | c4bc15d8b9cb07c4794c0fbf87ca34e35f45678f (patch) | |
tree | b01595815fc538a1d81da527c0daea36f1b875fa | |
parent | e686539639ed1de38a3a62d8e8afe8e3ef456173 (diff) | |
download | fetchmail-c4bc15d8b9cb07c4794c0fbf87ca34e35f45678f.tar.gz fetchmail-c4bc15d8b9cb07c4794c0fbf87ca34e35f45678f.tar.bz2 fetchmail-c4bc15d8b9cb07c4794c0fbf87ca34e35f45678f.zip |
Gunther Leber's fix.
svn path=/trunk/; revision=2048
-rw-r--r-- | fetchmail.c | 38 |
1 files changed, 30 insertions, 8 deletions
diff --git a/fetchmail.c b/fetchmail.c index 4cf1c338..2e08a2aa 100644 --- a/fetchmail.c +++ b/fetchmail.c @@ -83,12 +83,19 @@ static struct runctl cmd_run; /* global options set from command line */ static void termhook(); /* forward declaration of exit hook */ +#if 0 +#define SLEEP_WITH_ALARM +#endif + +#ifdef SLEEP_WITH_ALARM /* - * The function of this variable is to reduce the size of the window during - * which two SIGALRMS in rapid succession can hose the code. This is a - * bit of a kluge; the real right thing would use sigprocmask(), sigsuspend() - * and close the window entirely. But since the interval isn't normally - * going to be less than one second this is not a big issue. + * The function of this variable is to remove the window during which a + * SIGALRM can hose the code (ALARM is triggered *before* pause() is called). + * This is a bit of a kluge; the real right thing would use sigprocmask(), + * sigsuspend(). + * This work around lets the interval timer trigger the first alarm after the + * required interval and will then generate alarms all 5 seconds, until it + * is certain, that the critical section (ie., the window) is left. */ #if defined(STDC_HEADERS) static sig_atomic_t alarm_latch = FALSE; @@ -97,8 +104,16 @@ static sig_atomic_t alarm_latch = FALSE; static int alarm_latch = FALSE; #endif +RETSIGTYPE gotsigalrm(sig) +int sig; +{ + signal(sig, gotsigalrm); + lastsig = sig; + alarm_latch = TRUE; +} +#endif /* SLEEP_WITH_ALARM */ + RETSIGTYPE donothing(sig) int sig; {signal(sig, donothing); lastsig = sig;} -RETSIGTYPE gotsigalrm(sig) int sig; {signal(sig, donothing); lastsig = sig; alarm_latch = TRUE;} #ifdef HAVE_ON_EXIT static void unlockit(int n, void *p) @@ -611,8 +626,9 @@ int main (int argc, char **argv) */ struct itimerval ntimeout; - ntimeout.it_interval.tv_sec = ntimeout.it_interval.tv_usec = 0; - ntimeout.it_value.tv_sec = poll_interval; + ntimeout.it_interval.tv_sec = 5; /* repeat alarm every 5 secs */ + ntimeout.it_interval.tv_usec = 0; + ntimeout.it_value.tv_sec = run.poll_interval; ntimeout.it_value.tv_usec = 0; siginterrupt(SIGALRM, 1); @@ -620,8 +636,14 @@ int main (int argc, char **argv) signal(SIGALRM, gotsigalrm); /* first trap signals */ setitimer(ITIMER_REAL,&ntimeout,NULL); /* then start timer */ /* there is a very small window between the next two lines */ + /* which could result in a deadlock. But this will now be */ + /* caught by periodical alarms (see it_interval) */ if (!alarm_latch) pause(); + /* stop timer */ + ntimeout.it_interval.tv_sec = ntimeout.it_interval.tv_usec = 0; + ntimeout.it_value.tv_sec = ntimeout.it_value.tv_usec = 0; + setitimer(ITIMER_REAL,&ntimeout,NULL); /* now stop timer */ signal(SIGALRM, SIG_IGN); #else /* |