From: robertc <> Date: Mon, 7 Aug 2006 08:28:22 +0000 (+0000) Subject: Create an explicit EventLoop class which can be used to run an event loop X-Git-Tag: SQUID_3_0_PRE5~196 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a553a5a35d4f6bf515fc77867e66276f42d04fe1;p=thirdparty%2Fsquid.git Create an explicit EventLoop class which can be used to run an event loop outside of main.cc - i.e. for test cases. Refactor the event module into two sections - EventScheduler which schedules events, and EventDispatcher which dispatches events unconditionally. Refactor the signal handling code in main to use an event dispatcher too, making the loop cleaner. --- diff --git a/src/AuthUser.cc b/src/AuthUser.cc index 70cf0fb1d1..bcf74576cd 100644 --- a/src/AuthUser.cc +++ b/src/AuthUser.cc @@ -1,6 +1,6 @@ /* - * $Id: AuthUser.cc,v 1.1 2004/08/30 03:28:56 robertc Exp $ + * $Id: AuthUser.cc,v 1.2 2006/08/07 02:28:22 robertc Exp $ * * DEBUG: section 29 Authenticator * AUTHOR: Robert Collins @@ -40,6 +40,7 @@ #include "AuthConfig.h" #include "authenticate.h" #include "ACL.h" +#include "event.h" #ifndef _USE_INLINE_ #include "AuthUser.cci" diff --git a/src/CommRead.h b/src/CommRead.h index 73cebbc03d..26eb71e0ed 100644 --- a/src/CommRead.h +++ b/src/CommRead.h @@ -1,6 +1,6 @@ /* - * $Id: CommRead.h,v 1.6 2004/02/18 01:58:59 adrian Exp $ + * $Id: CommRead.h,v 1.7 2006/08/07 02:28:22 robertc Exp $ * * DEBUG: section 5 Comms * AUTHOR: Robert Collins @@ -41,6 +41,7 @@ #define COMMREAD_H #include "squid.h" +#include "comm.h" #include "List.h" template diff --git a/src/CompletionDispatcher.cc b/src/CompletionDispatcher.cc new file mode 100644 index 0000000000..2917206c93 --- /dev/null +++ b/src/CompletionDispatcher.cc @@ -0,0 +1,34 @@ + +/* + * $Id: CompletionDispatcher.cc,v 1.1 2006/08/07 02:28:22 robertc Exp $ + * + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ + +#include "CompletionDispatcher.h" diff --git a/src/CompletionDispatcher.h b/src/CompletionDispatcher.h new file mode 100644 index 0000000000..3d49451bce --- /dev/null +++ b/src/CompletionDispatcher.h @@ -0,0 +1,55 @@ + +/* + * $Id: CompletionDispatcher.h,v 1.1 2006/08/07 02:28:22 robertc Exp $ + * + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ + +#ifndef SQUID_COMPLETIONDISPATCHER_H +#define SQUID_COMPLETIONDISPATCHER_H + +#include "squid.h" + + +/* Dispatch code to handle events that have completed. Completed events are queued + * with a completion dispatcher by the OS Async engine - i.e. the poll or kqueue or + * select loop, or a signal reciever, or the diskd/diskthreads/etc modules. + */ + +class CompletionDispatcher +{ + +public: + + virtual ~CompletionDispatcher() {} + + virtual void dispatch() = 0; +}; + +#endif /* SQUID_COMPLETIONDISPATCHER_H */ diff --git a/src/DiskIO/DiskThreads/aiops.cc b/src/DiskIO/DiskThreads/aiops.cc index 8507de608e..72d52fc208 100644 --- a/src/DiskIO/DiskThreads/aiops.cc +++ b/src/DiskIO/DiskThreads/aiops.cc @@ -1,5 +1,5 @@ /* - * $Id: aiops.cc,v 1.9 2006/05/23 18:24:41 wessels Exp $ + * $Id: aiops.cc,v 1.10 2006/08/07 02:28:22 robertc Exp $ * * DEBUG: section 43 AIOPS * AUTHOR: Stewart Forster @@ -52,6 +52,7 @@ #endif #include "CommIO.h" #include "SquidTime.h" +#include "Store.h" #define RIDICULOUS_LENGTH 4096 diff --git a/src/EventLoop.cc b/src/EventLoop.cc new file mode 100644 index 0000000000..23e85d5483 --- /dev/null +++ b/src/EventLoop.cc @@ -0,0 +1,125 @@ + +/* + * $Id: EventLoop.cc,v 1.1 2006/08/07 02:28:22 robertc Exp $ + * + * DEBUG: section 1 Main Loop + * AUTHOR: Harvest Derived + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ + +#include "squid.h" +#include "event.h" +#include "EventLoop.h" +#include "comm.h" + +EventLoop::EventLoop() : errcount(0), last_loop(false) +{} + +void +EventLoop::prepareToRun() +{ + last_loop = false; + errcount = 0; +} + +void +EventLoop::registerDispatcher(CompletionDispatcher *dispatcher) +{ + dispatchers.push_back(dispatcher); +} + +void +EventLoop::run() +{ + prepareToRun(); + + while (!last_loop) + runOnce(); +} + +void +EventLoop::runOnce() +{ + int loop_delay = EventScheduler::GetInstance()->checkEvents(); + + for (dispatcher_vector::iterator i = dispatchers.begin(); + i != dispatchers.end(); ++i) + (*i)->dispatch(); + + if (loop_delay < 0) + loop_delay = 0; + + switch (comm_select(loop_delay)) { + + case COMM_OK: + errcount = 0; /* reset if successful */ + break; + + case COMM_IDLE: + /* TODO: rather than busy loop, if everything has returned IDLE we should + * wait for a reasonable timeout period, - if everything returned IDLE + * then not only is there no work to do, there is no work coming in - + * all the comm loops have no fds registered, and all the other + * async engines have no work active or pending. + * ... perhaps we can have a query method to say 'when could there be + * work' - i.e. the event dispatcher can return the next event in its + * queue, and everything else can return -1. + */ + errcount = 0; + break; + + case COMM_ERROR: + errcount++; + debugs(1, 0, "Select loop Error. Retry " << errcount); + + if (errcount == 10) + fatal_dump("Select Loop failed 10 times.!"); + + break; + + case COMM_TIMEOUT: + break; + + case COMM_SHUTDOWN: + stop(); + + break; + + default: + fatal_dump("MAIN: Internal error -- this should never happen."); + + break; + } +} + +void +EventLoop::stop() +{ + last_loop = true; +} diff --git a/src/EventLoop.h b/src/EventLoop.h new file mode 100644 index 0000000000..c1cbd96bc5 --- /dev/null +++ b/src/EventLoop.h @@ -0,0 +1,78 @@ + +/* + * $Id: EventLoop.h,v 1.1 2006/08/07 02:28:22 robertc Exp $ + * + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ + +#ifndef SQUID_EVENTLOOP_H +#define SQUID_EVENTLOOP_H + +#include "squid.h" +#include "Array.h" +#include "CompletionDispatcher.h" + +/* An event loop. An event loop is the core inner loop of squid. + * The event loop can be run until exit, or once. After it finishes control + * returns to the caller. If desired it can be run again. + * + * The event loop cannot be run once it is running until it has finished. + */ + +class EventLoop +{ + +public: + EventLoop(); + /* register an event dispatcher to be invoked on each event loop. */ + void registerDispatcher(CompletionDispatcher *dispatcher); + /* start the event loop running */ + void run(); + /* run the loop once. This may not complete all events! It should therefor + * be used with care. + * TODO: signal in runOnce whether or not the loop is over - IDLE vs OK vs + * TIMEOUT? + */ + void runOnce(); + /* stop the event loop - it will finish the current loop and then return to the + * caller of run(). + */ + void stop(); + +private: + /* setup state variables prior to running */ + void prepareToRun(); + int errcount; + bool last_loop; + typedef Vector dispatcher_vector; + dispatcher_vector dispatchers; +}; + + +#endif /* SQUID_EVENTLOOP_H */ diff --git a/src/ICAP/ICAPConfig.h b/src/ICAP/ICAPConfig.h index 007835c579..3fb81d7009 100644 --- a/src/ICAP/ICAPConfig.h +++ b/src/ICAP/ICAPConfig.h @@ -1,6 +1,6 @@ /* - * $Id: ICAPConfig.h,v 1.8 2006/04/28 05:05:47 wessels Exp $ + * $Id: ICAPConfig.h,v 1.9 2006/08/07 02:28:24 robertc Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -36,6 +36,7 @@ #ifndef SQUID_ICAPCONFIG_H #define SQUID_ICAPCONFIG_H +#include "event.h" #include "ICAPServiceRep.h" class acl_access; diff --git a/src/ICAP/ICAPXaction.h b/src/ICAP/ICAPXaction.h index b43c5ab2b3..b37194e1d2 100644 --- a/src/ICAP/ICAPXaction.h +++ b/src/ICAP/ICAPXaction.h @@ -1,6 +1,6 @@ /* - * $Id: ICAPXaction.h,v 1.6 2006/01/09 20:38:44 wessels Exp $ + * $Id: ICAPXaction.h,v 1.7 2006/08/07 02:28:24 robertc Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -34,6 +34,7 @@ #ifndef SQUID_ICAPXACTION_H #define SQUID_ICAPXACTION_H +#include "comm.h" #include "MemBuf.h" #include "ICAPServiceRep.h" diff --git a/src/ICAP/MsgPipe.h b/src/ICAP/MsgPipe.h index 3f38bcc56d..a4938fba5d 100644 --- a/src/ICAP/MsgPipe.h +++ b/src/ICAP/MsgPipe.h @@ -1,6 +1,6 @@ /* - * $Id: MsgPipe.h,v 1.3 2005/12/22 22:26:31 wessels Exp $ + * $Id: MsgPipe.h,v 1.4 2006/08/07 02:28:24 robertc Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -34,6 +34,7 @@ #ifndef SQUID_MSGPIPE_H #define SQUID_MSGPIPE_H +#include "event.h" // MsgPipe is a unidirectional communication channel for asynchronously // transmitting potentially large messages. It aggregates the message diff --git a/src/Makefile.am b/src/Makefile.am index 08160bfcac..03bc25dbee 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ # # Makefile for the Squid Object Cache server # -# $Id: Makefile.am,v 1.158 2006/07/15 21:15:19 serassio Exp $ +# $Id: Makefile.am,v 1.159 2006/08/07 02:28:22 robertc Exp $ # # Uncomment and customize the following to suit your needs: # @@ -402,6 +402,8 @@ squid_SOURCES = \ clientStream.cc \ clientStream.h \ CommIO.h \ + CompletionDispatcher.cc \ + CompletionDispatcher.h \ $(squid_COMMSOURCES) \ CommRead.h \ ConfigOption.cc \ @@ -421,6 +423,9 @@ squid_SOURCES = \ $(ESI_SOURCE) \ ETag.cc \ event.cc \ + event.h \ + EventLoop.h \ + EventLoop.cc \ external_acl.cc \ ExternalACL.h \ ExternalACLEntry.cc \ @@ -1053,6 +1058,8 @@ check_PROGRAMS+= \ tests/testACLMaxUserIP \ tests/testBoilerplate \ tests/testCacheManager \ + tests/testEvent \ + tests/testEventLoop \ tests/testHeaders \ tests/test_http_range \ tests/testHttpRequest \ @@ -1192,6 +1199,7 @@ tests_testCacheManager_SOURCES = \ mem.cc \ String.cc \ tests/testCacheManager.cc \ + tests/testCacheManager.h \ tests/testMain.cc \ time.cc \ access_log.cc \ @@ -1329,6 +1337,303 @@ tests_testCacheManager_DEPENDENCIES = $(top_builddir)/lib/libmiscutil.a \ @SQUID_CPPUNIT_LA@ \ @ICAP_LIBS@ +## Tests of the Even module. +tests_testEvent_SOURCES = \ + debug.cc \ + EventLoop.h \ + EventLoop.cc \ + globals.cc \ + HttpRequest.cc \ + HttpRequestMethod.cc \ + mem.cc \ + String.cc \ + tests/testEvent.cc \ + tests/testEvent.h \ + tests/testMain.cc \ + time.cc \ + access_log.cc \ + acl.cc \ + acl_noncore.cc \ + ACLChecklist.cc \ + ACLProxyAuth.cc \ + ACLStringData.cc \ + ACLRegexData.cc \ + ACLUserData.cc \ + authenticate.cc \ + BodyReader.cc \ + cache_manager.cc \ + cache_cf.cc \ + CacheDigest.cc \ + carp.cc \ + cbdata.cc \ + client_db.cc \ + client_side.cc \ + client_side_reply.cc \ + client_side_request.cc \ + clientStream.cc \ + $(squid_COMMSOURCES) \ + ConfigOption.cc \ + ConfigParser.cc \ + $(DELAY_POOL_SOURCE) \ + disk.cc \ + $(DNSSOURCE) \ + event.cc \ + errorpage.cc \ + $(ESI_SOURCE) \ + ETag.cc \ + external_acl.cc \ + ExternalACLEntry.cc \ + fd.cc \ + fde.cc \ + forward.cc \ + fqdncache.cc \ + ftp.cc \ + gopher.cc \ + helper.cc \ + $(HTCPSOURCE) \ + http.cc \ + HttpBody.cc \ + HttpHeader.cc \ + HttpHeaderTools.cc \ + HttpHdrCc.cc \ + HttpHdrContRange.cc \ + HttpHdrRange.cc \ + HttpHdrSc.cc \ + HttpHdrScTarget.cc \ + HttpMsg.cc \ + HttpReply.cc \ + HttpStatusLine.cc \ + icmp.cc \ + icp_v2.cc \ + icp_v3.cc \ + $(IDENT_SOURCE) \ + ipc.cc \ + ipcache.cc \ + int.cc \ + internal.cc \ + list.cc \ + logfile.cc \ + multicast.cc \ + mem_node.cc \ + MemBuf.cc \ + MemObject.cc \ + mime.cc \ + neighbors.cc \ + net_db.cc \ + Packer.cc \ + Parsing.cc \ + pconn.cc \ + peer_digest.cc \ + peer_select.cc \ + redirect.cc \ + referer.cc \ + refresh.cc \ + Server.cc \ + $(SNMP_SOURCE) \ + $(SSL_SOURCE) \ + stat.cc \ + StatHist.cc \ + stmem.cc \ + store.cc \ + store_client.cc \ + store_digest.cc \ + store_dir.cc \ + store_io.cc \ + store_key_md5.cc \ + store_log.cc \ + store_rebuild.cc \ + store_swapin.cc \ + store_swapmeta.cc \ + store_swapout.cc \ + StoreFileSystem.cc \ + StoreIOState.cc \ + StoreMeta.cc \ + StoreMetaMD5.cc \ + StoreMetaSTD.cc \ + StoreMetaUnpacker.cc \ + StoreMetaURL.cc \ + StoreMetaVary.cc \ + StoreSwapLogData.cc \ + tools.cc \ + tunnel.cc \ + SwapDir.cc \ + url.cc \ + URLScheme.cc \ + urn.cc \ + useragent.cc \ + wais.cc \ + wccp2.cc \ + whois.cc \ + wordlist.cc +nodist_tests_testEvent_SOURCES = \ + repl_modules.cc \ + string_arrays.c +tests_testEvent_LDADD = \ + libsquid.la \ + libauth.la \ + @REPL_OBJS@ \ + @ICAP_LIBS@ \ + @REGEXLIB@ \ + @SSLLIB@ \ + -L../lib -lmiscutil \ + @XTRA_LIBS@ \ + @SQUID_CPPUNIT_LIBS@ \ + @SQUID_CPPUNIT_LA@ \ + @SNMPLIB@ +tests_testEvent_LDFLAGS = $(LIBADD_DL) +tests_testEvent_DEPENDENCIES = $(top_builddir)/lib/libmiscutil.a \ + @REPL_OBJS@ \ + @SQUID_CPPUNIT_LA@ \ + @ICAP_LIBS@ + +## Tests of the EventLoop module. +tests_testEventLoop_SOURCES = \ + debug.cc \ + EventLoop.h \ + EventLoop.cc \ + globals.cc \ + HttpRequest.cc \ + HttpRequestMethod.cc \ + mem.cc \ + String.cc \ + tests/testEventLoop.cc \ + tests/testEventLoop.h \ + tests/testMain.cc \ + time.cc \ + access_log.cc \ + acl.cc \ + acl_noncore.cc \ + ACLChecklist.cc \ + ACLProxyAuth.cc \ + ACLStringData.cc \ + ACLRegexData.cc \ + ACLUserData.cc \ + authenticate.cc \ + BodyReader.cc \ + cache_manager.cc \ + cache_cf.cc \ + CacheDigest.cc \ + carp.cc \ + cbdata.cc \ + client_db.cc \ + client_side.cc \ + client_side_reply.cc \ + client_side_request.cc \ + clientStream.cc \ + $(squid_COMMSOURCES) \ + ConfigOption.cc \ + ConfigParser.cc \ + $(DELAY_POOL_SOURCE) \ + disk.cc \ + $(DNSSOURCE) \ + event.cc \ + errorpage.cc \ + $(ESI_SOURCE) \ + ETag.cc \ + external_acl.cc \ + ExternalACLEntry.cc \ + fd.cc \ + fde.cc \ + forward.cc \ + fqdncache.cc \ + ftp.cc \ + gopher.cc \ + helper.cc \ + $(HTCPSOURCE) \ + http.cc \ + HttpBody.cc \ + HttpHeader.cc \ + HttpHeaderTools.cc \ + HttpHdrCc.cc \ + HttpHdrContRange.cc \ + HttpHdrRange.cc \ + HttpHdrSc.cc \ + HttpHdrScTarget.cc \ + HttpMsg.cc \ + HttpReply.cc \ + HttpStatusLine.cc \ + icmp.cc \ + icp_v2.cc \ + icp_v3.cc \ + $(IDENT_SOURCE) \ + ipc.cc \ + ipcache.cc \ + int.cc \ + internal.cc \ + list.cc \ + logfile.cc \ + multicast.cc \ + mem_node.cc \ + MemBuf.cc \ + MemObject.cc \ + mime.cc \ + neighbors.cc \ + net_db.cc \ + Packer.cc \ + Parsing.cc \ + pconn.cc \ + peer_digest.cc \ + peer_select.cc \ + redirect.cc \ + referer.cc \ + refresh.cc \ + Server.cc \ + $(SNMP_SOURCE) \ + $(SSL_SOURCE) \ + stat.cc \ + StatHist.cc \ + stmem.cc \ + store.cc \ + store_client.cc \ + store_digest.cc \ + store_dir.cc \ + store_io.cc \ + store_key_md5.cc \ + store_log.cc \ + store_rebuild.cc \ + store_swapin.cc \ + store_swapmeta.cc \ + store_swapout.cc \ + StoreFileSystem.cc \ + StoreIOState.cc \ + StoreMeta.cc \ + StoreMetaMD5.cc \ + StoreMetaSTD.cc \ + StoreMetaUnpacker.cc \ + StoreMetaURL.cc \ + StoreMetaVary.cc \ + StoreSwapLogData.cc \ + tools.cc \ + tunnel.cc \ + SwapDir.cc \ + url.cc \ + URLScheme.cc \ + urn.cc \ + useragent.cc \ + wais.cc \ + wccp2.cc \ + whois.cc \ + wordlist.cc +nodist_tests_testEventLoop_SOURCES = \ + repl_modules.cc \ + string_arrays.c +tests_testEventLoop_LDADD = \ + libsquid.la \ + libauth.la \ + @REPL_OBJS@ \ + @ICAP_LIBS@ \ + @REGEXLIB@ \ + @SSLLIB@ \ + -L../lib -lmiscutil \ + @XTRA_LIBS@ \ + @SQUID_CPPUNIT_LIBS@ \ + @SQUID_CPPUNIT_LA@ \ + @SNMPLIB@ +tests_testEventLoop_LDFLAGS = $(LIBADD_DL) +tests_testEventLoop_DEPENDENCIES = $(top_builddir)/lib/libmiscutil.a \ + @REPL_OBJS@ \ + @SQUID_CPPUNIT_LA@ \ + @ICAP_LIBS@ ## test headers checks that individual headers can be parsed with no dependencies. ## as such, it needs a new .cc file for each header it parses, so that they @@ -1338,13 +1643,18 @@ tests_testCacheManager_DEPENDENCIES = $(top_builddir)/lib/libmiscutil.a \ ## RBC 20060422. HEADERS_TO_TEST = \ tests/testHeader_ACL.cc \ + tests/testHeader_CompletionDispatcher.cc \ tests/testHeader_ConfigParser.cc \ tests/testHeader_client_side_request.cc \ + tests/testHeader_comm.cc \ tests/testHeader_dlink.cc \ + tests/testHeader_event.cc \ + tests/testHeader_EventLoop.cc \ tests/testHeader_HttpHeader.cc \ tests/testHeader_HttpHeaderRange.cc \ tests/testHeader_HttpReply.cc \ tests/testHeader_HttpRequestMethod.cc \ + tests/testHeader_Store.cc \ tests/testHeader_StoreEntryStream.cc \ tests/testHeader_URL.cc \ tests/testHeader_URLScheme.cc \ diff --git a/src/ProfStats.cc b/src/ProfStats.cc index 1e593ea2fb..4035bb1380 100644 --- a/src/ProfStats.cc +++ b/src/ProfStats.cc @@ -1,6 +1,6 @@ /* - * $Id: ProfStats.cc,v 1.7 2006/05/29 00:15:01 robertc Exp $ + * $Id: ProfStats.cc,v 1.8 2006/08/07 02:28:22 robertc Exp $ * * DEBUG: section 81 CPU Profiling Routines * AUTHOR: Andres Kroonmaa @@ -34,6 +34,7 @@ */ #include "squid.h" +#include "event.h" #include "CacheManager.h" #ifdef USE_XPROF_STATS diff --git a/src/auth/digest/auth_digest.cc b/src/auth/digest/auth_digest.cc index 8bb38de918..e79a57e46a 100644 --- a/src/auth/digest/auth_digest.cc +++ b/src/auth/digest/auth_digest.cc @@ -1,6 +1,6 @@ /* - * $Id: auth_digest.cc,v 1.47 2006/07/07 19:10:29 serassio Exp $ + * $Id: auth_digest.cc,v 1.48 2006/08/07 02:28:24 robertc Exp $ * * DEBUG: section 29 Authenticator * AUTHOR: Robert Collins @@ -42,6 +42,7 @@ #include "rfc2617.h" #include "auth_digest.h" #include "authenticate.h" +#include "event.h" #include "CacheManager.h" #include "Store.h" #include "HttpRequest.h" diff --git a/src/client_db.cc b/src/client_db.cc index 77193d9569..25e879870c 100644 --- a/src/client_db.cc +++ b/src/client_db.cc @@ -1,6 +1,6 @@ /* - * $Id: client_db.cc,v 1.66 2006/05/29 00:15:01 robertc Exp $ + * $Id: client_db.cc,v 1.67 2006/08/07 02:28:22 robertc Exp $ * * DEBUG: section 0 Client Database * AUTHOR: Duane Wessels @@ -34,6 +34,7 @@ */ #include "squid.h" +#include "event.h" #include "CacheManager.h" #include "SquidTime.h" #include "Store.h" diff --git a/src/client_side.h b/src/client_side.h index 60db5e7260..a100aead7d 100644 --- a/src/client_side.h +++ b/src/client_side.h @@ -1,6 +1,6 @@ /* - * $Id: client_side.h,v 1.16 2006/06/06 19:22:13 hno Exp $ + * $Id: client_side.h,v 1.17 2006/08/07 02:28:22 robertc Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -34,6 +34,7 @@ #ifndef SQUID_CLIENTSIDE_H #define SQUID_CLIENTSIDE_H +#include "comm.h" #include "StoreIOBuffer.h" #include "BodyReader.h" #include "RefCount.h" diff --git a/src/comm.cc b/src/comm.cc index 5eefe49dc3..8df6963b29 100644 --- a/src/comm.cc +++ b/src/comm.cc @@ -1,6 +1,6 @@ /* - * $Id: comm.cc,v 1.419 2006/05/30 21:15:58 wessels Exp $ + * $Id: comm.cc,v 1.420 2006/08/07 02:28:22 robertc Exp $ * * DEBUG: section 5 Socket Functions * AUTHOR: Harvest Derived @@ -38,8 +38,10 @@ #include "squid.h" #include "StoreIOBuffer.h" #include "comm.h" +#include "event.h" #include "fde.h" #include "CommIO.h" +#include "CommRead.h" #include "ConnectionDetail.h" #include "MemBuf.h" #include "pconn.h" diff --git a/src/comm.h b/src/comm.h index 652cca9fb0..dd91d402be 100644 --- a/src/comm.h +++ b/src/comm.h @@ -1,11 +1,88 @@ #ifndef __COMM_H__ #define __COMM_H__ +#include "squid.h" #include "StoreIOBuffer.h" #include "Array.h" +typedef enum { + COMM_OK = 0, + COMM_ERROR = -1, + COMM_NOMESSAGE = -3, + COMM_TIMEOUT = -4, + COMM_SHUTDOWN = -5, + COMM_IDLE = -6, /* there are no active fds and no pending callbacks. */ + COMM_INPROGRESS = -7, + COMM_ERR_CONNECT = -8, + COMM_ERR_DNS = -9, + COMM_ERR_CLOSING = -10, +} comm_err_t; typedef void IOFCB(int fd, StoreIOBuffer recievedData, comm_err_t flag, int xerrno, void *data); typedef void IOWCB(int fd, char *buffer, size_t len, comm_err_t flag, int xerrno, void *data); + +typedef void CWCB(int fd, char *, size_t size, comm_err_t flag, void *data); +typedef void CNCB(int fd, comm_err_t status, int xerrno, void *data); + +typedef void IOCB(int fd, char *, size_t size, comm_err_t flag, int xerrno, void *data); + +struct _CommWriteStateData +{ + char *buf; + size_t size; + off_t offset; + CWCB *handler; + void *handler_data; + FREE *free_func; +}; + +/* comm.c */ +extern void comm_calliocallback(void); +extern bool comm_iocallbackpending(void); /* inline candidate */ + +extern int comm_listen(int fd); +SQUIDCEXTERN int commSetNonBlocking(int fd); +SQUIDCEXTERN int commUnsetNonBlocking(int fd); +SQUIDCEXTERN void commSetCloseOnExec(int fd); +extern void _comm_close(int fd, char const *file, int line); +#define comm_close(fd) (_comm_close((fd), __FILE__, __LINE__)) +SQUIDCEXTERN void comm_reset_close(int fd); +#if LINGERING_CLOSE +SQUIDCEXTERN void comm_lingering_close(int fd); +#endif +SQUIDCEXTERN void commConnectStart(int fd, const char *, u_short, CNCB *, void *); + +SQUIDCEXTERN int comm_connect_addr(int sock, const struct sockaddr_in *); +SQUIDCEXTERN void comm_init(void); + +SQUIDCEXTERN int comm_open(int, int, struct IN_ADDR, u_short port, int, const char *note); + +SQUIDCEXTERN int comm_openex(int, int, struct IN_ADDR, u_short, int, unsigned char TOS, const char *); +SQUIDCEXTERN u_short comm_local_port(int fd); + +SQUIDCEXTERN void commSetSelect(int, unsigned int, PF *, void *, time_t); + +SQUIDCEXTERN int comm_udp_sendto(int, const struct sockaddr_in *, int, const void *, int); +SQUIDCEXTERN void comm_old_write(int fd, + const char *buf, + int size, + CWCB * handler, + void *handler_data, + FREE *); +SQUIDCEXTERN void comm_old_write_mbuf(int fd, MemBuf *mb, CWCB * handler, void *handler_data); +SQUIDCEXTERN void commCallCloseHandlers(int fd); +SQUIDCEXTERN int commSetTimeout(int fd, int, PF *, void *); +SQUIDCEXTERN int ignoreErrno(int); +SQUIDCEXTERN void commCloseAllSockets(void); +SQUIDCEXTERN void checkTimeouts(void); + + +/* + * comm_select.c + */ +SQUIDCEXTERN void comm_select_init(void); +SQUIDCEXTERN comm_err_t comm_select(int); +SQUIDCEXTERN void comm_quick_poll_required(void); + /* fill sb with up to length data from fd */ extern void comm_fill_immediate(int fd, StoreIOBuffer sb, IOFCB *callback, void *data); @@ -27,7 +104,6 @@ extern int comm_udp_recv(int fd, void *buf, size_t len, int flags); extern ssize_t comm_udp_send(int s, const void *buf, size_t len, int flags); extern void comm_write(int s, const char *buf, size_t len, IOWCB *callback, void *callback_data); -#include "Store.h" extern void commMarkHalfClosed(int); extern int commIsHalfClosed(int); extern void commCheckHalfClosed(void *); diff --git a/src/comm_poll.cc b/src/comm_poll.cc index 086dd990df..eca9f8a636 100644 --- a/src/comm_poll.cc +++ b/src/comm_poll.cc @@ -1,6 +1,6 @@ /* - * $Id: comm_poll.cc,v 1.16 2006/05/29 00:15:02 robertc Exp $ + * $Id: comm_poll.cc,v 1.17 2006/08/07 02:28:22 robertc Exp $ * * DEBUG: section 5 Socket Functions * @@ -424,11 +424,6 @@ comm_select(int msec) PROF_stop(comm_poll_prep_pfds); - if (nfds == 0) { - assert(shutting_down); - return COMM_SHUTDOWN; - } - if (comm_iocallbackpending()) npending++; @@ -438,6 +433,14 @@ comm_select(int msec) if (msec > MAX_POLL_TIME) msec = MAX_POLL_TIME; + /* nothing to do */ + if (nfds == 0 && !npending) { + if (shutting_down) + return COMM_SHUTDOWN; + else + return COMM_IDLE; + } + for (;;) { PROF_start(comm_poll_normal); statCounter.syscalls.polls++; diff --git a/src/delay_pools.cc b/src/delay_pools.cc index 8ef73b5f9f..7a8cbaca08 100644 --- a/src/delay_pools.cc +++ b/src/delay_pools.cc @@ -1,6 +1,6 @@ /* - * $Id: delay_pools.cc,v 1.46 2006/05/29 00:15:02 robertc Exp $ + * $Id: delay_pools.cc,v 1.47 2006/08/07 02:28:22 robertc Exp $ * * DEBUG: section 77 Delay Pools * AUTHOR: Robert Collins @@ -44,6 +44,7 @@ #include "CacheManager.h" #include "DelaySpec.h" #include "DelayPools.h" +#include "event.h" #include "StoreClient.h" #include "Store.h" #include "MemObject.h" diff --git a/src/dns_internal.cc b/src/dns_internal.cc index 17e2d83972..9640da8435 100644 --- a/src/dns_internal.cc +++ b/src/dns_internal.cc @@ -1,6 +1,6 @@ /* - * $Id: dns_internal.cc,v 1.90 2006/07/24 19:21:26 serassio Exp $ + * $Id: dns_internal.cc,v 1.91 2006/08/07 02:28:22 robertc Exp $ * * DEBUG: section 78 DNS lookups; interacts with lib/rfc1035.c * AUTHOR: Duane Wessels @@ -35,6 +35,7 @@ #include "config.h" #include "squid.h" +#include "event.h" #include "CacheManager.h" #include "SquidTime.h" #include "Store.h" diff --git a/src/enums.h b/src/enums.h index fdeedcdcb6..a3c2eba08b 100644 --- a/src/enums.h +++ b/src/enums.h @@ -1,6 +1,6 @@ /* - * $Id: enums.h,v 1.252 2006/06/07 22:39:34 hno Exp $ + * $Id: enums.h,v 1.253 2006/08/07 02:28:22 robertc Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -542,18 +542,6 @@ typedef enum { DIGEST_READ_DONE } digest_read_state_t; -typedef enum { - COMM_OK = 0, - COMM_ERROR = -1, - COMM_NOMESSAGE = -3, - COMM_TIMEOUT = -4, - COMM_SHUTDOWN = -5, - COMM_INPROGRESS = -6, - COMM_ERR_CONNECT = -7, - COMM_ERR_DNS = -8, - COMM_ERR_CLOSING = -9 -} comm_err_t; - /* Distinguish between Request and Reply (for header mangling) */ enum { ROR_REQUEST, diff --git a/src/event.cc b/src/event.cc index eac403efbd..3deb693794 100644 --- a/src/event.cc +++ b/src/event.cc @@ -1,6 +1,6 @@ /* - * $Id: event.cc,v 1.40 2006/08/06 06:26:27 robertc Exp $ + * $Id: event.cc,v 1.41 2006/08/07 02:28:22 robertc Exp $ * * DEBUG: section 41 Event Processing * AUTHOR: Henrik Nordstrom @@ -33,59 +33,23 @@ * */ -#include "squid.h" +#include "event.h" #include "CacheManager.h" #include "Store.h" /* The list of event processes */ -class ev_entry -{ - -public: - MEMPROXY_CLASS(ev_entry); - EVH *func; - void *arg; - const char *name; - double when; - - struct ev_entry *next; - int weight; - int id; - bool cbdata; -}; -MEMPROXY_CLASS_INLINE(ev_entry); - -static struct ev_entry *tasks = NULL; static OBJH eventDump; -static int run_id = 0; static const char *last_event_ran = NULL; +ev_entry::ev_entry(char const * name, EVH * func, void * arg, double when, int weight, bool cbdata) : name(name), func(func), arg(cbdata ? cbdataReference(arg) : arg), when(when), weight(weight), cbdata(cbdata) +{} + void eventAdd(const char *name, EVH * func, void *arg, double when, int weight, bool cbdata) { - - struct ev_entry *event = new ev_entry; - - struct ev_entry **E; - event->func = func; - event->arg = cbdata ? cbdataReference(arg) : arg; - event->name = name; - event->when = current_dtime + when; - event->weight = weight; - event->id = run_id; - event->cbdata = cbdata; - debug(41, 7) ("eventAdd: Adding '%s', in %f seconds\n", name, when); - /* Insert after the last event with the same or earlier time */ - - for (E = &tasks; *E; E = &(*E)->next) { - if ((*E)->when > event->when) - break; - } - - event->next = *E; - *E = event; + EventScheduler::GetInstance()->schedule(name, func, arg, when, weight, cbdata); } /* same as eventAdd but adds a random offset within +-1/3 of delta_ish */ @@ -107,10 +71,90 @@ eventAddIsh(const char *name, EVH * func, void *arg, double delta_ish, int weigh void eventDelete(EVH * func, void *arg) { + EventScheduler::GetInstance()->cancel(func, arg); +} - struct ev_entry **E; +void +eventInit(CacheManager &manager) +{ + manager.registerAction("events", "Event Queue", eventDump, 0, 1); +} - struct ev_entry *event; +static void +eventDump(StoreEntry * sentry) +{ + EventScheduler::GetInstance()->dump(sentry); +} + +void +eventFreeMemory(void) +{ + EventScheduler::GetInstance()->clean(); +} + +int +eventFind(EVH * func, void *arg) +{ + return EventScheduler::GetInstance()->find(func, arg); +} + +EventDispatcher EventDispatcher::_instance; + +EventDispatcher::EventDispatcher() +{} + +void + +EventDispatcher::add + (ev_entry * event) +{ + queue.push_back(event); +} + +void +EventDispatcher::dispatch() +{ + for (Vector::iterator i = queue.begin(); i != queue.end(); ++i) { + ev_entry * event = *i; + EVH *callback; + void *cbdata = event->arg; + callback = event->func; + event->func = NULL; + + if (!event->cbdata || cbdataReferenceValidDone(event->arg, &cbdata)) { + /* XXX assumes ->name is static memory! */ + last_event_ran = event->name; + debugs(41, 5, "EventDispatcher::dispatch: Running '" << event->name << "'"); + callback(cbdata); + } + + delete event; + } + + queue.clean(); +} + +EventDispatcher * +EventDispatcher::GetInstance() +{ + return &_instance; +} + +EventScheduler EventScheduler::_instance(EventDispatcher::GetInstance()); + +EventScheduler::EventScheduler(EventDispatcher *dispatcher) : dispatcher(dispatcher), tasks(NULL) +{} + +EventScheduler::~EventScheduler() +{ + clean(); +} + +void +EventScheduler::cancel(EVH * func, void *arg) +{ + ev_entry **E; + ev_entry *event; for (E = &tasks; (event = *E) != NULL; E = &(*E)->next) { if (event->func != func) @@ -132,76 +176,68 @@ eventDelete(EVH * func, void *arg) debug_trap("eventDelete: event not found"); } -void -eventRun(void) +int +EventScheduler::checkDelay() +{ + if (!tasks) + return (int) 10; + + return (int) ((tasks->when - current_dtime) * 1000); +} + +int +EventScheduler::checkEvents() { struct ev_entry *event = NULL; - int weight = 0; if (NULL == tasks) - return; + return checkDelay(); if (tasks->when > current_dtime) - return; + return checkDelay(); PROF_start(eventRun); - run_id++; - - debug(41, 5) ("eventRun: RUN ID %d\n", run_id); + debugs(41, 5, "eventRun: \n"); while ((event = tasks)) { - EVH *callback; - void *cbdata = event->arg; - if (event->when > current_dtime) break; - if (event->id == run_id) /* was added during this run */ - break; - - if (weight) - break; + dispatcher->add + (event); tasks = event->next; - callback = event->func; - - event->func = NULL; - - if (!event->cbdata || cbdataReferenceValidDone(event->arg, &cbdata)) { - weight += event->weight; - /* XXX assumes ->name is static memory! */ - last_event_ran = event->name; - debug(41, 5) ("eventRun: Running '%s', id %d\n", - event->name, event->id); - callback(cbdata); - } - - delete event; + if (!event->cbdata || cbdataReferenceValid(event->arg)) + if (event->weight) + /* this event is marked as being 'heavy', so dont dequeue any others. + */ + break; } PROF_stop(eventRun); + return checkDelay(); } -int -eventNextTime(void) +void +EventScheduler::clean() { - if (!tasks) - return (int) 10; + while (ev_entry * event = tasks) { + tasks = event->next; - return (int) ((tasks->when - current_dtime) * 1000); -} + if (event->cbdata) + cbdataReferenceDone(event->arg); -void -eventInit(CacheManager &manager) -{ - manager.registerAction("events", "Event Queue", eventDump, 0, 1); + delete event; + } + + tasks = NULL; } -static void -eventDump(StoreEntry * sentry) +void +EventScheduler::dump(StoreEntry * sentry) { struct ev_entry *e = tasks; @@ -223,34 +259,41 @@ eventDump(StoreEntry * sentry) } } -void -eventFreeMemory(void) +bool +EventScheduler::find(EVH * func, void * arg) { struct ev_entry *event; - while ((event = tasks)) { - tasks = event->next; - - if (event->cbdata) - cbdataReferenceDone(event->arg); - - delete event; + for (event = tasks; event != NULL; event = event->next) { + if (event->func == func && event->arg == arg) + return true; } - tasks = NULL; + return false; } -int -eventFind(EVH * func, void *arg) +EventScheduler * +EventScheduler::GetInstance() { + return &_instance; +} - struct ev_entry *event; +void +EventScheduler::schedule(const char *name, EVH * func, void *arg, double when, int weight, bool cbdata) +{ - for (event = tasks; event != NULL; event = event->next) { - if (event->func == func && event->arg == arg) - return 1; + struct ev_entry *event = new ev_entry(name, func, arg, current_dtime + when, weight, cbdata); + + struct ev_entry **E; + debugs(41, 7, "eventAdd: Adding '" << name << "', in " << when << " seconds"); + /* Insert after the last event with the same or earlier time */ + + for (E = &tasks; *E; E = &(*E)->next) { + if ((*E)->when > event->when) + break; } - return 0; + event->next = *E; + *E = event; } diff --git a/src/event.h b/src/event.h new file mode 100644 index 0000000000..2831feb89c --- /dev/null +++ b/src/event.h @@ -0,0 +1,128 @@ + +/* + * $Id: event.h,v 1.1 2006/08/07 02:28:22 robertc Exp $ + * + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ + +#ifndef SQUID_EVENT_H +#define SQUID_EVENT_H + +#include "squid.h" +#include "Array.h" +#include "CompletionDispatcher.h" + +/* forward decls */ + +class StoreEntry; + +/* event scheduling facilities - run a callback after a given time period. */ + +typedef void EVH(void *); + +extern void eventAdd(const char *name, EVH * func, void *arg, double when, int, bool cbdata=true); +SQUIDCEXTERN void eventAddIsh(const char *name, EVH * func, void *arg, double delta_ish, int); +SQUIDCEXTERN void eventDelete(EVH * func, void *arg); +SQUIDCEXTERN void eventInit(CacheManager &); +SQUIDCEXTERN void eventFreeMemory(void); +SQUIDCEXTERN int eventFind(EVH *, void *); + +class ev_entry +{ + +public: + ev_entry(char const * name, EVH * func, void *arg, double when, int weight, bool cbdata=true); + MEMPROXY_CLASS(ev_entry); + const char *name; + EVH *func; + void *arg; + double when; + + int weight; + bool cbdata; + + struct ev_entry *next; +}; + +MEMPROXY_CLASS_INLINE(ev_entry); + +class EventDispatcher : public CompletionDispatcher +{ + +public: + EventDispatcher(); + /* add an event to dequeue when dispatch is called */ + + void add + (ev_entry *); + + /* add an event to be dispatched in the future */ + void add + (const char *name, EVH * func, void *arg, double when, int, bool cbdata=true); + + void dispatch(); + + static EventDispatcher *GetInstance(); + +private: + Vector queue; + + static EventDispatcher _instance; +}; + +class EventScheduler +{ + +public: + /* Create an event scheduler that will hand its ready to run callbacks to + * an EventDispatcher */ + EventScheduler(EventDispatcher *); + ~EventScheduler(); + /* cancel a scheduled but not dispatched event */ + void cancel(EVH * func, void * arg); + /* clean up the used memory in the scheduler */ + void clean(); + /* how long until the next event ? */ + int checkDelay(); + /* cache manager output for the event queue */ + void dump(StoreEntry *); + /* find a scheduled event */ + bool find(EVH * func, void * arg); + /* schedule a callback function to run in when seconds */ + void schedule(const char *name, EVH * func, void *arg, double when, int weight, bool cbdata=true); + int checkEvents(); + static EventScheduler *GetInstance(); + +private: + static EventScheduler _instance; + EventDispatcher * dispatcher; + ev_entry * tasks; +}; + +#endif /* SQUID_EVENT_H */ diff --git a/src/forward.cc b/src/forward.cc index f3f9fcd68a..fac0684f6d 100644 --- a/src/forward.cc +++ b/src/forward.cc @@ -1,6 +1,6 @@ /* - * $Id: forward.cc,v 1.146 2006/06/19 22:49:59 hno Exp $ + * $Id: forward.cc,v 1.147 2006/08/07 02:28:22 robertc Exp $ * * DEBUG: section 17 Request Forwarding * AUTHOR: Duane Wessels @@ -35,6 +35,7 @@ #include "squid.h" +#include "event.h" #include "CacheManager.h" #include "forward.h" #include "SquidTime.h" diff --git a/src/forward.h b/src/forward.h index cfc0543a09..9cf06cc65d 100644 --- a/src/forward.h +++ b/src/forward.h @@ -5,6 +5,8 @@ class CacheManager; +#include "comm.h" + class FwdServer { diff --git a/src/fqdncache.cc b/src/fqdncache.cc index efa7e5192d..19862cf89e 100644 --- a/src/fqdncache.cc +++ b/src/fqdncache.cc @@ -1,6 +1,6 @@ /* - * $Id: fqdncache.cc,v 1.168 2006/05/29 00:15:02 robertc Exp $ + * $Id: fqdncache.cc,v 1.169 2006/08/07 02:28:22 robertc Exp $ * * DEBUG: section 35 FQDN Cache * AUTHOR: Harvest Derived @@ -34,6 +34,7 @@ */ #include "squid.h" +#include "event.h" #include "CacheManager.h" #include "SquidTime.h" #include "Store.h" diff --git a/src/fs/coss/store_dir_coss.cc b/src/fs/coss/store_dir_coss.cc index 081b62dbaa..53d6722cfd 100644 --- a/src/fs/coss/store_dir_coss.cc +++ b/src/fs/coss/store_dir_coss.cc @@ -1,6 +1,6 @@ /* - * $Id: store_dir_coss.cc,v 1.64 2006/08/05 15:37:21 hno Exp $ + * $Id: store_dir_coss.cc,v 1.65 2006/08/07 02:28:25 robertc Exp $ * vim: set et : * * DEBUG: section 47 Store COSS Directory Routines @@ -39,6 +39,7 @@ #include "Store.h" #include "store_coss.h" +#include "event.h" #include "fde.h" #include "SwapDir.h" #include "StoreSwapLogData.h" diff --git a/src/fs/null/store_null.cc b/src/fs/null/store_null.cc index 25bfee64a6..a46b8d7b50 100644 --- a/src/fs/null/store_null.cc +++ b/src/fs/null/store_null.cc @@ -1,6 +1,6 @@ /* - * $Id: store_null.cc,v 1.9 2006/05/23 00:48:13 wessels Exp $ + * $Id: store_null.cc,v 1.10 2006/08/07 02:28:25 robertc Exp $ * * DEBUG: section 47 Store Directory Routines * AUTHOR: Duane Wessels @@ -34,6 +34,7 @@ */ #include "squid.h" +#include "event.h" #if HAVE_STATVFS #if HAVE_SYS_STATVFS_H #include diff --git a/src/fs/ufs/ufscommon.h b/src/fs/ufs/ufscommon.h index 49b22f920e..c537f61f58 100644 --- a/src/fs/ufs/ufscommon.h +++ b/src/fs/ufs/ufscommon.h @@ -1,6 +1,6 @@ /* - * $Id: ufscommon.h,v 1.7 2006/05/31 17:47:53 wessels Exp $ + * $Id: ufscommon.h,v 1.8 2006/08/07 02:28:26 robertc Exp $ * * SQUID Web Proxy Cache http://www.squid-cache.org/ * ---------------------------------------------------------- @@ -34,6 +34,7 @@ #define SQUID_UFSCOMMON_H #include "squid.h" +#include "event.h" #define DefaultLevelOneDirs 16 #define DefaultLevelTwoDirs 256 diff --git a/src/ipcache.cc b/src/ipcache.cc index 41c47b0e57..165da8d183 100644 --- a/src/ipcache.cc +++ b/src/ipcache.cc @@ -1,6 +1,6 @@ /* - * $Id: ipcache.cc,v 1.255 2006/05/29 00:15:02 robertc Exp $ + * $Id: ipcache.cc,v 1.256 2006/08/07 02:28:22 robertc Exp $ * * DEBUG: section 14 IP Cache * AUTHOR: Harvest Derived @@ -34,6 +34,7 @@ */ #include "squid.h" +#include "event.h" #include "CacheManager.h" #include "SquidTime.h" #include "Store.h" diff --git a/src/main.cc b/src/main.cc index 380b0979ad..c829130bb3 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,6 +1,6 @@ /* - * $Id: main.cc,v 1.427 2006/07/02 16:53:46 serassio Exp $ + * $Id: main.cc,v 1.428 2006/08/07 02:28:22 robertc Exp $ * * DEBUG: section 1 Startup and Main Loop * AUTHOR: Harvest Derived @@ -38,6 +38,8 @@ #include "authenticate.h" #include "CacheManager.h" #include "ConfigParser.h" +#include "event.h" +#include "EventLoop.h" #include "ExternalACL.h" #include "Store.h" #include "ICP.h" @@ -126,6 +128,59 @@ static const char *squid_start_script = "squid_start"; #include "test_access.c" #endif +class SignalDispatcher : public CompletionDispatcher +{ + +public: + SignalDispatcher(EventLoop &loop) : loop(loop) {} + + void addEventLoop(EventLoop * loop); + virtual void dispatch(); + +private: + static void StopEventLoop(void * data) + { + static_cast(data)->loop.stop(); + } + + EventLoop &loop; +}; + +void +SignalDispatcher::dispatch() +{ + if (do_reconfigure) { + mainReconfigure(); + do_reconfigure = 0; +#if defined(_SQUID_MSWIN_) && defined(_DEBUG) + + } else if (do_debug_trap) { + do_debug_trap = 0; + __asm int 3; +#endif + + } else if (do_rotate) { + mainRotate(); + do_rotate = 0; + } else if (do_shutdown) { + time_t wait = do_shutdown > 0 ? (int) Config.shutdownLifetime : 0; + debug(1, 1) ("Preparing for shutdown after %d requests\n", + statCounter.client_http.requests); + debug(1, 1) ("Waiting %d seconds for active connections to finish\n", + (int) wait); + do_shutdown = 0; + shutting_down = 1; +#if USE_WIN32_SERVICE + + WIN32_svcstatusupdate(SERVICE_STOP_PENDING, (wait + 1) * 1000); +#endif + + serverConnectionsClose(); + //eventAdd("SquidShutdown", StopEventLoop, this, (double) (wait + 1), 1, false); + eventAdd("SquidShutdown", SquidShutdown, NULL, (double) (wait + 1), 1, false); + } +} + static void usage(void) { @@ -1014,7 +1069,6 @@ int main(int argc, char **argv) #endif { - int errcount = 0; mode_t oldmask; #ifdef _SQUID_WIN32_ @@ -1238,41 +1292,17 @@ main(int argc, char **argv) #endif /* main loop */ + EventLoop mainLoop; - for (;;) - { - if (do_reconfigure) { - mainReconfigure(); - do_reconfigure = 0; -#if defined(_SQUID_MSWIN_) && defined(_DEBUG) - - } else if (do_debug_trap) { - do_debug_trap = 0; - __asm int 3; -#endif - - } else if (do_rotate) { - mainRotate(); - do_rotate = 0; - } else if (do_shutdown) { - time_t wait = do_shutdown > 0 ? (int) Config.shutdownLifetime : 0; - debug(1, 1) ("Preparing for shutdown after %d requests\n", - statCounter.client_http.requests); - debug(1, 1) ("Waiting %d seconds for active connections to finish\n", - (int) wait); - do_shutdown = 0; - shutting_down = 1; -#if USE_WIN32_SERVICE - - WIN32_svcstatusupdate(SERVICE_STOP_PENDING, (wait + 1) * 1000); -#endif + SignalDispatcher signal_dispatcher(mainLoop); - serverConnectionsClose(); - eventAdd("SquidShutdown", SquidShutdown, NULL, (double) (wait + 1), 1); - } + mainLoop.registerDispatcher(&signal_dispatcher); - eventRun(); + /* TODO: stop requiring the singleton here */ + mainLoop.registerDispatcher(EventDispatcher::GetInstance()); + for (;;) + { /* Attempt any pending storedir IO * Note: the storedir is roughly a reactor of its own. */ @@ -1288,39 +1318,7 @@ main(int argc, char **argv) if (comm_iocallbackpending()) comm_calliocallback(); - int loop_delay = eventNextTime(); - - if (loop_delay < 0) - loop_delay = 0; - - switch (comm_select(loop_delay)) { - - case COMM_OK: - errcount = 0; /* reset if successful */ - break; - - case COMM_ERROR: - errcount++; - debug(1, 0) ("Select loop Error. Retry %d\n", errcount); - - if (errcount == 10) - fatal_dump("Select Loop failed!"); - - break; - - case COMM_TIMEOUT: - break; - - case COMM_SHUTDOWN: - SquidShutdown(NULL); - - break; - - default: - fatal_dump("MAIN: Internal error -- this should never happen."); - - break; - } + mainLoop.runOnce(); } /* NOTREACHED */ @@ -1490,7 +1488,6 @@ watch_child(char *argv[]) #endif - /* * RBCOLLINS - if cygwin stackdumps when squid is run without * -N, check the cygwin1.dll version, it needs to be AT LEAST diff --git a/src/mem.cc b/src/mem.cc index 6cf6441559..3446dee3d0 100644 --- a/src/mem.cc +++ b/src/mem.cc @@ -1,6 +1,6 @@ /* - * $Id: mem.cc,v 1.98 2006/05/29 00:15:02 robertc Exp $ + * $Id: mem.cc,v 1.99 2006/08/07 02:28:22 robertc Exp $ * * DEBUG: section 13 High Level Memory Pool Management * AUTHOR: Harvest Derived @@ -38,6 +38,7 @@ #include #include +#include "event.h" #include "CacheManager.h" #include "Mem.h" #include "memMeter.h" diff --git a/src/neighbors.cc b/src/neighbors.cc index 9f31cd2597..4b90ec4979 100644 --- a/src/neighbors.cc +++ b/src/neighbors.cc @@ -1,6 +1,6 @@ /* - * $Id: neighbors.cc,v 1.338 2006/07/25 18:22:37 hno Exp $ + * $Id: neighbors.cc,v 1.339 2006/08/07 02:28:22 robertc Exp $ * * DEBUG: section 15 Neighbor Routines * AUTHOR: Harvest Derived @@ -34,6 +34,7 @@ */ #include "squid.h" +#include "event.h" #include "CacheManager.h" #include "Store.h" #include "ICP.h" diff --git a/src/net_db.cc b/src/net_db.cc index 7e83d727df..794febee33 100644 --- a/src/net_db.cc +++ b/src/net_db.cc @@ -1,6 +1,6 @@ /* - * $Id: net_db.cc,v 1.189 2006/05/29 00:15:02 robertc Exp $ + * $Id: net_db.cc,v 1.190 2006/08/07 02:28:22 robertc Exp $ * * DEBUG: section 38 Network Measurement Database * AUTHOR: Duane Wessels @@ -42,6 +42,7 @@ */ #include "squid.h" +#include "event.h" #include "CacheManager.h" #include "Store.h" #include "SwapDir.h" diff --git a/src/peer_digest.cc b/src/peer_digest.cc index 54768d8491..184694222b 100644 --- a/src/peer_digest.cc +++ b/src/peer_digest.cc @@ -1,6 +1,6 @@ /* - * $Id: peer_digest.cc,v 1.116 2006/06/18 08:56:33 serassio Exp $ + * $Id: peer_digest.cc,v 1.117 2006/08/07 02:28:22 robertc Exp $ * * DEBUG: section 72 Peer Digest Routines * AUTHOR: Alex Rousskov @@ -36,6 +36,7 @@ #include "squid.h" #if USE_CACHE_DIGESTS +#include "event.h" #include "Store.h" #include "HttpRequest.h" #include "HttpReply.h" diff --git a/src/peer_select.cc b/src/peer_select.cc index 3d8ae69429..3bd17444bb 100644 --- a/src/peer_select.cc +++ b/src/peer_select.cc @@ -1,6 +1,6 @@ /* - * $Id: peer_select.cc,v 1.140 2006/05/19 17:19:10 wessels Exp $ + * $Id: peer_select.cc,v 1.141 2006/08/07 02:28:22 robertc Exp $ * * DEBUG: section 44 Peer Selection Algorithm * AUTHOR: Duane Wessels @@ -34,6 +34,7 @@ */ #include "squid.h" +#include "event.h" #include "PeerSelectState.h" #include "Store.h" #include "ICP.h" diff --git a/src/protos.h b/src/protos.h index d3871ed8fe..2f61364ec2 100644 --- a/src/protos.h +++ b/src/protos.h @@ -1,6 +1,6 @@ /* - * $Id: protos.h,v 1.534 2006/07/02 16:53:46 serassio Exp $ + * $Id: protos.h,v 1.535 2006/08/07 02:28:22 robertc Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -117,55 +117,6 @@ SQUIDCEXTERN void httpRequestFree(void *); extern void clientAccessCheck(void *); -/* comm.c */ -extern void comm_calliocallback(void); -extern bool comm_iocallbackpending(void); /* inline candidate */ - -extern int comm_listen(int fd); -SQUIDCEXTERN int commSetNonBlocking(int fd); -SQUIDCEXTERN int commUnsetNonBlocking(int fd); -SQUIDCEXTERN void commSetCloseOnExec(int fd); -extern void _comm_close(int fd, char const *file, int line); -#define comm_close(fd) (_comm_close((fd), __FILE__, __LINE__)) -SQUIDCEXTERN void comm_reset_close(int fd); -#if LINGERING_CLOSE -SQUIDCEXTERN void comm_lingering_close(int fd); -#endif -SQUIDCEXTERN void commConnectStart(int fd, const char *, u_short, CNCB *, void *); - -SQUIDCEXTERN int comm_connect_addr(int sock, const struct sockaddr_in *); -SQUIDCEXTERN void comm_init(void); - -SQUIDCEXTERN int comm_open(int, int, struct IN_ADDR, u_short port, int, const char *note); - -SQUIDCEXTERN int comm_openex(int, int, struct IN_ADDR, u_short, int, unsigned char TOS, const char *); -SQUIDCEXTERN u_short comm_local_port(int fd); - -SQUIDCEXTERN void commSetSelect(int, unsigned int, PF *, void *, time_t); - -SQUIDCEXTERN int comm_udp_sendto(int, const struct sockaddr_in *, int, const void *, int); -SQUIDCEXTERN void comm_old_write(int fd, - const char *buf, - int size, - CWCB * handler, - void *handler_data, - FREE *); -SQUIDCEXTERN void comm_old_write_mbuf(int fd, MemBuf *mb, CWCB * handler, void *handler_data); -SQUIDCEXTERN void commCallCloseHandlers(int fd); -SQUIDCEXTERN int commSetTimeout(int fd, int, PF *, void *); -SQUIDCEXTERN int ignoreErrno(int); -SQUIDCEXTERN void commCloseAllSockets(void); -SQUIDCEXTERN void checkTimeouts(void); - - -/* - * comm_select.c - */ -SQUIDCEXTERN void comm_select_init(void); -SQUIDCEXTERN comm_err_t comm_select(int); -SQUIDCEXTERN void comm_quick_poll_required(void); - - /* see debug.c for info on context-based debugging */ SQUIDCEXTERN Ctx ctx_enter(const char *descr); SQUIDCEXTERN void ctx_exit(Ctx ctx); @@ -214,15 +165,6 @@ SQUIDCEXTERN void idnsALookup(const char *, IDNSCB *, void *); SQUIDCEXTERN void idnsPTRLookup(const struct IN_ADDR, IDNSCB *, void *); -extern void eventAdd(const char *name, EVH * func, void *arg, double when, int, bool cbdata=true); -SQUIDCEXTERN void eventAddIsh(const char *name, EVH * func, void *arg, double delta_ish, int); -SQUIDCEXTERN void eventRun(void); -SQUIDCEXTERN int eventNextTime(void); -SQUIDCEXTERN void eventDelete(EVH * func, void *arg); -SQUIDCEXTERN void eventInit(CacheManager &); -SQUIDCEXTERN void eventFreeMemory(void); -SQUIDCEXTERN int eventFind(EVH *, void *); - SQUIDCEXTERN void fd_close(int fd); SQUIDCEXTERN void fd_open(int fd, unsigned int type, const char *); SQUIDCEXTERN void fd_note(int fd, const char *); @@ -253,7 +195,7 @@ SQUIDCEXTERN const char *fqdnFromAddr(struct IN_ADDR); SQUIDCEXTERN int fqdncacheQueueDrain(void); SQUIDCEXTERN void fqdncacheFreeMemory(void); SQUIDCEXTERN void fqdncache_restart(void); -SQUIDCEXTERN EVH fqdncache_purgelru; +SQUIDCEXTERN void fqdncache_purgelru(void *); SQUIDCEXTERN void fqdncacheAddEntryFromHosts(char *addr, wordlist * hostnames); class FwdState; @@ -393,7 +335,7 @@ extern void wccp2ConnectionClose(void); SQUIDCEXTERN void ipcache_nbgethostbyname(const char *name, IPH * handler, void *handlerData); -SQUIDCEXTERN EVH ipcache_purgelru; +SQUIDCEXTERN void ipcache_purgelru(void *); SQUIDCEXTERN const ipcache_addrs *ipcache_gethostbyname(const char *, int flags); SQUIDCEXTERN void ipcacheInvalidate(const char *); SQUIDCEXTERN void ipcacheInvalidateNegative(const char *); @@ -453,7 +395,7 @@ SQUIDCEXTERN peer *peerFindByNameAndPort(const char *, unsigned short); SQUIDCEXTERN peer *getDefaultParent(HttpRequest * request); SQUIDCEXTERN peer *getRoundRobinParent(HttpRequest * request); SQUIDCEXTERN peer *getWeightedRoundRobinParent(HttpRequest * request); -SQUIDCEXTERN EVH peerClearRR; +SQUIDCEXTERN void peerClearRR(void *); SQUIDCEXTERN peer *getAnyParent(HttpRequest * request); SQUIDCEXTERN lookup_t peerDigestLookup(peer * p, HttpRequest * request); SQUIDCEXTERN peer *neighborsDigestSelect(HttpRequest * request); @@ -485,7 +427,7 @@ SQUIDCEXTERN void netdbUpdatePeer(HttpRequest *, peer * e, int rtt, int hops); SQUIDCEXTERN void netdbDeleteAddrNetwork(struct IN_ADDR addr); SQUIDCEXTERN void netdbBinaryExchange(StoreEntry *); -SQUIDCEXTERN EVH netdbExchangeStart; +SQUIDCEXTERN void netdbExchangeStart(void *); SQUIDCEXTERN void netdbExchangeUpdatePeer(struct IN_ADDR, peer *, double, double); SQUIDCEXTERN peer *netdbClosestParent(HttpRequest *); diff --git a/src/send-announce.cc b/src/send-announce.cc index 8abb86e0d5..bb7839f0d9 100644 --- a/src/send-announce.cc +++ b/src/send-announce.cc @@ -1,6 +1,6 @@ /* - * $Id: send-announce.cc,v 1.66 2006/05/08 23:38:33 robertc Exp $ + * $Id: send-announce.cc,v 1.67 2006/08/07 02:28:22 robertc Exp $ * * DEBUG: section 27 Cache Announcer * AUTHOR: Duane Wessels @@ -34,6 +34,7 @@ */ #include "squid.h" +#include "event.h" #include "fde.h" #include "SquidTime.h" diff --git a/src/stat.cc b/src/stat.cc index ce6ae3a59d..e7dcd0b0ed 100644 --- a/src/stat.cc +++ b/src/stat.cc @@ -1,5 +1,5 @@ /* - * $Id: stat.cc,v 1.396 2006/07/08 16:38:07 serassio Exp $ + * $Id: stat.cc,v 1.397 2006/08/07 02:28:22 robertc Exp $ * * DEBUG: section 18 Cache Manager Statistics * AUTHOR: Harvest Derived @@ -33,6 +33,7 @@ */ #include "squid.h" +#include "event.h" #include "StoreClient.h" #include "AuthUserRequest.h" #include "CacheManager.h" diff --git a/src/store.cc b/src/store.cc index 3dba7b8820..126dcc1c5b 100644 --- a/src/store.cc +++ b/src/store.cc @@ -1,6 +1,6 @@ /* - * $Id: store.cc,v 1.596 2006/05/29 00:15:02 robertc Exp $ + * $Id: store.cc,v 1.597 2006/08/07 02:28:22 robertc Exp $ * * DEBUG: section 20 Storage Manager * AUTHOR: Harvest Derived @@ -34,6 +34,7 @@ */ #include "squid.h" +#include "event.h" #include "Store.h" #include "CacheManager.h" #include "StoreClient.h" diff --git a/src/store_client.cc b/src/store_client.cc index 2a15b1968d..3c11fbe14f 100644 --- a/src/store_client.cc +++ b/src/store_client.cc @@ -1,6 +1,6 @@ /* - * $Id: store_client.cc,v 1.146 2006/05/23 00:30:21 wessels Exp $ + * $Id: store_client.cc,v 1.147 2006/08/07 02:28:22 robertc Exp $ * * DEBUG: section 90 Storage Manager Client-Side Interface * AUTHOR: Duane Wessels @@ -35,6 +35,7 @@ */ #include "squid.h" +#include "event.h" #include "StoreClient.h" #include "Store.h" #include "HttpReply.h" diff --git a/src/store_digest.cc b/src/store_digest.cc index d10d93240b..f2a7885421 100644 --- a/src/store_digest.cc +++ b/src/store_digest.cc @@ -1,6 +1,6 @@ /* - * $Id: store_digest.cc,v 1.68 2006/05/29 21:44:18 robertc Exp $ + * $Id: store_digest.cc,v 1.69 2006/08/07 02:28:22 robertc Exp $ * * DEBUG: section 71 Store Digest Manager * AUTHOR: Alex Rousskov @@ -41,6 +41,7 @@ */ #include "squid.h" +#include "event.h" #include "CacheManager.h" #if USE_CACHE_DIGESTS diff --git a/src/store_rebuild.cc b/src/store_rebuild.cc index 64889398e3..4997b40a8d 100644 --- a/src/store_rebuild.cc +++ b/src/store_rebuild.cc @@ -1,6 +1,6 @@ /* - * $Id: store_rebuild.cc,v 1.84 2006/05/19 20:22:56 wessels Exp $ + * $Id: store_rebuild.cc,v 1.85 2006/08/07 02:28:22 robertc Exp $ * * DEBUG: section 20 Store Rebuild Routines * AUTHOR: Duane Wessels @@ -34,6 +34,7 @@ */ #include "squid.h" +#include "event.h" #include "Store.h" #include "SwapDir.h" #include "StoreSearch.h" diff --git a/src/structs.h b/src/structs.h index e4ed04e37b..dbecfd81c2 100644 --- a/src/structs.h +++ b/src/structs.h @@ -1,6 +1,6 @@ /* - * $Id: structs.h,v 1.545 2006/07/31 13:17:57 serassio Exp $ + * $Id: structs.h,v 1.546 2006/08/07 02:28:22 robertc Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -1531,16 +1531,6 @@ unsigned int ignore_auth: flags; }; -struct _CommWriteStateData -{ - char *buf; - size_t size; - off_t offset; - CWCB *handler; - void *handler_data; - FREE *free_func; -}; - struct _ErrorState { err_type type; diff --git a/src/tests/CapturingStoreEntry.h b/src/tests/CapturingStoreEntry.h new file mode 100644 index 0000000000..b992020482 --- /dev/null +++ b/src/tests/CapturingStoreEntry.h @@ -0,0 +1,39 @@ +#ifndef SQUID_TESTS_CAPTURINGSTORE_ENTRY_H +#define SQUID_TESTS_CAPTURINGSTORE_ENTRY_H + +#include "Mem.h" +#include "Store.h" + +/* class that captures various call data for test analysis */ + +class CapturingStoreEntry : public StoreEntry +{ + +public: + MEMPROXY_CLASS(CapturingStoreEntry); + + CapturingStoreEntry() : _buffer_calls(0), _flush_calls(0) {} + + String _appended_text; + int _buffer_calls; + int _flush_calls; + + virtual void buffer() + { + _buffer_calls += 1; + } + + virtual void flush() + { + _flush_calls += 1; + } + + virtual void append(char const * buf, int len) + { + _appended_text.append(buf, len); + } +}; + +MEMPROXY_CLASS_INLINE(CapturingStoreEntry); + +#endif diff --git a/src/tests/stub_comm.cc b/src/tests/stub_comm.cc index a92b7267e7..156beccb60 100644 --- a/src/tests/stub_comm.cc +++ b/src/tests/stub_comm.cc @@ -1,5 +1,5 @@ /* - * $Id: stub_comm.cc,v 1.1 2005/01/03 16:08:27 robertc Exp $ + * $Id: stub_comm.cc,v 1.2 2006/08/07 02:28:26 robertc Exp $ * * DEBUG: section 84 Helper process maintenance * AUTHOR: Robert Collins @@ -34,6 +34,7 @@ #include "squid.h" #include "comm.h" +#include "CommRead.h" #include "fde.h" DeferredReadManager::~DeferredReadManager() diff --git a/src/tests/testCoss.cc b/src/tests/testCoss.cc index 61b2911093..501422ff2e 100644 --- a/src/tests/testCoss.cc +++ b/src/tests/testCoss.cc @@ -172,10 +172,11 @@ testCoss::testCossSearch() /* ok, ready to use */ Store::Root().init(); - /* ensure rebuilding finishes */ + /* ensure rebuilding finishes - run a mini event loop */ while (store_dirs_rebuilding > 1) { getCurrentTime(); - eventRun(); + EventScheduler::GetInstance()->checkEvents(); + EventDispatcher::GetInstance()->dispatch(); } /* nothing to rebuild */ diff --git a/src/tests/testEvent.cc b/src/tests/testEvent.cc new file mode 100644 index 0000000000..b00be3301b --- /dev/null +++ b/src/tests/testEvent.cc @@ -0,0 +1,156 @@ +#include "squid.h" +#include + +#include "CapturingStoreEntry.h" +#include "CompletionDispatcher.h" +#include "Mem.h" +#include "testEvent.h" +#include "event.h" + + +CPPUNIT_TEST_SUITE_REGISTRATION( testEvent ); + +/* stub functions to link successfully */ +void +shut_down(int) +{} + +/* end stubs */ + +/* init legacy static-initialized modules */ + +struct Initer +{ + Initer() + { + Mem::Init(); + statInit(); + } +}; + +static Initer ensure_mempools; + +/* + * Test creating a EventDispatcher and Scheduler + */ +void +testEvent::testCreate() +{ + EventDispatcher dispatcher = EventDispatcher(); + EventScheduler scheduler = EventScheduler(&dispatcher); +} + + +/* Helper for tests - an event which records the number of calls it recieved. */ + +struct CalledEvent +{ + CalledEvent() : calls(0) {} + + static void Handler(void *data) + { + static_cast(data)->calls++; + } + + int calls; +}; + +/* do a trivial test of invoking callbacks */ +void +testEvent::testDispatch() +{ + EventDispatcher dispatcher; + CalledEvent event; + dispatcher.add(new ev_entry("test event", CalledEvent::Handler, &event, 0, 0, false)); + dispatcher.dispatch(); + dispatcher.dispatch(); + CPPUNIT_ASSERT_EQUAL(1, event.calls); +} + +/* submit two callbacks, and cancel one, then dispatch and only the other should run. + */ +void +testEvent::testCancel() +{ + EventDispatcher dispatcher; + EventScheduler scheduler(&dispatcher); + CalledEvent event; + CalledEvent event_to_cancel; + scheduler.schedule("test event", CalledEvent::Handler, &event, 0, 0, false); + scheduler.schedule("test event2", CalledEvent::Handler, &event_to_cancel, 0, 0, false); + scheduler.cancel(CalledEvent::Handler, &event_to_cancel); + scheduler.checkEvents(); + dispatcher.dispatch(); + CPPUNIT_ASSERT_EQUAL(1, event.calls); + CPPUNIT_ASSERT_EQUAL(0, event_to_cancel.calls); +} + +/* submit two callbacks, and then dump the queue. + */ +void +testEvent::testDump() +{ + EventDispatcher dispatcher; + EventScheduler scheduler(&dispatcher); + CalledEvent event; + CalledEvent event2; + CapturingStoreEntry * anEntry = new CapturingStoreEntry(); + scheduler.schedule("last event", CalledEvent::Handler, &event, 0, 0, false); + /* schedule and dispatch to set the last run event */ + scheduler.checkEvents(); + dispatcher.dispatch(); + scheduler.schedule("test event", CalledEvent::Handler, &event, 0, 0, false); + scheduler.schedule("test event2", CalledEvent::Handler, &event2, 0, 0, false); + scheduler.dump(anEntry); + CPPUNIT_ASSERT_EQUAL(String( + "Last event to run: last event\n" + "\n" + "Operation\tNext Execution\tWeight\tCallback Valid?\n" + "test event\t0.000000 seconds\t0\tN/A\n" + "test event2\t0.000000 seconds\t0\tN/A\n" + ), anEntry->_appended_text); + delete anEntry; +} + +/* submit two callbacks, and find the right one. + */ +void +testEvent::testFind() +{ + EventDispatcher dispatcher; + EventScheduler scheduler(&dispatcher); + CalledEvent event; + CalledEvent event_to_find; + scheduler.schedule("test event", CalledEvent::Handler, &event, 0, 0, false); + scheduler.schedule("test event2", CalledEvent::Handler, &event_to_find, 0, 0, false); + CPPUNIT_ASSERT_EQUAL(true, scheduler.find(CalledEvent::Handler, &event_to_find)); +} + +/* do a trivial test of invoking callbacks */ +void +testEvent::testCheckEvents() +{ + EventDispatcher dispatcher; + EventScheduler scheduler(&dispatcher); + CalledEvent event; + CPPUNIT_ASSERT_EQUAL(10, scheduler.checkEvents()); + /* event running now gets sent to the dispatcher and the delay is set to 10ms */ + scheduler.schedule("test event", CalledEvent::Handler, &event, 0, 0, false); + CPPUNIT_ASSERT_EQUAL(10, scheduler.checkEvents()); + dispatcher.dispatch(); + /* event running later results in a delay of the time till it runs */ + scheduler.schedule("test event", CalledEvent::Handler, &event, 2, 0, false); + CPPUNIT_ASSERT_EQUAL(2000, scheduler.checkEvents()); + dispatcher.dispatch(); + CPPUNIT_ASSERT_EQUAL(1, event.calls); +} + +/* for convenience we have a singleton scheduler and dispatcher*/ +void +testEvent::testSingleton() +{ + EventScheduler *scheduler = dynamic_cast(EventScheduler::GetInstance()); + CPPUNIT_ASSERT(NULL != scheduler); + EventDispatcher *dispatcher = dynamic_cast(EventDispatcher::GetInstance()); + CPPUNIT_ASSERT(NULL != dispatcher); +} diff --git a/src/tests/testEvent.h b/src/tests/testEvent.h new file mode 100644 index 0000000000..6fa0b8e4a5 --- /dev/null +++ b/src/tests/testEvent.h @@ -0,0 +1,36 @@ + +#ifndef SQUID_SRC_TEST_EVENT_H +#define SQUID_SRC_TEST_EVENT_H + +#include + +/* + * test the event module. + */ + +class testEvent : public CPPUNIT_NS::TestFixture +{ + CPPUNIT_TEST_SUITE( testEvent ); + CPPUNIT_TEST( testCreate ); + CPPUNIT_TEST( testDispatch ); + CPPUNIT_TEST( testDump ); + CPPUNIT_TEST( testFind ); + CPPUNIT_TEST( testCheckEvents ); + CPPUNIT_TEST( testSingleton ); + CPPUNIT_TEST( testCancel ); + CPPUNIT_TEST_SUITE_END(); + +public: + +protected: + void testCreate(); + void testDispatch(); + void testDump(); + void testFind(); + void testCheckEvents(); + void testSingleton(); + void testCancel(); +}; + +#endif + diff --git a/src/tests/testEventLoop.cc b/src/tests/testEventLoop.cc new file mode 100644 index 0000000000..2a28bfbf2b --- /dev/null +++ b/src/tests/testEventLoop.cc @@ -0,0 +1,109 @@ +#include "squid.h" +#include + +#include "CompletionDispatcher.h" +#include "Mem.h" +#include "testEventLoop.h" +#include "EventLoop.h" + + +CPPUNIT_TEST_SUITE_REGISTRATION( testEventLoop ); + +/* stub functions to link successfully */ +void +shut_down(int) +{} + +/* end stubs */ + +/* init legacy static-initialized modules */ + +struct Initer +{ + Initer() + { + Mem::Init(); + statInit(); + } +}; + +static Initer ensure_mempools; + +/* + * Test creating a EventLoop + */ +void +testEventLoop::testCreate() +{ + EventLoop(); +} + + +/* + * Running the loop once is useful for integration with other loops, such as + * migrating to it in incrementally. + * + * This test works by having a customer dispatcher which records how many times its + * called. + */ + +class RecordDispatcher : public CompletionDispatcher +{ + +public: + int calls; + RecordDispatcher(): calls(0) + {} + + void dispatch() + { + ++calls; + } +}; + +void +testEventLoop::testRunOnce() +{ + EventLoop theLoop; + RecordDispatcher dispatcher; + theLoop.registerDispatcher(&dispatcher); + theLoop.runOnce(); + CPPUNIT_ASSERT_EQUAL(1, dispatcher.calls); +} + +/* + * completion dispatchers registered with the event loop are invoked by the event + * loop. + * + * This test works by having a customer dispatcher which shuts the loop down once its + * been invoked twice. + * + * It also tests that loop.run() and loop.stop() work, because if they dont work, + * this test will either hang, or fail. + */ + +class ShutdownDispatcher : public CompletionDispatcher +{ + +public: + EventLoop &theLoop; + int calls; + ShutdownDispatcher(EventLoop & theLoop):theLoop(theLoop), calls(0) + {} + + void dispatch() + { + if (++calls == 2) + theLoop.stop(); + } +}; + +void +testEventLoop::testRegisterDispatcher() +{ + EventLoop theLoop; + ShutdownDispatcher testDispatcher(theLoop); + theLoop.registerDispatcher(&testDispatcher); + theLoop.run(); + CPPUNIT_ASSERT_EQUAL(2, testDispatcher.calls); +} diff --git a/src/tests/testEventLoop.h b/src/tests/testEventLoop.h new file mode 100644 index 0000000000..6aa0f1d193 --- /dev/null +++ b/src/tests/testEventLoop.h @@ -0,0 +1,28 @@ + +#ifndef SQUID_SRC_TEST_EVENTLOOP_H +#define SQUID_SRC_TEST_EVENTLOOP_H + +#include + +/* + * test the EventLoop implementation + */ + +class testEventLoop : public CPPUNIT_NS::TestFixture +{ + CPPUNIT_TEST_SUITE( testEventLoop ); + CPPUNIT_TEST( testCreate ); + CPPUNIT_TEST( testRunOnce ); + CPPUNIT_TEST( testRegisterDispatcher ); + CPPUNIT_TEST_SUITE_END(); + +public: + +protected: + void testCreate(); + void testRunOnce(); + void testRegisterDispatcher(); +}; + +#endif + diff --git a/src/tests/testHeader_CompletionDispatcher.cc b/src/tests/testHeader_CompletionDispatcher.cc new file mode 100644 index 0000000000..b901721311 --- /dev/null +++ b/src/tests/testHeader_CompletionDispatcher.cc @@ -0,0 +1,4 @@ +/* This test tests that the header below can be processed on its own with + * no other #includes. Dont add any! + */ +#include "CompletionDispatcher.h" diff --git a/src/tests/testHeader_EventLoop.cc b/src/tests/testHeader_EventLoop.cc new file mode 100644 index 0000000000..f4ad807c3e --- /dev/null +++ b/src/tests/testHeader_EventLoop.cc @@ -0,0 +1,4 @@ +/* This test tests that the header below can be processed on its own with + * no other #includes. Dont add any! + */ +#include "EventLoop.h" diff --git a/src/tests/testHeader_Store.cc b/src/tests/testHeader_Store.cc new file mode 100644 index 0000000000..9ce27b4a33 --- /dev/null +++ b/src/tests/testHeader_Store.cc @@ -0,0 +1,4 @@ +/* This test tests that the header below can be processed on its own with + * no other #includes. Dont add any! + */ +#include "Store.h" diff --git a/src/tests/testHeader_comm.cc b/src/tests/testHeader_comm.cc new file mode 100644 index 0000000000..d2fa3fa15d --- /dev/null +++ b/src/tests/testHeader_comm.cc @@ -0,0 +1,4 @@ +/* This test tests that the header below can be processed on its own with + * no other #includes. Dont add any! + */ +#include "comm.h" diff --git a/src/tests/testHeader_event.cc b/src/tests/testHeader_event.cc new file mode 100644 index 0000000000..ecc40c4c9b --- /dev/null +++ b/src/tests/testHeader_event.cc @@ -0,0 +1,4 @@ +/* This test tests that the header below can be processed on its own with + * no other #includes. Dont add any! + */ +#include "event.h" diff --git a/src/tests/testNull.cc b/src/tests/testNull.cc index adfa19c91a..cbd932e5de 100644 --- a/src/tests/testNull.cc +++ b/src/tests/testNull.cc @@ -140,11 +140,12 @@ testNull::testNullSearch() /* ok, ready to use */ Store::Root().init(); - /* ensure rebuilding finishes */ + /* ensure rebuilding finishes - run a mini event loop */ while (store_dirs_rebuilding > 1) { getCurrentTime(); - eventRun(); + EventScheduler::GetInstance()->checkEvents(); + EventDispatcher::GetInstance()->dispatch(); } /* nothing to rebuild */ diff --git a/src/tests/testStoreEntryStream.cc b/src/tests/testStoreEntryStream.cc index b8f458b39e..69d51ab171 100644 --- a/src/tests/testStoreEntryStream.cc +++ b/src/tests/testStoreEntryStream.cc @@ -2,6 +2,7 @@ #include "Mem.h" #include "testStore.h" #include "testStoreEntryStream.h" +#include "CapturingStoreEntry.h" #include "Store.h" #include "StoreEntryStream.h" @@ -11,39 +12,6 @@ CPPUNIT_TEST_SUITE_REGISTRATION( testStoreEntryStream ); -/* class that captures various call data for test analysis */ - -class CapturingStoreEntry : public StoreEntry -{ - -public: - MEMPROXY_CLASS(CapturingStoreEntry); - - CapturingStoreEntry() : _buffer_calls(0), _flush_calls(0) {} - - String _appended_text; - int _buffer_calls; - int _flush_calls; - - virtual void buffer() - { - _buffer_calls += 1; - } - - virtual void flush() - { - _flush_calls += 1; - } - - virtual void append(char const * buf, int len) - { - _appended_text.append(buf, len); - } -}; - -MEMPROXY_CLASS_INLINE(CapturingStoreEntry); - - /* init memory pools */ struct Initer diff --git a/src/tests/testString.cc b/src/tests/testString.cc index 0f63e26cac..09659ddd2b 100644 --- a/src/tests/testString.cc +++ b/src/tests/testString.cc @@ -1,4 +1,5 @@ #include "squid.h" +#include "event.h" #include "Mem.h" #include "SquidString.h" #include "testString.h" diff --git a/src/tests/testUfs.cc b/src/tests/testUfs.cc index 2c1beb0b2f..3fd15da110 100644 --- a/src/tests/testUfs.cc +++ b/src/tests/testUfs.cc @@ -106,10 +106,11 @@ testUfs::testUfsSearch() /* ok, ready to use - init store & hash too */ Store::Root().init(); - /* ensure rebuilding finishes */ + /* ensure rebuilding finishes - run a mini event loop */ while (store_dirs_rebuilding > 1) { getCurrentTime(); - eventRun(); + EventScheduler::GetInstance()->checkEvents(); + EventDispatcher::GetInstance()->dispatch(); } /* nothing to rebuild */ diff --git a/src/typedefs.h b/src/typedefs.h index 9f8c5d07c2..2f1724b0ff 100644 --- a/src/typedefs.h +++ b/src/typedefs.h @@ -1,6 +1,6 @@ /* - * $Id: typedefs.h,v 1.186 2006/05/22 19:58:51 wessels Exp $ + * $Id: typedefs.h,v 1.187 2006/08/07 02:28:22 robertc Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -237,15 +237,9 @@ typedef variable_list *(oid_ParseFn) (variable_list *, snint *); typedef struct _snmp_request_t snmp_request_t; #endif -typedef void CWCB(int fd, char *, size_t size, comm_err_t flag, void *data); -typedef void CNCB(int fd, comm_err_t status, int xerrno, void *data); - -typedef void IOCB(int fd, char *, size_t size, comm_err_t flag, int xerrno, void *data); - typedef void FREE(void *); typedef void CBDUNL(void *); typedef void FOCB(void *, int fd, int errcode); -typedef void EVH(void *); typedef void PF(int, void *); /* disk.c / diskd.c callback typedefs */ diff --git a/src/wccp.cc b/src/wccp.cc index 90348ffce0..6ae16ae26a 100644 --- a/src/wccp.cc +++ b/src/wccp.cc @@ -1,6 +1,6 @@ /* - * $Id: wccp.cc,v 1.40 2006/07/02 16:53:47 serassio Exp $ + * $Id: wccp.cc,v 1.41 2006/08/07 02:28:22 robertc Exp $ * * DEBUG: section 80 WCCP Support * AUTHOR: Glenn Chisholm @@ -34,6 +34,7 @@ */ #include "squid.h" #include "comm.h" +#include "event.h" #if USE_WCCP diff --git a/src/wccp2.cc b/src/wccp2.cc index dec8c374a3..e763d6ce5a 100644 --- a/src/wccp2.cc +++ b/src/wccp2.cc @@ -1,6 +1,6 @@ /* - * $Id: wccp2.cc,v 1.3 2006/07/31 13:17:57 serassio Exp $ + * $Id: wccp2.cc,v 1.4 2006/08/07 02:28:22 robertc Exp $ * * DEBUG: section 80 WCCP Support * AUTHOR: Steven WIlton @@ -34,7 +34,9 @@ */ #include "squid.h" #include "comm.h" +#include "event.h" #include "Parsing.h" +#include "Store.h" #if USE_WCCPv2 #include