/*
- * $Id: comm.c,v 1.4 2009-10-13 22:55:37 didg Exp $
+ * $Id: comm.c,v 1.5 2009-10-18 17:50:13 didg Exp $
*
* Copyright (C) Joerg Lenneis 2003
* All Rights Reserved. See COPYING.
#include <sys/socket.h>
#endif
+#include <sys/select.h>
#include <assert.h>
#include <time.h>
* things and clean up fd_table. The same happens for any read/write errors.
*/
-static int check_fd(void)
+static int check_fd(time_t timeout, const sigset_t *sigmask)
{
int fd;
fd_set readfds;
- struct timeval tv;
+ struct timespec tv;
int ret;
int i;
int maxfd = control_fd;
maxfd = fd_table[i].fd;
}
- tv.tv_usec = 0;
- tv.tv_sec = 1;
- if ((ret = select(maxfd + 1, &readfds, NULL, NULL, &tv)) < 0) {
+ tv.tv_nsec = 0;
+ tv.tv_sec = timeout;
+ if ((ret = pselect(maxfd + 1, &readfds, NULL, NULL, &tv, sigmask)) < 0) {
if (errno == EINTR)
return 0;
LOG(log_error, logtype_cnid, "error in select: %s",strerror(errno));
}
/* ------------ */
-int comm_rcv(struct cnid_dbd_rqst *rqst)
+int comm_rcv(struct cnid_dbd_rqst *rqst, time_t timeout, const sigset_t *sigmask)
{
char *nametmp;
int b;
- if ((cur_fd = check_fd()) < 0)
+ if ((cur_fd = check_fd(timeout, sigmask)) < 0)
return -1;
if (!cur_fd)
/*
- * $Id: comm.h,v 1.3 2009-10-13 22:55:37 didg Exp $
+ * $Id: comm.h,v 1.4 2009-10-18 17:50:13 didg Exp $
*
* Copyright (C) Joerg Lenneis 2003
* All Rights Reserved. See COPYING.
extern int comm_init (struct db_param *, int, int);
-extern int comm_rcv (struct cnid_dbd_rqst *);
+extern int comm_rcv (struct cnid_dbd_rqst *, time_t, const sigset_t *);
extern int comm_snd (struct cnid_dbd_rply *);
extern int comm_nbe (void);
/*
- * $Id: main.c,v 1.11 2009-10-14 01:38:28 didg Exp $
+ * $Id: main.c,v 1.12 2009-10-18 17:50:13 didg Exp $
*
* Copyright (C) Joerg Lenneis 2003
* Copyright (c) Frank Lahm 2009
of the cnid_dbd_rply structure contains further details.
*/
+#ifndef min
+#define min(a,b) ((a)<(b)?(a):(b))
+#endif
static int loop(struct db_param *dbp)
{
struct cnid_dbd_rqst rqst;
struct cnid_dbd_rply rply;
+ time_t timeout;
int ret, cret;
int count;
time_t now, time_next_flush, time_last_rqst;
char timebuf[64];
static char namebuf[MAXPATHLEN + 1];
+ sigset_t set;
+
+ sigemptyset(&set);
+ sigprocmask(SIG_SETMASK, NULL, &set);
+ sigdelset(&set, SIGINT);
+ sigdelset(&set, SIGTERM);
count = 0;
now = time(NULL);
dbp->flush_interval, timebuf);
while (1) {
- if ((cret = comm_rcv(&rqst)) < 0)
+ timeout = min(time_next_flush, time_last_rqst +dbp->idle_timeout);
+ if (timeout > now)
+ timeout -= now;
+ else
+ timeout = 1;
+
+ if ((cret = comm_rcv(&rqst, timeout, &set)) < 0)
return -1;
now = time(NULL);
if (cret == 0) {
/* comm_rcv returned from select without receiving anything. */
-
- /* Give signals a chance... */
- block_sigs_onoff(0);
- block_sigs_onoff(1);
if (exit_sig)
/* Received signal (TERM|INT) */
return 0;
set_signal();
- /* SIGINT and SIGTERM are always off, unless we get a return code of 0 from
- comm_rcv (no requests for one second, see above in loop()). That means we
- only shut down after one second of inactivity. */
+ /* SIGINT and SIGTERM are always off, unless we are in pselect */
block_sigs_onoff(1);
if ((dbp = db_param_read(dir, CNID_DBD)) == NULL)