Changeset: 48fec04bccd1 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=48fec04bccd1 Modified Files: tools/merovingian/daemon/forkmserver.c tools/merovingian/daemon/merovingian.c tools/merovingian/daemon/merovingian.h Branch: Jun2016 Log Message:
Fix race. In logListener, only read from file descriptors that we added to the list of file descriptors to read. If during the wait in select a file descriptor is closed and the corresponding link in the list is freed, and then a new link is added that happens to contain the same file descriptor, we don't want to read from that one. We do this by setting a flag that we're interested in the file descriptor, and only reading from file descriptors whose flag is set. See bug 4066, comment 29. diffs (96 lines): diff --git a/tools/merovingian/daemon/forkmserver.c b/tools/merovingian/daemon/forkmserver.c --- a/tools/merovingian/daemon/forkmserver.c +++ b/tools/merovingian/daemon/forkmserver.c @@ -350,6 +350,7 @@ forkMserver(char *database, sabdb** stat dp->type = MEROFUN; dp->pid = getpid(); dp->dbname = strdup(database); + dp->flag = 0; pthread_mutex_unlock(&_mero_topdp_lock); @@ -581,6 +582,7 @@ forkMserver(char *database, sabdb** stat dp->type = MERODB; dp->pid = pid; dp->dbname = strdup(database); + dp->flag = 0; pthread_mutex_unlock(&_mero_topdp_lock); diff --git a/tools/merovingian/daemon/merovingian.c b/tools/merovingian/daemon/merovingian.c --- a/tools/merovingian/daemon/merovingian.c +++ b/tools/merovingian/daemon/merovingian.c @@ -199,6 +199,7 @@ logListener(void *x) FD_SET(w->err, &readfds); if (nfds < w->err) nfds = w->err; + w->flag |= 1; w = w->next; } @@ -216,12 +217,16 @@ logListener(void *x) w = d; while (w != NULL) { - if (FD_ISSET(w->out, &readfds) != 0) - logFD(w->out, "MSG", w->dbname, - (long long int)w->pid, _mero_logfile); - if (w->err != w->out && FD_ISSET(w->err, &readfds) != 0) - logFD(w->err, "ERR", w->dbname, - (long long int)w->pid, _mero_logfile); + /* only look at records we've added in the previous loop */ + if (w->flag & 1) { + if (FD_ISSET(w->out, &readfds) != 0) + logFD(w->out, "MSG", w->dbname, + (long long int)w->pid, _mero_logfile); + if (w->err != w->out && FD_ISSET(w->err, &readfds) != 0) + logFD(w->err, "ERR", w->dbname, + (long long int)w->pid, _mero_logfile); + w->flag &= ~1; + } w = w->next; } @@ -625,6 +630,7 @@ main(int argc, char *argv[]) _mero_topdp->pid = 0; _mero_topdp->type = MERO; _mero_topdp->dbname = NULL; + _mero_topdp->flag = 0; /* where should our msg output go to? */ p = getConfVal(_mero_props, "logfile"); @@ -667,6 +673,7 @@ main(int argc, char *argv[]) d->pid = getpid(); d->type = MERO; d->dbname = "merovingian"; + d->flag = 0; /* separate entry for the neighbour discovery service */ d = d->next = &dpdisc; @@ -688,6 +695,7 @@ main(int argc, char *argv[]) d->type = MERO; d->dbname = "discovery"; d->next = NULL; + d->flag = 0; /* separate entry for the control runner */ d = d->next = &dpcont; @@ -709,6 +717,7 @@ main(int argc, char *argv[]) d->type = MERO; d->dbname = "control"; d->next = NULL; + d->flag = 0; /* allow a thread to relock this mutex */ pthread_mutexattr_init(&mta); diff --git a/tools/merovingian/daemon/merovingian.h b/tools/merovingian/daemon/merovingian.h --- a/tools/merovingian/daemon/merovingian.h +++ b/tools/merovingian/daemon/merovingian.h @@ -57,6 +57,7 @@ typedef struct _dpair { int out; /* where to read stdout messages from */ int err; /* where to read stderr messages from */ mtype type; /* type of process */ + short flag; /* flag internal to logListener */ pid_t pid; /* this process' id */ char *dbname; /* the database that this server serves */ struct _dpair* next; _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list