Package: dspam
Version: 3.10.2+dfsg-7
Severity: normal
Tags: patch
--- Please enter the report below this line. ---
Hi,
Currently, the daemon has an active loop. It calls select with a 2
seconds timeout, just to to be sure that no signal was raised.
This could be avoided. I choose the self-pipe trick, cause it's the
solution that integrate the most with the current code.
Using pselect would have meant blocking signals just before the call,
and would have needed a re-enabling in the process request. I didn't
have the time to appreciate the impact of that.
This has been submitted upstream on
https://sourceforge.net/tracker/?func=detail&aid=3607521&group_id=250683&atid=1126467
I just hope that Debian packagers are faster than dspam main development
team :)
--- System information. ---
Architecture: i386
Kernel: Linux 3.2.0-4-686-pae
Debian Release: 7.0
500 unstable ftp.fr.debian.org
1 experimental ftp.fr.debian.org
--- Package information. ---
Package's Depends field is empty.
Package's Recommends field is empty.
Package's Suggests field is empty.
Index: dspam-3.10.2+dfsg/src/daemon.c
===================================================================
--- dspam-3.10.2+dfsg.orig/src/daemon.c 2013-03-10 13:14:10.395276325 +0100
+++ dspam-3.10.2+dfsg/src/daemon.c 2013-03-10 13:40:37.385764095 +0100
@@ -104,6 +104,11 @@
signal(SIGTERM, process_signal);
signal(SIGHUP, process_signal);
+ /* Setup of the self-pipe */
+ if (pipe2(self_pipe, O_NONBLOCK | O_CLOEXEC) == -1) {
+ LOG(LOG_CRIT, ERR_DAEMON_FAIL, strerror(errno));
+ }
+
if (_ds_read_attribute(agent_config, "ServerPort"))
port = atoi(_ds_read_attribute(agent_config, "ServerPort"));
@@ -201,17 +206,18 @@
}
FD_SET(listener, &master);
+ FD_SET(self_pipe[0], &master);
fdmax = listener;
/* Process new connections (until death or reload) */
for(;;) {
read_fds = master;
- tv.tv_sec = 2;
- tv.tv_usec = 0;
if (__daemon_run == 0) {
close(listener);
+ close(self_pipe[0]);
+ close(self_pipe[1]);
if (_ds_read_attribute(agent_config, "ServerDomainSocketPath"))
unlink (_ds_read_attribute(agent_config, "ServerDomainSocketPath"));
@@ -219,7 +225,7 @@
return 0;
}
- if (select(fdmax+1, &read_fds, NULL, NULL, &tv)>0) {
+ if (select(fdmax+1, &read_fds, NULL, NULL, NULL)>0) {
/* Process read-ready connections */
@@ -227,8 +233,14 @@
if (FD_ISSET(i, &read_fds)) {
/* Accept new connections */
-
- if (i == listener) {
+ if (i == self_pipe[0]) {
+ /* Empty the pipe */
+ char ch;
+ LOGDEBUG("Self wakeup");
+ /* Remember that the pipe is non-blocking */
+ while (read(self_pipe[0], &ch, 1) > 0) {
+ }
+ } else if (i == listener) {
int newfd;
int addrlen = sizeof(remote_addr);
@@ -1096,6 +1108,14 @@
__hup = 0;
}
+ // Self wakeup
+ int savedErrno; /* In case we change 'errno' */
+
+ savedErrno = errno;
+ if (write(self_pipe[1], "x", 1) == -1 && errno != EAGAIN) {
+ LOGDEBUG("Unable to wakeup ourself");
+ }
+ errno = savedErrno;
return;
}
Index: dspam-3.10.2+dfsg/src/daemon.h
===================================================================
--- dspam-3.10.2+dfsg.orig/src/daemon.h 2013-03-10 13:14:10.395276325 +0100
+++ dspam-3.10.2+dfsg/src/daemon.h 2013-03-10 13:14:10.391276306 +0100
@@ -46,6 +46,7 @@
int __num_threads; /* number of live threads */
int __hup; /* should we reload? */
pthread_mutex_t __lock; /* global var lock */
+int self_pipe[2]; /* self-pipe trick for signal handler */
typedef struct {
int sockfd;