Changeset: f3bdb8dcaebf for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=f3bdb8dcaebf Modified Files: monetdb5/modules/mal/mal_mapi.c Branch: Jan2014 Log Message:
Fix potential race conditions, and avoid killing threads. diffs (96 lines): diff --git a/monetdb5/modules/mal/mal_mapi.c b/monetdb5/modules/mal/mal_mapi.c --- a/monetdb5/modules/mal/mal_mapi.c +++ b/monetdb5/modules/mal/mal_mapi.c @@ -178,9 +178,13 @@ doChallenge(stream *in, stream *out) { MSscheduleClient(buf, challenge, bs, fdout); } -static MT_Id listener[8]; -static int lastlistener=0; -static int serveractive=TRUE; +static volatile ATOMIC_TYPE nlistener = 0; /* nr of listeners */ +static volatile ATOMIC_TYPE serveractive = 0; +static volatile ATOMIC_TYPE serverexiting = 0; /* listeners should exit */ +#ifdef ATOMIC_LOCK +/* lock for all three ATOMIC_TYPE variables above */ +static MT_Lock atomicLock MT_LOCK_INITIALIZER("atomicLock"); +#endif static void SERVERlistenThread(SOCKET *Sock) @@ -199,8 +203,7 @@ SERVERlistenThread(SOCKET *Sock) GDKfree(Sock); } - if (lastlistener < 8) - listener[lastlistener++] = MT_getpid(); + (void) ATOMIC_INC(nlistener, atomicLock, "SERVERlistenThread"); do { FD_ZERO(&fds); @@ -221,7 +224,8 @@ SERVERlistenThread(SOCKET *Sock) msgsock = usock; #endif retval = select((int)msgsock + 1, &fds, NULL, NULL, &tv); - if (GDKexiting()) + if (ATOMIC_GET(serverexiting, atomicLock, "SERVERlistenThread") || + GDKexiting()) break; if (retval == 0) { /* nothing interesting has happened */ @@ -236,7 +240,7 @@ SERVERlistenThread(SOCKET *Sock) } if (sock != INVALID_SOCKET && FD_ISSET(sock, &fds)) { if ((msgsock = accept(sock, (SOCKPTR)0, (socklen_t *)0)) == INVALID_SOCKET) { - if (MT_geterrno() != EINTR || serveractive == FALSE) { + if (MT_geterrno() != EINTR || !ATOMIC_GET(serveractive, atomicLock, "SERVERlistenThread")) { msg = "accept failed"; goto error; } @@ -330,7 +334,9 @@ SERVERlistenThread(SOCKET *Sock) doChallenge( socket_rastream(msgsock, "Server read"), socket_wastream(msgsock, "Server write")); - } while (!GDKexiting()); + } while (!ATOMIC_GET(serverexiting, atomicLock, "SERVERlistenThread") && + !GDKexiting()); + (void) ATOMIC_DEC(nlistener, atomicLock, "SERVERlistenThread"); return; error: fprintf(stderr, "!mal_mapi.listen: %s, terminating listener\n", msg); @@ -599,12 +605,12 @@ SERVERlisten_port(int *ret, int *pid) str SERVERstop(int *ret) { - int i; - -printf("SERVERstop\n"); - for( i=0; i< lastlistener; i++) - MT_kill_thread(listener[i]); - lastlistener = 0; +fprintf(stderr, "SERVERstop\n"); + ATOMIC_SET(serverexiting, 1, atomicLock, "SERVERstop"); + /* wait until they all exited, but skip the wait if the whole + * system is going down */ + while (ATOMIC_GET(nlistener, atomicLock, "SERVERstop") > 0 && !GDKexiting()) + MT_sleep_ms(100); (void) ret; /* fool compiler */ return MAL_SUCCEED; } @@ -614,14 +620,14 @@ str SERVERsuspend(int *res) { (void) res; - serveractive= FALSE; + ATOMIC_SET(serveractive, 0, atomicLock, "SERVERsuspend"); return MAL_SUCCEED; } str SERVERresume(int *res) { - serveractive= TRUE; + ATOMIC_SET(serveractive, 1, atomicLock, "SERVERsuspend"); (void) res; return MAL_SUCCEED; } _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list