X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Fstatserv.c;h=a502bee2e0235f1489c866667552c54cbeb238ec;hp=d111a6f53f9dc37202fc12f4243949ba5492487b;hb=5c3d2d2ab097e4bb59ba5718a396b020a2d302c0;hpb=f4c095a042b1bcccb78136be87944e46412386aa diff --git a/src/statserv.c b/src/statserv.c index d111a6f..a502bee 100644 --- a/src/statserv.c +++ b/src/statserv.c @@ -5,7 +5,7 @@ * NT threaded server code by * Chas Woodfield, Fretwell Downing Informatics. * - * $Id: statserv.c,v 1.13 2004-12-13 14:21:55 heikki Exp $ + * $Id: statserv.c,v 1.17 2005-01-03 11:56:08 adam Exp $ */ /** @@ -404,23 +404,32 @@ static int no_sessions = 0; static void listener(IOCHAN h, int event) { COMSTACK line = (COMSTACK) iochan_getdata(h); - static int hand[2]; - static int child = 0; int res; if (event == EVENT_INPUT) { - if (control_block.dynamic && !child) + COMSTACK new_line; + if ((res = cs_listen_check(line, 0, 0, control_block.check_ip, + control_block.daemon_name)) < 0) + { + yaz_log(YLOG_WARN|YLOG_ERRNO, "cs_listen failed"); + return; + } + else if (res == 1) + { + yaz_log(YLOG_WARN, "cs_listen incomplete"); + return; + } + new_line = cs_accept(line); + if (!new_line) + { + yaz_log(YLOG_FATAL, "Accept failed."); + iochan_setflags(h, EVENT_INPUT | EVENT_EXCEPT); /* reset listener */ + return; + } + no_sessions++; + if (control_block.dynamic) { - int res; - - ++no_sessions; - if (pipe(hand) < 0) - { - yaz_log(YLOG_FATAL|YLOG_ERRNO, "pipe"); - iochan_destroy(h); - return; - } if ((res = fork()) < 0) { yaz_log(YLOG_FATAL|YLOG_ERRNO, "fork"); @@ -432,16 +441,11 @@ static void listener(IOCHAN h, int event) char nbuf[100]; IOCHAN pp; - close(hand[0]); - child = 1; for (pp = pListener; pp; pp = iochan_getnext(pp)) { - if (pp != h) - { - COMSTACK l = (COMSTACK)iochan_getdata(pp); - cs_close(l); - iochan_destroy(pp); - } + COMSTACK l = (COMSTACK)iochan_getdata(pp); + cs_close(l); + iochan_destroy(pp); } sprintf(nbuf, "%s(%d)", me, no_sessions); yaz_log_init(control_block.loglevel, nbuf, 0); @@ -451,82 +455,17 @@ static void listener(IOCHAN h, int event) } else /* parent */ { - close(hand[1]); - /* wait for child to take the call */ - for (;;) - { - char dummy[1]; - int res; - - if ((res = read(hand[0], dummy, 1)) < 0 && - yaz_errno() != EINTR) - { - yaz_log(YLOG_FATAL|YLOG_ERRNO, "handshake read"); - return; - } - else if (res >= 0) - break; - } - yaz_log(YLOG_DEBUG, "P: Child has taken the call"); - close(hand[0]); + cs_close(new_line); return; } } - if ((res = cs_listen_check(line, 0, 0, control_block.check_ip, - control_block.daemon_name)) < 0) - { - yaz_log(YLOG_WARN|YLOG_ERRNO, "cs_listen failed"); - return; - } - else if (res == 1) - return; - yaz_log(YLOG_DEBUG, "listen ok"); - iochan_setevent(h, EVENT_OUTPUT); - iochan_setflags(h, EVENT_OUTPUT | EVENT_EXCEPT); /* set up for acpt */ - } - /* in dynamic mode, only the child ever comes down here */ - else if (event == EVENT_OUTPUT) - { - COMSTACK new_line = cs_accept(line); - - if (!new_line) - { - yaz_log(YLOG_FATAL, "Accept failed."); - iochan_setflags(h, EVENT_INPUT | EVENT_EXCEPT); /* reset listener */ - return; - } - yaz_log(YLOG_DEBUG, "accept ok"); - if (control_block.dynamic) - { - IOCHAN pp; - /* close our half of the listener socket */ - for (pp = pListener; pp; pp = iochan_getnext(pp)) - { - COMSTACK l = (COMSTACK)iochan_getdata(pp); - cs_close(l); - iochan_destroy(pp); - } - /* release dad */ - yaz_log(YLOG_DEBUG, "Releasing parent"); - close(hand[1]); - } - else - { - iochan_setflags(h, EVENT_INPUT | EVENT_EXCEPT); /* reset listener */ - ++no_sessions; - } -#if YAZ_POSIX_THREADS if (control_block.threads) { +#if YAZ_POSIX_THREADS pthread_t child_thread; pthread_create (&child_thread, 0, new_session, new_line); pthread_detach (child_thread); - } - else - new_session(new_line); #elif YAZ_GNU_THREADS - if (control_block.threads) - { pth_attr_t attr; pth_t child_thread; @@ -538,12 +477,12 @@ static void listener(IOCHAN h, int event) child_thread = pth_spawn (attr, new_session, new_line); yaz_log (YLOG_DEBUG, "pth_spawn finish"); pth_attr_destroy (attr); +#else + new_session(new_line); +#endif } else new_session(new_line); -#else - new_session(new_line); -#endif } else if (event == EVENT_TIMEOUT) { @@ -599,9 +538,9 @@ static void *new_session (void *vp) #else a = 0; #endif - yaz_log(log_session, "Starting session from %s (pid=%d)", - a ? a : "[Unknown]", getpid()); - if (max_sessions && no_sessions == max_sessions) + yaz_log(log_session, "Starting session %d from %s (pid=%ld)", + no_sessions, a ? a : "[Unknown]", (long) getpid()); + if (max_sessions && no_sessions >= max_sessions) control_block.one_shot = 1; if (control_block.threads) { @@ -773,25 +712,48 @@ int statserv_start(int argc, char **argv) inetd_connection(control_block.default_proto); else { + static int hand[2]; if (control_block.background) { + /* create pipe so that parent waits until child has created + PID (or failed) */ + if (pipe(hand) < 0) + { + yaz_log(YLOG_FATAL|YLOG_ERRNO, "pipe"); + return 1; + } switch (fork()) { case 0: break; case -1: return 1; - default: - _exit(0); + default: + close(hand[1]); + while(1) + { + char dummy[1]; + int res = read(hand[0], dummy, 1); + if (res < 0 && yaz_errno() != EINTR) + { + yaz_log(YLOG_FATAL|YLOG_ERRNO, "read fork handshake"); + break; + } + else if (res >= 0) + break; + } + close(hand[0]); + _exit(0); } - + /* child */ + close(hand[0]); if (setsid() < 0) return 1; close(0); close(1); close(2); - open("/dev/null",O_RDWR); + open("/dev/null", O_RDWR); dup(0); dup(0); } if (!pListener && *control_block.default_listen) @@ -814,7 +776,11 @@ int statserv_start(int argc, char **argv) fclose(f); } - yaz_log (log_server, "Starting server %s pid=%d", programname, getpid()); + if (control_block.background) + close(hand[1]); + + yaz_log (log_server, "Starting server %s pid=%ld", programname, + (long) getpid()); #if 0 sigset_t sigs_to_block;