=== modified file 'configure.in' --- configure.in 2009-04-30 11:51:29 +0000 +++ configure.in 2009-05-03 10:43:21 +0000 @@ -65,6 +65,10 @@ AC_LIBTOOL_DLOPEN if test $use_loadable_modules = yes; then + dnl Debian libtool 2.2.6 is broken. + top_build_prefix=${top_build_dir} + _AC_HAVE_TOP_BUILD_PREFIX=0 + AC_LIBLTDL_CONVENIENCE(lib/libLtdl) fi AC_PROG_LIBTOOL === modified file 'src/helper.cc' --- src/helper.cc 2009-04-17 22:09:22 +0000 +++ src/helper.cc 2009-05-05 12:09:27 +0000 @@ -68,6 +68,30 @@ static void helperStatefulServerKickQueue(helper_stateful_server * srv); static bool helperStartStats(StoreEntry *sentry, void *hlp, const char *label); +/** + * Abort reading from this helper immediately. + * + * This is a sharp short closure for the helper which may be used + * for quick closure or error aborting. + * Any pending requests are abandoned. + * + * It's used during helprShutdown, but that is just graceful enough + * to schedule the close and wait for existing queues to drain. + */ +static void helperDoAbort(helper_server * srv); +static void helperStatefulDoAbort(helper_stateful_server * srv); + +/** + * Graceful closure of the helper. + * Write socket is closed and helper marked as closing so that + * further requests are not queued. + * + * Pending queued items are currently abandoned (need to fix that), + * but requests already sent to the helper are waited for + * and the sockets only fully closed when none remain to receive back. + */ +static void helperDoGracefulClose(helper_server * srv); +static void helperStatefulDoGracefulClose(helper_stateful_server * srv); CBDATA_TYPE(helper); CBDATA_TYPE(helper_server); @@ -419,7 +443,7 @@ if (srv->flags.reserved == S_HELPER_RESERVED) continue; - if (!srv->flags.shutdown) + if (srv->flags.shutdown || srv->flags.closing) continue; if ((hlp->IsAvailable != NULL) && (srv->data != NULL) && @@ -587,7 +611,7 @@ storeAppendPrintf(sentry, " B = BUSY\n"); storeAppendPrintf(sentry, " W = WRITING\n"); storeAppendPrintf(sentry, " C = CLOSING\n"); - storeAppendPrintf(sentry, " S = SHUTDOWN\n"); + storeAppendPrintf(sentry, " S = SHUTDOWN PENDING\n"); } void @@ -644,16 +668,15 @@ storeAppendPrintf(sentry, " B = BUSY\n"); storeAppendPrintf(sentry, " C = CLOSING\n"); storeAppendPrintf(sentry, " R = RESERVED or DEFERRED\n"); - storeAppendPrintf(sentry, " S = SHUTDOWN\n"); + storeAppendPrintf(sentry, " S = SHUTDOWN PENDING\n"); storeAppendPrintf(sentry, " P = PLACEHOLDER\n"); } -void +int helperShutdown(helper * hlp) { dlink_node *link = hlp->servers.head; #ifdef _SQUID_MSWIN_ - HANDLE hIpc; pid_t pid; int no; @@ -669,65 +692,31 @@ continue; } - hlp->n_active--; - assert(hlp->n_active >= 0); - - srv->flags.shutdown = 1; /* request it to shut itself down */ + srv->flags.shutdown = 1; /* request it to shut itself down at next available moment */ if (srv->flags.closing) { - debugs(84, 3, "helperShutdown: " << hlp->id_name << " #" << srv->index + 1 << " is CLOSING."); + debugs(84, 3, "helperShutdown: " << hlp->id_name << " #" << srv->index + 1 << " is CLOSING. Shutdown pending."); continue; } if (srv->stats.pending) { - debugs(84, 3, "helperShutdown: " << hlp->id_name << " #" << srv->index + 1 << " is BUSY."); + debugs(84, 1, "helperShutdown: " << hlp->id_name << " #" << srv->index + 1 << " is BUSY. Shutdown delayed."); continue; } - srv->flags.closing = 1; -#ifdef _SQUID_MSWIN_ - - hIpc = srv->hIpc; - pid = srv->pid; - no = srv->index + 1; - shutdown(srv->wfd, SD_BOTH); -#endif - - debugs(84, 3, "helperShutdown: " << hlp->id_name << " #" << srv->index + 1 << " shutting down."); - /* the rest of the details is dealt with in the helperServerFree - * close handler - */ - comm_close(srv->rfd); -#ifdef _SQUID_MSWIN_ - - if (hIpc) { - if (WaitForSingleObject(hIpc, 5000) != WAIT_OBJECT_0) { - getCurrentTime(); - debugs(84, 1, "helperShutdown: WARNING: " << hlp->id_name << - " #" << no << " (" << hlp->cmdline->key << "," << - (long int)pid << ") didn't exit in 5 seconds"); - - } - - CloseHandle(hIpc); - } - -#endif - + hlp->n_active--; + assert(hlp->n_active >= 0); + helperDoAbort(srv); } + + return hlp->n_active; } -void +int helperStatefulShutdown(statefulhelper * hlp) { dlink_node *link = hlp->servers.head; helper_stateful_server *srv; -#ifdef _SQUID_MSWIN_ - - HANDLE hIpc; - pid_t pid; - int no; -#endif while (link) { srv = (helper_stateful_server *)link->data; @@ -738,63 +727,118 @@ continue; } - hlp->n_active--; - assert(hlp->n_active >= 0); srv->flags.shutdown = 1; /* request it to shut itself down */ + if (srv->flags.closing) { + debugs(84, 3, "helperStatefulShutdown: " << hlp->id_name << " #" << srv->index + 1 << " is CLOSING."); + continue; + } + if (srv->flags.busy) { - debugs(84, 3, "helperStatefulShutdown: " << hlp->id_name << " #" << srv->index + 1 << " is BUSY."); - continue; - } - - if (srv->flags.closing) { - debugs(84, 3, "helperStatefulShutdown: " << hlp->id_name << " #" << srv->index + 1 << " is CLOSING."); + debugs(84, 1, "helperStatefulShutdown: " << hlp->id_name << " #" << srv->index + 1 << " is BUSY."); continue; } if (srv->flags.reserved != S_HELPER_FREE) { - debugs(84, 3, "helperStatefulShutdown: " << hlp->id_name << " #" << srv->index + 1 << " is RESERVED."); + debugs(84, 1, "helperStatefulShutdown: " << hlp->id_name << " #" << srv->index + 1 << " is RESERVED."); continue; } if (srv->deferred_requests) { - debugs(84, 3, "helperStatefulShutdown: " << hlp->id_name << " #" << srv->index + 1 << " has DEFERRED requests."); + debugs(84, 1, "helperStatefulShutdown: " << hlp->id_name << " #" << srv->index + 1 << " has DEFERRED requests."); continue; } - srv->flags.closing = 1; -#ifdef _SQUID_MSWIN_ - - hIpc = srv->hIpc; - pid = srv->pid; - no = srv->index + 1; - shutdown(srv->wfd, SD_BOTH); -#endif - - debugs(84, 3, "helperStatefulShutdown: " << hlp->id_name << " #" << srv->index + 1 << " shutting down."); - - /* the rest of the details is dealt with in the helperStatefulServerFree - * close handler - */ - comm_close(srv->rfd); -#ifdef _SQUID_MSWIN_ - - if (hIpc) { - if (WaitForSingleObject(hIpc, 5000) != WAIT_OBJECT_0) { - getCurrentTime(); - debugs(84, 1, "helperShutdown: WARNING: " << hlp->id_name << - " #" << no << " (" << hlp->cmdline->key << "," << - (long int)pid << ") didn't exit in 5 seconds"); - } - - CloseHandle(hIpc); - } - -#endif - - } -} - + hlp->n_active--; + assert(hlp->n_active >= 0); + helperStatefulDoAbort(srv); + } + + return hlp->n_active; +} + + +void +helperDoAbort(helper_server *srv) +{ +#ifdef _SQUID_MSWIN_ + HANDLE hIpc = srv->hIpc; + pid_t pid = srv->pid; + int no = srv->index + 1; + shutdown(srv->wfd, SD_BOTH); +#endif + + debugs(84, 3, "helperDoClose: " << hlp->id_name << " #" << srv->index + 1 << " shutting down."); + + /* the rest of the details is dealt with in the helperServerFree + * close handler + */ + srv->flags.closing = 1; + comm_close(srv->rfd); + +#ifdef _SQUID_MSWIN_ + if (hIpc) { + if (WaitForSingleObject(hIpc, 5000) != WAIT_OBJECT_0) { + getCurrentTime(); + debugs(84, 1, "helperDoClose: WARNING: " << hlp->id_name << + " #" << no << " (" << hlp->cmdline->key << "," << + (long int)pid << ") didn't exit in 5 seconds"); + } + CloseHandle(hIpc); + } +#endif +} + +// TODO merge the stateful and non-stateful close functions into one. They are exactly identical. +void +helperStatefulDoAbort(helper_stateful_server *srv) +{ +#ifdef _SQUID_MSWIN_ + HANDLE hIpc = srv->hIpc; + pid_t pid = srv->pid; + int no = srv->index + 1; + shutdown(srv->wfd, SD_BOTH); +#endif + + debugs(84, 3, "helperStatefulDoClose: " << hlp->id_name << " #" << srv->index + 1 << " shutting down."); + + /* the rest of the details is dealt with in the helperStatefulServerFree + * close handler + */ + srv->flags.closing = 1; + comm_close(srv->rfd); + +#ifdef _SQUID_MSWIN_ + if (hIpc) { + if (WaitForSingleObject(hIpc, 5000) != WAIT_OBJECT_0) { + getCurrentTime(); + debugs(84, 1, "helperStatefulDoClose: WARNING: " << hlp->id_name << + " #" << no << " (" << hlp->cmdline->key << "," << + (long int)pid << ") didn't exit in 5 seconds"); + } + CloseHandle(hIpc); + } +#endif +} + +void +helperDoGracefulClose(helper_server *srv) +{ + int wfd = srv->wfd; + srv->wfd = -1; + srv->flags.closing=1; + comm_close(wfd); +} + +// TODO merge the stateful and non-stateful close functions into one. They are exactly identical. +void +helperStatefulDoGracefulClose(helper_stateful_server *srv) +{ + int wfd = srv->wfd; + srv->wfd = -1; + srv->flags.closing=1; + comm_close(wfd); +} helper * helperCreate(const char *name) @@ -892,8 +936,9 @@ safe_free(srv->requests); + /* TODO: walk the local queue of requests and carry them all out with error results ? */ if (srv->wfd != srv->rfd && srv->wfd != -1) - comm_close(srv->wfd); + helperDoGracefulClose(srv); dlinkDelete(&srv->link, &hlp->servers); @@ -954,9 +999,9 @@ srv->request = NULL; } - /* TODO: walk the local queue of requests and carry them all out */ + /* TODO: walk the local queue of requests and carry them all out with error results ? */ if (srv->wfd != srv->rfd && srv->wfd != -1) - comm_close(srv->wfd); + helperStatefulDoGracefulClose(srv); dlinkDelete(&srv->link, &hlp->servers); @@ -1011,8 +1056,7 @@ if (len < 0) debugs(84, 1, "helperHandleRead: FD " << fd << " read: " << xstrerror()); - comm_close(fd); - + helperDoClose(srv); return; } @@ -1080,17 +1124,13 @@ debugs(84, 1, "helperHandleRead: unexpected reply on channel " << i << " from " << hlp->id_name << " #" << srv->index + 1 << " '" << srv->rbuf << "'"); - } srv->roffset -= (t - srv->rbuf); memmove(srv->rbuf, t, srv->roffset + 1); if (srv->flags.shutdown) { - int wfd = srv->wfd; - srv->wfd = -1; - srv->flags.closing=1; - comm_close(wfd); + helperDoGracefulClose(srv); return; } else helperKickQueue(hlp); @@ -1123,8 +1163,7 @@ if (len < 0) debugs(84, 1, "helperStatefulHandleRead: FD " << fd << " read: " << xstrerror()); - comm_close(fd); - + helperStatefulDoClose(srv); return; } @@ -1219,10 +1258,8 @@ if (srv->flags.shutdown && srv->flags.reserved == S_HELPER_FREE && !srv->deferred_requests) { - int wfd = srv->wfd; - srv->wfd = -1; - srv->flags.closing=1; - comm_close(wfd); + + helperStatefulDoGracefulClose(srv); } else { if (srv->queue.head) helperStatefulServerKickQueue(srv); @@ -1381,7 +1418,7 @@ if (selected && selected->stats.pending <= srv->stats.pending) continue; - if (srv->flags.shutdown) + if (srv->flags.shutdown || srv->flags.closing) continue; if (!srv->stats.pending) @@ -1424,7 +1461,7 @@ if (srv->flags.reserved == S_HELPER_RESERVED) continue; - if (srv->flags.shutdown) + if (srv->flags.shutdown || srv->flags.closing) continue; if ((hlp->IsAvailable != NULL) && (srv->data != NULL) && !(hlp->IsAvailable(srv->data))) @@ -1553,9 +1590,7 @@ if (srv->flags.shutdown && srv->flags.reserved == S_HELPER_FREE && !srv->deferred_requests) { - int wfd = srv->wfd; - srv->wfd = -1; - comm_close(wfd); + helperStatefulDoGracefulClose(srv); } else { if (srv->queue.head) helperStatefulServerKickQueue(srv);