[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
Re: signal() behavior
I've noticed an annoying behavior in the alpha slapd on Linux: If the daemon
is running in the background, it appears to ignore SIGTERM. What has
actually happened is that the daemon is in select(), and the select call has
been restarted after the signal handler was invoked. I.e., the default
behavior on Linux for signal() is to restart system calls - it uses the
default BSD semantics. Anyone testing on Solaris or other SVR4-derived OSs
will not see this problem, because SysV signal() does not restart system
calls by default.
The solution seems to be to check for sigaction() in configure, and use it
instead of signal() if it's found. I'll make this fix in a little while.
I've been fighting with this for a while, too. However, it's not as
simple as using sigaction (or sigvec) in place of signal where
possible. Some systems don't return EINTR from select even when a
signal is set with the SA_RESTART (or SA_INTERRUPT) flag set in these
two calls. The issue is that some systems set the signal, and the
first thread to notice the signal will service it. If the thread
that has called select is not the thread to pick up the signal, the
select call will not return with EINTR.
There has to be some way to make this work "correctly" on all
systems, and that's what I've been searching for. For now, I've been
using a kludge solution that never passes NULL as the time value to
select. Instead, tvp is set to point to a tv that specifies some
small number of seconds. This uses a bit of CPU time, but solves the
problem of killing slapd (without using kill -9).
Here are diffs from daemon.c. I have not submitted them because they
are not the ideal fix for this problem. However, if there is no good
fix, I'll submit them.
--- daemon.c 1999/08/19 09:44:44 1.106
+++ daemon.c 1999/08/24 23:46:36
@@ -517,5 +517,5 @@
struct hostent *hp;
#endif
- struct timeval zero;
+ struct timeval zero , five;
struct timeval *tvp;
@@ -532,4 +532,6 @@
zero.tv_sec = 0;
zero.tv_usec = 0;
+ five.tv_sec = 5;
+ five.tv_usec = 0;
ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
@@ -573,4 +575,7 @@
#endif
+ if (!tvp)
+ tvp = &five;
+
for ( l = 0; slap_listeners[l] != NULL; l++ ) {
if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID )