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;

Reply via email to