# Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: kinkie@squid-cache.org-20080714133509-pk3ez8mf2dxd3s2s # target_branch: ../repo/squid-trunk # testament_sha1: dd2ad370c8b7e2525fbd2c58be9785f7099c2312 # timestamp: 2008-07-14 15:37:37 +0200 # base_revision_id: henrik@henriknordstrom.net-20080714100125-\ # 2j4maop6iz80j0xu # # Begin patch === modified file 'helpers/basic_auth/squid_radius_auth/radius-util.h' (properties changed: +x to -x) === modified file 'helpers/basic_auth/squid_radius_auth/squid_rad_auth.c' (properties changed: +x to -x) === modified file 'helpers/external_acl/session/squid_session.c' (properties changed: +x to -x) === modified file 'helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegohelp.c' (properties changed: +x to -x) === modified file 'helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegohelp.h' (properties changed: +x to -x) === modified file 'helpers/ntlm_auth/fakeauth/fakeauth_auth.c' (properties changed: +x to -x) === modified file 'include/profiling.h' --- include/profiling.h 2008-04-14 21:29:38 +0000 +++ include/profiling.h 2008-07-13 08:37:43 +0000 @@ -213,9 +213,6 @@ SQUIDCEXTERN void xprof_start(xprof_type type, const char *timer); SQUIDCEXTERN void xprof_stop(xprof_type type, const char *timer); SQUIDCEXTERN void xprof_event(void *data); -#if __cplusplus -extern void xprofRegisterWithCacheManager(CacheManager & manager); -#endif #define PROF_start(type) xprof_start(XPROF_##type, #type) #define PROF_stop(type) xprof_stop(XPROF_##type, #type) === modified file 'include/squid_mswin.h' (properties changed: +x to -x) === modified file 'lib/dirent.c' (properties changed: +x to -x) === modified file 'lib/encrypt.c' (properties changed: +x to -x) === modified file 'lib/getopt.c' (properties changed: +x to -x) === modified file 'lib/inet_ntoa.c' (properties changed: +x to -x) === modified file 'lib/radix.c' (properties changed: +x to -x) === modified file 'lib/strnstr.cc' (properties changed: +x to -x) === modified file 'lib/win32lib.c' (properties changed: +x to -x) === modified file 'src/ACLASN.h' --- src/ACLASN.h 2008-07-09 11:55:41 +0000 +++ src/ACLASN.h 2008-07-13 08:37:43 +0000 @@ -41,19 +41,12 @@ #include "ACLChecklist.h" #include "IPAddress.h" -/* forward decls */ - -class CacheManager; - SQUIDCEXTERN int asnMatchIp(CbDataList *, IPAddress &); /// \ingroup ACLAPI SQUIDCEXTERN void asnInit(void); /// \ingroup ACLAPI -extern void asnRegisterWithCacheManager(CacheManager & manager); - -/// \ingroup ACLAPI SQUIDCEXTERN void asnFreeMemory(void); /// \ingroup ACLAPI === modified file 'src/AccessLogEntry.h' --- src/AccessLogEntry.h 2008-06-25 12:21:03 +0000 +++ src/AccessLogEntry.h 2008-07-13 08:37:43 +0000 @@ -40,7 +40,6 @@ #include "HttpRequestMethod.h" /* forward decls */ -class CacheManager; class HttpReply; class HttpRequest; @@ -144,7 +143,6 @@ extern void accessLogRotate(void); extern void accessLogClose(void); extern void accessLogInit(void); -extern void accessLogRegisterWithCacheManager(CacheManager & manager); extern void accessLogFreeMemory(AccessLogEntry * aLogEntry); extern const char *accessLogTime(time_t); extern int accessLogParseLogFormat(logformat_token ** fmt, char *def); === modified file 'src/AuthConfig.cc' --- src/AuthConfig.cc 2007-05-09 15:07:38 +0000 +++ src/AuthConfig.cc 2008-07-09 14:28:16 +0000 @@ -77,5 +77,5 @@ /* Default behaviour is to expose nothing */ void -AuthConfig::registerWithCacheManager(CacheManager & manager) +AuthConfig::registerWithCacheManager(void) {} === modified file 'src/AuthConfig.h' --- src/AuthConfig.h 2008-03-20 11:30:19 +0000 +++ src/AuthConfig.h 2008-07-13 08:37:43 +0000 @@ -36,7 +36,6 @@ class StoreEntry; class HttpReply; class HttpRequest; -class CacheManager; /* for http_hdr_type parameters-by-value */ #include "HttpHeader.h" @@ -114,7 +113,7 @@ /** prepare to handle requests */ virtual void init(AuthConfig *) = 0; /** expose any/all statistics to a CacheManager */ - virtual void registerWithCacheManager(CacheManager & manager); + virtual void registerWithCacheManager(void); /** parse config options */ virtual void parse(AuthConfig *, int, char *) = 0; /** the http string id */ === modified file 'src/CacheManager.h' --- src/CacheManager.h 2008-03-16 21:48:45 +0000 +++ src/CacheManager.h 2008-07-05 23:26:10 +0000 @@ -35,34 +35,47 @@ #define SQUID_CACHEMANAGER_H #include "squid.h" +#include "Array.h" /** \defgroup CacheManagerAPI Cache Manager API \ingroup Components - */ - -/// \ingroup CacheManagerAPI -extern void cachemgrStart(int fd, HttpRequest * request, StoreEntry * entry); - -/** + + \defgroup CacheManagerInternal Cache Manager intenal API (not for public use) \ingroup CacheManagerAPI - * A single menu item in the cache manager - an 'action'. - */ -class CacheManagerAction -{ - + */ + +/** + \ingroup CacheManagerInternal + * The basic action handler. Its virtual method run(StoreEntry *) is invoked + * to perform the actual action. + */ +class CacheManagerAction { +public: + virtual void run(StoreEntry *sentry) = 0; + char *action; + char *desc; + struct + { + unsigned int pw_req:1; + unsigned int atomic:1; + } flags; + virtual ~CacheManagerAction(); + CacheManagerAction(char const *anAction, char const *aDesc, unsigned int isPwReq, unsigned int isAtomic); + +}; + +/** + \ingroup CacheManagerInternal + * wrapper allowing c-style callbacks to be used. Arguments are supposed to + * managed by the caller. + * This object is generated by CacheManager::registerAction + */ +class CacheManagerActionLegacy : public CacheManagerAction { public: - char *action; - char *desc; - OBJH *handler; - - struct - { - unsigned int pw_req:1; - unsigned int atomic:1; - } flags; - - CacheManagerAction *next; + OBJH *handler; + virtual void run (StoreEntry *sentry); + CacheManagerActionLegacy(char const *anAction, char const *aDesc, unsigned int isPwReq, unsigned int isAtomic, OBJH *aHandler); }; @@ -72,12 +85,12 @@ * This is currently just an adapter to the global cachemgr* routines to * provide looser coupling between modules, but once fully transitioned, * an instance of this class will represent a single independent manager. + * TODO: update documentation to reflect the new singleton model. */ class CacheManager { public: - CacheManager(); /* the holy trinity - assignment, copy cons, destructor */ /* unimplemented - prevents bugs from synthetic */ CacheManager & operator = (CacheManager &); @@ -86,8 +99,71 @@ /* inline so that we dont need to link in cachemgr.cc at all in tests */ virtual ~CacheManager() {} - virtual void registerAction(char const * action, char const * desc, OBJH * handler, int pw_req_flag, int atomic); - virtual CacheManagerAction * findAction(char const * action); + void registerAction(char const * action, char const * desc, OBJH * handler, int pw_req_flag, int atomic); + void registerAction(CacheManagerAction *anAction); + CacheManagerAction * findAction(char const * action); + + void Start(int fd, HttpRequest * request, StoreEntry * entry); + + static CacheManager* GetInstance(); + const char *ActionProtection(const CacheManagerAction * at); + +protected: + // command classes. They are private to the cachemanager, they + // may require access to local data, plus we avoid polluting + // the namespace more than needed. + class ShutdownAction : public CacheManagerAction { + public: + virtual void run (StoreEntry *sentry); + ShutdownAction(); + }; + class ReconfigureAction : public CacheManagerAction { + public: + virtual void run (StoreEntry *sentry); + ReconfigureAction(); + }; + class OfflineToggleAction : public CacheManagerAction { + public: + virtual void run (StoreEntry *sentry); + OfflineToggleAction(); + }; + class MenuAction : public CacheManagerAction { + private: + //needs to reference the cachemgr in order to get to ActionsList + CacheManager *cmgr; + public: + virtual void run (StoreEntry *sentry); + MenuAction(CacheManager *); + + }; + + /// \ingroup CacheManagerInternal + typedef struct + { + StoreEntry *entry; + char *action; + char *user_name; + char *passwd; + } cachemgrStateData; + + + CacheManager(); + cachemgrStateData* ParseUrl(const char *url); + void ParseHeaders(cachemgrStateData * mgr, const HttpRequest * request); + int CheckPassword(cachemgrStateData * mgr); + char *PasswdGet(cachemgr_passwd *, const char *); + + // \ingroup CacheManagerInternal + typedef Vector CacheManagerActionList; + CacheManagerActionList ActionsList; + + +private: + static CacheManager* instance; + + void StateFree(cachemgrStateData * mgr); + + }; #endif /* SQUID_CACHEMANAGER_H */ === modified file 'src/ConfigParser.h' --- src/ConfigParser.h 2007-05-29 19:31:36 +0000 +++ src/ConfigParser.h 2008-07-09 13:51:36 +0000 @@ -38,10 +38,6 @@ #include "squid.h" -/* forward decls */ - -class CacheManager; - /* * A configuration file Parser. Instances of this class track * parsing state and perform tokenisation. Syntax is currently @@ -66,6 +62,6 @@ static char * strtokFile(); }; -extern int parseConfigFile(const char *file_name, CacheManager & manager); +extern int parseConfigFile(const char *file_name); #endif /* SQUID_CONFIGPARSER_H */ === modified file 'src/DelayPools.h' --- src/DelayPools.h 2008-03-20 11:30:19 +0000 +++ src/DelayPools.h 2008-07-13 08:37:43 +0000 @@ -50,7 +50,6 @@ }; /* forward decls */ -class CacheManager; class DelayPool; class Updateable; class StoreEntry; @@ -64,7 +63,6 @@ public: static void Init(); - static void RegisterWithCacheManager(CacheManager & manager); static void Update(void *); static unsigned short pools(); static void pools (u_short pools); @@ -82,6 +80,7 @@ static unsigned short pools_; static void FreeDelayData (); static Vector toUpdate; + static void RegisterWithCacheManager(void); }; #endif /* SQUID_DELAYPOOLS_H */ === modified file 'src/DiskIO/DiskDaemon/DiskDaemonDiskIOModule.cc' --- src/DiskIO/DiskDaemon/DiskDaemonDiskIOModule.cc 2007-04-13 01:37:23 +0000 +++ src/DiskIO/DiskDaemon/DiskDaemonDiskIOModule.cc 2008-07-12 06:07:28 +0000 @@ -69,12 +69,14 @@ debugs(47, 1, "diskd started"); #endif initialised = true; + + registerWithCacheManager(); } void -DiskDaemonDiskIOModule::registerWithCacheManager(CacheManager & manager) +DiskDaemonDiskIOModule::registerWithCacheManager(void) { - manager.registerAction("diskd", "DISKD Stats", Stats, 0, 1); + CacheManager::GetInstance()->registerAction("diskd", "DISKD Stats", Stats, 0, 1); } void === modified file 'src/DiskIO/DiskDaemon/DiskDaemonDiskIOModule.h' --- src/DiskIO/DiskDaemon/DiskDaemonDiskIOModule.h 2006-05-29 06:14:59 +0000 +++ src/DiskIO/DiskDaemon/DiskDaemonDiskIOModule.h 2008-07-12 06:07:28 +0000 @@ -43,7 +43,6 @@ static DiskDaemonDiskIOModule &GetInstance(); DiskDaemonDiskIOModule(); virtual void init(); - virtual void registerWithCacheManager(CacheManager & manager); virtual void shutdown(); virtual char const *type () const; virtual DiskIOStrategy* createStrategy(); @@ -52,6 +51,7 @@ static void Stats(StoreEntry * sentry); static DiskDaemonDiskIOModule Instance; bool initialised; + void registerWithCacheManager(void); }; #endif /* SQUID_DISKDAEMONDISKIOMODULE_H */ === modified file 'src/DiskIO/DiskIOModule.cc' --- src/DiskIO/DiskIOModule.cc 2006-09-14 06:51:09 +0000 +++ src/DiskIO/DiskIOModule.cc 2008-07-12 06:07:28 +0000 @@ -49,13 +49,6 @@ } void -DiskIOModule::RegisterAllModulesWithCacheManager(CacheManager & manager) -{ - for (iterator i = GetModules().begin(); i != GetModules().end(); ++i) - (*i)->registerWithCacheManager(manager); -} - -void DiskIOModule::SetupAllModules() { for (iterator i = GetModules().begin(); i != GetModules().end(); ++i) @@ -130,7 +123,3 @@ return result; } -/* disk modules dont export anything by default */ -void -DiskIOModule::registerWithCacheManager(CacheManager & manager) -{} === modified file 'src/DiskIO/DiskIOModule.h' --- src/DiskIO/DiskIOModule.h 2006-09-14 06:51:09 +0000 +++ src/DiskIO/DiskIOModule.h 2008-07-13 08:37:43 +0000 @@ -47,7 +47,6 @@ { public: - static void RegisterAllModulesWithCacheManager(CacheManager & manager); static void SetupAllModules(); static void ModuleAdd(DiskIOModule &); static void FreeAllModules(); @@ -63,7 +62,7 @@ virtual ~DiskIOModule(){} virtual void init() = 0; - virtual void registerWithCacheManager(CacheManager & manager); + //virtual void registerWithCacheManager(void); virtual void shutdown() = 0; virtual DiskIOStrategy *createStrategy() = 0; @@ -74,6 +73,7 @@ protected: //bool initialised; + static void RegisterAllModulesWithCacheManager(void); private: static Vector &GetModules(); === modified file 'src/DiskIO/DiskThreads/DiskThreadsDiskIOModule.cc' --- src/DiskIO/DiskThreads/DiskThreadsDiskIOModule.cc 2006-05-29 06:14:59 +0000 +++ src/DiskIO/DiskThreads/DiskThreadsDiskIOModule.cc 2008-07-12 06:07:28 +0000 @@ -54,12 +54,6 @@ } void -DiskThreadsDiskIOModule::registerWithCacheManager(CacheManager & manager) -{ - DiskThreadsIOStrategy::Instance.registerWithCacheManager(manager); -} - -void DiskThreadsDiskIOModule::shutdown() { DiskThreadsIOStrategy::Instance.done(); === modified file 'src/DiskIO/DiskThreads/DiskThreadsDiskIOModule.h' --- src/DiskIO/DiskThreads/DiskThreadsDiskIOModule.h 2006-05-29 06:14:59 +0000 +++ src/DiskIO/DiskThreads/DiskThreadsDiskIOModule.h 2008-07-12 06:07:28 +0000 @@ -43,7 +43,7 @@ static DiskThreadsDiskIOModule &GetInstance(); DiskThreadsDiskIOModule(); virtual void init(); - virtual void registerWithCacheManager(CacheManager & manager); + //virtual void registerWithCacheManager(void); virtual void shutdown(); virtual char const *type () const; virtual DiskIOStrategy* createStrategy(); === modified file 'src/DiskIO/DiskThreads/DiskThreadsIOStrategy.cc' --- src/DiskIO/DiskThreads/DiskThreadsIOStrategy.cc 2007-04-29 04:26:37 +0000 +++ src/DiskIO/DiskThreads/DiskThreadsIOStrategy.cc 2008-07-12 06:07:28 +0000 @@ -58,13 +58,16 @@ * hasn't been parsed yet and we don't know how many cache_dirs * there are, which means we don't know how many threads to start. */ + + registerWithCacheManager(); } void -DiskThreadsIOStrategy::registerWithCacheManager(CacheManager & manager) +DiskThreadsIOStrategy::registerWithCacheManager(void) { - manager.registerAction("squidaio_counts", "Async IO Function Counters", - aioStats, 0, 1); + CacheManager::GetInstance()-> + registerAction("squidaio_counts", "Async IO Function Counters", + aioStats, 0, 1); } void === modified file 'src/DiskIO/DiskThreads/DiskThreadsIOStrategy.h' --- src/DiskIO/DiskThreads/DiskThreadsIOStrategy.h 2007-04-13 05:51:55 +0000 +++ src/DiskIO/DiskThreads/DiskThreadsIOStrategy.h 2008-07-12 06:07:28 +0000 @@ -58,7 +58,6 @@ virtual int callback(); virtual void sync(); virtual void init(); - virtual void registerWithCacheManager(CacheManager & manager); void done(); /* Todo: add access limitations */ bool initialised; @@ -67,6 +66,7 @@ private: static void aioStats(StoreEntry * sentry); + void registerWithCacheManager(void); }; #endif === modified file 'src/ExternalACL.h' --- src/ExternalACL.h 2008-03-20 11:30:19 +0000 +++ src/ExternalACL.h 2008-07-13 08:37:43 +0000 @@ -92,6 +92,4 @@ MEMPROXY_CLASS_INLINE(ACLExternal); -extern void externalAclRegisterWithCacheManager(CacheManager & manager); - #endif /* SQUID_EXTERNALACL_H */ === modified file 'src/HttpHeader.cc' --- src/HttpHeader.cc 2008-06-13 14:30:53 +0000 +++ src/HttpHeader.cc 2008-07-13 08:37:43 +0000 @@ -272,6 +272,15 @@ * Module initialization routines */ +static void +httpHeaderRegisterWithCacheManager(void) +{ + CacheManager::GetInstance()-> + registerAction("http_headers", + "HTTP Header Statistics", + httpHeaderStoreReport, 0, 1); +} + void httpHeaderInitModule(void) { @@ -326,15 +335,8 @@ httpHdrCcInitModule(); httpHdrScInitModule(); -} -void -httpHeaderRegisterWithCacheManager(CacheManager & manager) -{ - /* register with cache manager */ - manager.registerAction("http_headers", - "HTTP Header Statistics", - httpHeaderStoreReport, 0, 1); + httpHeaderRegisterWithCacheManager(); } void === modified file 'src/HttpHeader.h' --- src/HttpHeader.h 2008-03-20 11:30:19 +0000 +++ src/HttpHeader.h 2008-07-13 08:37:43 +0000 @@ -33,9 +33,6 @@ #ifndef SQUID_HTTPHEADER_H #define SQUID_HTTPHEADER_H -/* forward decls */ - -class CacheManager; /* because we pass a spec by value */ #include "HttpHeaderRange.h" @@ -269,7 +266,6 @@ }; -extern void httpHeaderRegisterWithCacheManager(CacheManager & manager); extern int httpHeaderParseQuotedString (const char *start, String *val); SQUIDCEXTERN int httpHeaderHasByNameListMember(const HttpHeader * hdr, const char *name, const char *member, const char separator); SQUIDCEXTERN void httpHeaderUpdate(HttpHeader * old, const HttpHeader * fresh, const HttpHeaderMask * denied_mask); === modified file 'src/ICAP/Makefile.am' --- src/ICAP/Makefile.am 2008-04-14 13:51:31 +0000 +++ src/ICAP/Makefile.am 2008-07-13 21:40:50 +0000 @@ -33,7 +33,7 @@ check_PROGRAMS = testHeaders ## test .h correctness -testHeaders: *.h +testHeaders: $(top_srcdir)/src/ICAP/*.h $(top_srcdir)/test-suite/testheaders.sh "$(CXXCOMPILE)" "." || exit 1 ## No such file... === modified file 'src/ICMPPinger.cc' (properties changed: +x to -x) === modified file 'src/ICMPv4.h' (properties changed: +x to -x) === modified file 'src/Makefile.am' (properties changed: +x to -x) --- src/Makefile.am 2008-07-11 20:43:43 +0000 +++ src/Makefile.am 2008-07-14 13:35:09 +0000 @@ -1193,7 +1193,7 @@ ## Special Universal .h dependency test script ## aborts if error encountered -testHeaders: *.h DiskIO/*.h +testHeaders: $(top_srcdir)/src/*.h $(top_srcdir)/src/DiskIO/*.h $(SHELL) $(top_srcdir)/test-suite/testheaders.sh "$(CXXCOMPILE)" "." || exit 1 $(SHELL) $(top_srcdir)/test-suite/testheaders.sh "$(CXXCOMPILE)" "DiskIO" || exit 1 ## src/repl/ has no .h files and its own makefile. @@ -1235,6 +1235,7 @@ StatHist.cc HttpHdrRange.cc ETag.cc tests/stub_errorpage.cc \ tests/stub_HttpRequest.cc tests/stub_DelayId.cc \ tests/stub_MemObject.cc mem_node.cc \ + tests/stub_cache_manager.cc \ stmem.cc \ tests/stub_comm.cc \ tests/stub_http.cc \ @@ -1315,6 +1316,7 @@ tests/stub_DelayId.cc \ tests/stub_MemObject.cc \ tests/stub_store.cc \ + tests/stub_cache_manager.cc \ tests/testACLMaxUserIP.cc \ tests/testACLMaxUserIP.h \ tests/testMain.cc \ === modified file 'src/Mem.h' --- src/Mem.h 2008-03-20 11:30:19 +0000 +++ src/Mem.h 2008-07-13 08:37:43 +0000 @@ -34,7 +34,6 @@ #ifndef SQUID_MEM #define SQUID_MEM -class CacheManager; class StoreEntry; class MemPoolStats; class MemPoolMeter; @@ -48,11 +47,13 @@ public: static void Init(); static void Report(); - static void RegisterWithCacheManager(CacheManager & manager); static void Stats(StoreEntry *); static void CleanIdlePools(void *unused); static void Report(std::ostream &); static void PoolReport(const MemPoolStats * mp_st, const MemPoolMeter * AllMeter, std::ostream &); + +protected: + static void RegisterWithCacheManager(void); }; #endif /* SQUID_MEM */ === modified file 'src/ProfStats.cc' --- src/ProfStats.cc 2007-04-25 17:30:14 +0000 +++ src/ProfStats.cc 2008-07-13 08:37:43 +0000 @@ -265,6 +265,16 @@ } } +static void +xprofRegisterWithCacheManager(void) +{ + CacheManager::GetInstance()-> + registerAction("cpu_profile", "CPU Profiling Stats", xprof_summary, 0, 1); +} + +// FIXME: +// this gets colled once per event. This doesn't seem to make much sense, +// does it? static hrtime_t now; static void xprof_Init(void) @@ -275,12 +285,8 @@ xprof_delta = xprof_verystart = xprof_start_t = now; xprof_inited = 1; -} -void -xprofRegisterWithCacheManager(CacheManager & manager) -{ - manager.registerAction("cpu_profile", "CPU Profiling Stats", xprof_summary, 0, 1); + xprofRegisterWithCacheManager(); //moved here so it's not double-init'ed } void === modified file 'src/SquidString.h' --- src/SquidString.h 2008-03-20 11:30:19 +0000 +++ src/SquidString.h 2008-07-13 08:37:43 +0000 @@ -37,10 +37,6 @@ #include "config.h" -/* forward decls */ - -class CacheManager; - /** todo checks to wrap this include properly */ #include @@ -60,7 +56,7 @@ void add (String const *); - void registerWithCacheManager(CacheManager & manager); + StringRegistry(); void remove (String const *); === modified file 'src/Store.h' --- src/Store.h 2008-03-20 11:30:19 +0000 +++ src/Store.h 2008-07-13 08:37:43 +0000 @@ -339,9 +339,6 @@ SQUIDCEXTERN void storeInit(void); /// \ingroup StoreAPI -extern void storeRegisterWithCacheManager(CacheManager & manager); - -/// \ingroup StoreAPI SQUIDCEXTERN void storeConfigure(void); /// \ingroup StoreAPI === modified file 'src/StoreFileSystem.cc' --- src/StoreFileSystem.cc 2006-05-29 06:14:59 +0000 +++ src/StoreFileSystem.cc 2008-07-10 18:13:35 +0000 @@ -40,10 +40,10 @@ Vector *StoreFileSystem::_FileSystems = NULL; void -StoreFileSystem::RegisterAllFsWithCacheManager(CacheManager & manager) +StoreFileSystem::RegisterAllFsWithCacheManager(void) { for (iterator i = GetFileSystems().begin(); i != GetFileSystems().end(); ++i) - (*i)->registerWithCacheManager(manager); + (*i)->registerWithCacheManager(); } void @@ -98,5 +98,5 @@ /* no filesystem is required to export statistics */ void -StoreFileSystem::registerWithCacheManager(CacheManager & manager) +StoreFileSystem::registerWithCacheManager(void) {} === modified file 'src/StoreFileSystem.h' --- src/StoreFileSystem.h 2008-04-21 12:52:20 +0000 +++ src/StoreFileSystem.h 2008-07-13 08:37:43 +0000 @@ -104,7 +104,6 @@ * given StoreEntry. A maxobjsize of -1 means 'any size'. */ -class CacheManager; class SwapDir; /** @@ -117,7 +116,6 @@ { public: - static void RegisterAllFsWithCacheManager(CacheManager & manager); static void SetupAllFs(); static void FsAdd(StoreFileSystem &); static void FreeAllFs(); @@ -131,7 +129,6 @@ virtual char const *type () const = 0; virtual SwapDir *createSwapDir() = 0; virtual void done() = 0; - virtual void registerWithCacheManager(CacheManager & manager); virtual void setup() = 0; // Not implemented StoreFileSystem(StoreFileSystem const &); @@ -139,10 +136,12 @@ protected: bool initialised; + virtual void registerWithCacheManager(void); private: static Vector &GetFileSystems(); static Vector *_FileSystems; + static void RegisterAllFsWithCacheManager(void); }; // TODO: Kill this typedef! === modified file 'src/String.cc' --- src/String.cc 2008-01-24 06:08:58 +0000 +++ src/String.cc 2008-07-12 15:11:10 +0000 @@ -253,11 +253,12 @@ return lhs - rhs; } -void -StringRegistry::registerWithCacheManager(CacheManager & manager) +StringRegistry::StringRegistry() { - manager.registerAction("strings", +#if DEBUGSTRINGS + CacheManager::GetInstance()->registerAction("strings", "Strings in use in squid", Stat, 0, 1); +#endif } void === modified file 'src/WinSvc.cc' (properties changed: +x to -x) === modified file 'src/access_log.cc' --- src/access_log.cc 2008-06-25 12:21:03 +0000 +++ src/access_log.cc 2008-07-12 15:40:56 +0000 @@ -105,7 +105,7 @@ static OBJH fvdbDumpForw; static FREE fvdbFreeEntry; static void fvdbClear(void); -static void fvdbRegisterWithCacheManager(CacheManager & manager); +static void fvdbRegisterWithCacheManager(); #endif static int LogfileStatus = LOG_DISABLE; @@ -1555,10 +1555,21 @@ xstrncpy(hl->host, cache_peer, SQUIDHOSTNAMELEN); } +static void +accessLogRegisterWithCacheManager(void) +{ +#if FORW_VIA_DB + fvdbRegisterWithCacheManager(); +#endif +} + void accessLogInit(void) { customlog *log; + + accessLogRegisterWithCacheManager(); + assert(sizeof(log_tags) == (LOG_TYPE_MAX + 1) * sizeof(char *)); for (log = Config.Log.accesslogs; log; log = log->next) { @@ -1610,16 +1621,6 @@ #endif } -void -accessLogRegisterWithCacheManager(CacheManager & manager) -{ -#if FORW_VIA_DB - - fvdbRegisterWithCacheManager(manager); - -#endif -} - const char * accessLogTime(time_t t) { @@ -1648,10 +1649,11 @@ } static void -fvdbRegisterWithCacheManager(CacheManager & manager) +fvdbRegisterWithCacheManager(void) { - manager.registerAction("via_headers", "Via Request Headers", fvdbDumpVia, 0, 1); - manager.registerAction("forw_headers", "X-Forwarded-For Request Headers", + CacheManager *manager=CacheManager::GetInstance(); + manager->registerAction("via_headers", "Via Request Headers", fvdbDumpVia, 0, 1); + manager->registerAction("forw_headers", "X-Forwarded-For Request Headers", fvdbDumpForw, 0, 1); } === modified file 'src/adaptation/Makefile.am' --- src/adaptation/Makefile.am 2008-04-14 13:51:31 +0000 +++ src/adaptation/Makefile.am 2008-07-13 21:40:50 +0000 @@ -32,7 +32,7 @@ check_PROGRAMS = testHeaders ## test .h correctness -testHeaders: *.h +testHeaders: $(top_srcdir)/src/adaptation/*.h $(top_srcdir)/test-suite/testheaders.sh "$(CXXCOMPILE)" "." || exit 1 ## No such file... === modified file 'src/asn.cc' --- src/asn.cc 2008-07-09 11:55:41 +0000 +++ src/asn.cc 2008-07-12 15:51:24 +0000 @@ -179,6 +179,12 @@ asnCacheStart(i->element); } +static void +asnRegisterWithCacheManager(void) +{ + CacheManager::GetInstance()->registerAction("asndb", "AS Number Database", asnStats, 0, 1); +} + /* initialize the radix tree structure */ SQUIDCEXTERN int squid_max_keylen; /* yuck.. this is in lib/radix.c */ @@ -195,12 +201,8 @@ squid_rn_init(); squid_rn_inithead(&AS_tree_head, 8); -} -void -asnRegisterWithCacheManager(CacheManager & manager) -{ - manager.registerAction("asndb", "AS Number Database", asnStats, 0, 1); + asnRegisterWithCacheManager(); } void === modified file 'src/auth/Makefile.am' --- src/auth/Makefile.am 2008-04-14 13:51:31 +0000 +++ src/auth/Makefile.am 2008-07-13 21:40:50 +0000 @@ -24,7 +24,7 @@ ## Special Universal .h dependency test script ## aborts if error encountered -testHeaders: basic/*.h digest/*.h ntlm/*.h negotiate/*.h +testHeaders: $(top_srcdir)/src/auth/basic/*.h $(top_srcdir)/src/auth/digest/*.h $(top_srcdir)/src/auth/ntlm/*.h $(top_srcdir)/src/auth/negotiate/*.h $(SHELL) $(top_srcdir)/test-suite/testheaders.sh "$(CXXCOMPILE)" "basic" || exit 1 $(SHELL) $(top_srcdir)/test-suite/testheaders.sh "$(CXXCOMPILE)" "digest" || exit 1 $(SHELL) $(top_srcdir)/test-suite/testheaders.sh "$(CXXCOMPILE)" "ntlm" || exit 1 === modified file 'src/auth/basic/auth_basic.cc' --- src/auth/basic/auth_basic.cc 2008-07-07 11:53:28 +0000 +++ src/auth/basic/auth_basic.cc 2008-07-09 14:38:11 +0000 @@ -624,9 +624,10 @@ } void -AuthBasicConfig::registerWithCacheManager(CacheManager & manager) +AuthBasicConfig::registerWithCacheManager(void) { - manager.registerAction("basicauthenticator", + CacheManager::GetInstance()-> + registerAction("basicauthenticator", "Basic User Authenticator Stats", authenticateBasicStats, 0, 1); } === modified file 'src/auth/basic/auth_basic.h' --- src/auth/basic/auth_basic.h 2008-07-07 11:53:28 +0000 +++ src/auth/basic/auth_basic.h 2008-07-09 14:38:11 +0000 @@ -124,7 +124,7 @@ virtual void fixHeader(AuthUserRequest *, HttpReply *, http_hdr_type, HttpRequest *); virtual void init(AuthConfig *); virtual void parse(AuthConfig *, int, char *); - virtual void registerWithCacheManager(CacheManager & manager); + virtual void registerWithCacheManager(void); virtual const char * type() const; int authenticateChildren; int authenticateConcurrency; === modified file 'src/auth/digest/auth_digest.cc' --- src/auth/digest/auth_digest.cc 2008-07-07 11:53:28 +0000 +++ src/auth/digest/auth_digest.cc 2008-07-09 14:38:11 +0000 @@ -888,9 +888,10 @@ } void -AuthDigestConfig::registerWithCacheManager(CacheManager & manager) +AuthDigestConfig::registerWithCacheManager(void) { - manager.registerAction("digestauthenticator", + CacheManager::GetInstance()-> + registerAction("digestauthenticator", "Digest User Authenticator Stats", authenticateDigestStats, 0, 1); } === modified file 'src/auth/digest/auth_digest.h' --- src/auth/digest/auth_digest.h 2008-07-07 11:53:28 +0000 +++ src/auth/digest/auth_digest.h 2008-07-09 14:38:11 +0000 @@ -153,7 +153,7 @@ virtual void fixHeader(AuthUserRequest *, HttpReply *, http_hdr_type, HttpRequest *); virtual void init(AuthConfig *); virtual void parse(AuthConfig *, int, char *); - virtual void registerWithCacheManager(CacheManager & manager); + virtual void registerWithCacheManager(void); virtual const char * type() const; int authenticateChildren; char *digestAuthRealm; === modified file 'src/auth/negotiate/auth_negotiate.cc' --- src/auth/negotiate/auth_negotiate.cc 2008-03-20 11:30:19 +0000 +++ src/auth/negotiate/auth_negotiate.cc 2008-07-09 14:28:16 +0000 @@ -212,9 +212,10 @@ } void -AuthNegotiateConfig::registerWithCacheManager(CacheManager & manager) +AuthNegotiateConfig::registerWithCacheManager(void) { - manager.registerAction("negotiateauthenticator", + CacheManager::GetInstance()-> + registerAction("negotiateauthenticator", "Negotiate User Authenticator Stats", authenticateNegotiateStats, 0, 1); } === modified file 'src/auth/negotiate/auth_negotiate.h' --- src/auth/negotiate/auth_negotiate.h 2008-04-21 12:05:23 +0000 +++ src/auth/negotiate/auth_negotiate.h 2008-07-09 14:28:16 +0000 @@ -125,7 +125,7 @@ virtual void fixHeader(AuthUserRequest *, HttpReply *, http_hdr_type, HttpRequest *); virtual void init(AuthConfig *); virtual void parse(AuthConfig *, int, char *); - virtual void registerWithCacheManager(CacheManager & manager); + virtual void registerWithCacheManager(void); virtual const char * type() const; int authenticateChildren; int keep_alive; === modified file 'src/auth/ntlm/auth_ntlm.cc' --- src/auth/ntlm/auth_ntlm.cc 2008-06-13 14:30:53 +0000 +++ src/auth/ntlm/auth_ntlm.cc 2008-07-09 14:28:16 +0000 @@ -198,9 +198,10 @@ } void -AuthNTLMConfig::registerWithCacheManager(CacheManager & manager) +AuthNTLMConfig::registerWithCacheManager(void) { - manager.registerAction("ntlmauthenticator", + CacheManager::GetInstance()-> + registerAction("ntlmauthenticator", "NTLM User Authenticator Stats", authenticateNTLMStats, 0, 1); } === modified file 'src/auth/ntlm/auth_ntlm.h' --- src/auth/ntlm/auth_ntlm.h 2008-03-16 22:10:18 +0000 +++ src/auth/ntlm/auth_ntlm.h 2008-07-09 14:28:16 +0000 @@ -110,7 +110,7 @@ virtual void fixHeader(AuthUserRequest *, HttpReply *, http_hdr_type, HttpRequest *); virtual void init(AuthConfig *); virtual void parse(AuthConfig *, int, char *); - virtual void registerWithCacheManager(CacheManager & manager); + virtual void registerWithCacheManager(void); virtual const char * type() const; int authenticateChildren; int keep_alive; === modified file 'src/authenticate.cc' --- src/authenticate.cc 2008-03-20 11:30:19 +0000 +++ src/authenticate.cc 2008-07-12 15:51:24 +0000 @@ -73,6 +73,15 @@ return rv; } +static void +authenticateRegisterWithCacheManager(authConfig * config) +{ + for (authConfig::iterator i = config->begin(); i != config->end(); ++i) { + AuthConfig *scheme = *i; + scheme->registerWithCacheManager(); + } +} + void authenticateInit(authConfig * config) { @@ -87,15 +96,8 @@ AuthUser::cacheInit(); else AuthUser::CachedACLsReset(); -} -void -authenticateRegisterWithCacheManager(authConfig * config, CacheManager & manager) -{ - for (authConfig::iterator i = config->begin(); i != config->end(); ++i) { - AuthConfig *scheme = *i; - scheme->registerWithCacheManager(manager); - } + authenticateRegisterWithCacheManager(&Config.authConfiguration); } void === modified file 'src/authenticate.h' --- src/authenticate.h 2008-04-21 12:05:23 +0000 +++ src/authenticate.h 2008-07-12 15:51:24 +0000 @@ -83,8 +83,6 @@ /// \ingroup AuthAPI extern void authenticateInit(authConfig *); /// \ingroup AuthAPI -extern void authenticateRegisterWithCacheManager(authConfig * config, CacheManager & manager); -/// \ingroup AuthAPI extern void authenticateShutdown(void); /// \ingroup AuthAPI extern int authenticateAuthUserInuse(AuthUser * auth_user); === modified file 'src/cache_cf.cc' --- src/cache_cf.cc 2008-07-11 20:20:31 +0000 +++ src/cache_cf.cc 2008-07-14 13:35:09 +0000 @@ -382,9 +382,10 @@ } int -parseConfigFile(const char *file_name, CacheManager & manager) +parseConfigFile(const char *file_name) { int err_count = 0; + CacheManager *manager=CacheManager::GetInstance(); configFreeMemory(); @@ -409,7 +410,7 @@ } if (opt_send_signal == -1) { - manager.registerAction("config", + manager->registerAction("config", "Current Squid Configuration", dump_config, 1, 1); === modified file 'src/cache_manager.cc' --- src/cache_manager.cc 2008-05-01 15:59:41 +0000 +++ src/cache_manager.cc 2008-07-11 05:47:55 +0000 @@ -41,6 +41,7 @@ #include "fde.h" #include "SquidTime.h" #include "wordlist.h" +#include "Debug.h" /** \defgroup CacheManagerInternal Cache Manager Internals @@ -50,92 +51,88 @@ /// \ingroup CacheManagerInternal #define MGR_PASSWD_SZ 128 -/// \ingroup CacheManagerInternal -typedef struct -{ - StoreEntry *entry; - char *action; - char *user_name; - char *passwd; -} cachemgrStateData; - -static CacheManagerAction *cachemgrFindAction(const char *action); -static cachemgrStateData *cachemgrParseUrl(const char *url); -static void cachemgrParseHeaders(cachemgrStateData * mgr, const HttpRequest * request); -static int cachemgrCheckPassword(cachemgrStateData *); -static void cachemgrStateFree(cachemgrStateData * mgr); -static char *cachemgrPasswdGet(cachemgr_passwd *, const char *); -static const char *cachemgrActionProtection(const CacheManagerAction * at); -static OBJH cachemgrShutdown; -static OBJH cachemgrReconfigure; -static OBJH cachemgrMenu; -static OBJH cachemgrOfflineToggle; - -/// \ingroup CacheManagerInternal -CacheManagerAction *ActionTable = NULL; - + +/** + \ingroup CacheManagerInternals + * Constructor. Its purpose is to register internal commands + */ CacheManager::CacheManager() { - registerAction("menu", "This Cachemanager Menu", cachemgrMenu, 0, 1); - registerAction("shutdown", - "Shut Down the Squid Process", - cachemgrShutdown, 1, 1); - registerAction("reconfigure", - "Reconfigure the Squid Process", - cachemgrReconfigure, 1, 1); - registerAction("offline_toggle", - "Toggle offline_mode setting", - cachemgrOfflineToggle, 1, 1); + registerAction(new OfflineToggleAction); + registerAction(new ShutdownAction); + registerAction(new ReconfigureAction); + registerAction(new MenuAction(this)); } +/** + \ingroup CacheManagerAPI + * Registers a C-style action, which is implemented as a pointer to a function + * taking as argument a pointer to a StoreEntry and returning void. + * Implemented via CacheManagerActionLegacy. + */ void CacheManager::registerAction(char const * action, char const * desc, OBJH * handler, int pw_req_flag, int atomic) { - CacheManagerAction *a; - CacheManagerAction **A; + debugs(16, 3, "CacheManager::registerAction: registering legacy " << action); + registerAction(new CacheManagerActionLegacy(action,desc,pw_req_flag,atomic,handler)); +} +/** + \ingroup CacheManagerAPI + * Registers a C++-style action, via a poiner to a subclass of + * a CacheManagerAction object, whose run() method will be invoked when + * CacheManager identifies that the user has requested the action. + */ +void +CacheManager::registerAction(CacheManagerAction *anAction) +{ + char *action = anAction->action; if (findAction(action) != NULL) { - debugs(16, 3, "CacheManager::registerAction: Duplicate '" << action << "'"); + debugs(16, 2, "CacheManager::registerAction: Duplicate '" << action << "'. Skipping."); return; } assert (strstr (" ", action) == NULL); - a = (CacheManagerAction *)xcalloc(1, sizeof(CacheManagerAction)); - a->action = xstrdup(action); - a->desc = xstrdup(desc); - a->handler = handler; - a->flags.pw_req = pw_req_flag; - a->flags.atomic = atomic; - for (A = &ActionTable; *A; A = &(*A)->next); - *A = a; + ActionsList += anAction; debugs(16, 3, "CacheManager::registerAction: registered " << action); } + +/** + \ingroup CacheManagerInternal + * Locates an action in the actions registry ActionsList. +\retval NULL if Action not found +\retval CacheManagerAction* if the action was found + */ CacheManagerAction * CacheManager::findAction(char const * action) { - return cachemgrFindAction(action); -} - -/// \ingroup CacheManagerInternal -static CacheManagerAction * -cachemgrFindAction(const char *action) -{ - CacheManagerAction *a; - - for (a = ActionTable; a != NULL; a = a->next) { - if (0 == strcmp(a->action, action)) - return a; + CacheManagerActionList::iterator a; + + debugs(16, 5, "CacheManager::findAction: looking for action " << action); + for ( a = ActionsList.begin(); a != ActionsList.end(); a++) { + if (0 == strcmp((*a)->action, action)) { + debugs(16, 6, " found"); + return *a; + } } + debugs(16, 6, "Action not found."); return NULL; } -/// \ingroup CacheManagerInternal -static cachemgrStateData * -cachemgrParseUrl(const char *url) +/** + \ingroup CacheManagerInternal + * define whether the URL is a cache-manager URL and parse the action + * requested by the user. Checks via CacheManager::ActionProtection() that the + * item is accessible by the user. + \retval CacheManager::cachemgrStateData state object for the following handling + \retval NULL if the action can't be found or can't be accessed by the user + */ +CacheManager::cachemgrStateData * +CacheManager::ParseUrl(const char *url) { int t; LOCAL_ARRAY(char, host, MAX_URL); @@ -157,14 +154,14 @@ xstrncpy(request, "menu", MAX_URL); #endif - } else if ((a = cachemgrFindAction(request)) == NULL) { - debugs(16, 1, "cachemgrParseUrl: action '" << request << "' not found"); + } else if ((a = findAction(request)) == NULL) { + debugs(16, DBG_IMPORTANT, "CacheManager::ParseUrl: action '" << request << "' not found"); return NULL; } else { - prot = cachemgrActionProtection(a); + prot = ActionProtection(a); if (!strcmp(prot, "disabled") || !strcmp(prot, "hidden")) { - debugs(16, 1, "cachemgrParseUrl: action '" << request << "' is " << prot); + debugs(16, DBG_IMPORTANT, "CacheManager::ParseUrl: action '" << request << "' is " << prot); return NULL; } } @@ -182,8 +179,13 @@ } /// \ingroup CacheManagerInternal -static void -cachemgrParseHeaders(cachemgrStateData * mgr, const HttpRequest * request) +/* + \ingroup CacheManagerInternal + * Decodes the headers needed to perform user authentication and fills + * the details into the cachemgrStateData argument + */ +void +CacheManager::ParseHeaders(cachemgrStateData * mgr, const HttpRequest * request) { const char *basic_cookie; /* base 64 _decoded_ user:passwd pair */ const char *passwd_del; @@ -194,7 +196,7 @@ return; if (!(passwd_del = strchr(basic_cookie, ':'))) { - debugs(16, 1, "cachemgrParseHeaders: unknown basic_cookie format '" << basic_cookie << "'"); + debugs(16, DBG_IMPORTANT, "CacheManager::ParseHeaders: unknown basic_cookie format '" << basic_cookie << "'"); return; } @@ -210,7 +212,7 @@ mgr->passwd = xstrdup(passwd_del + 1); /* warning: this prints decoded password which maybe not what you want to do @?@ @?@ */ - debugs(16, 9, "cachemgrParseHeaders: got user: '" << mgr->user_name << "' passwd: '" << mgr->passwd << "'"); + debugs(16, 9, "CacheManager::ParseHeaders: got user: '" << mgr->user_name << "' passwd: '" << mgr->passwd << "'"); } /** @@ -220,11 +222,13 @@ \retval 1 if mgr->password is "disable" \retval !0 if mgr->password does not match configured password */ -static int -cachemgrCheckPassword(cachemgrStateData * mgr) +int +CacheManager::CheckPassword(cachemgrStateData * mgr) { - char *pwd = cachemgrPasswdGet(Config.passwd_list, mgr->action); - CacheManagerAction *a = cachemgrFindAction(mgr->action); + char *pwd = PasswdGet(Config.passwd_list, mgr->action); + CacheManagerAction *a = findAction(mgr->action); + + debugs(16, 4, "CacheManager::CheckPassword for action " << mgr->action); assert(a != NULL); if (pwd == NULL) @@ -243,8 +247,8 @@ } /// \ingroup CacheManagerInternal -static void -cachemgrStateFree(cachemgrStateData * mgr) +void +CacheManager::StateFree(cachemgrStateData * mgr) { safe_free(mgr->action); safe_free(mgr->user_name); @@ -253,16 +257,21 @@ xfree(mgr); } -// API +/** + \ingroup CacheManagerAPI + * Main entry point in the Cache Manager's activity. Gets called as part + * of the forward chain if the right URL is detected there. Initiates + * all needed internal work and renders the response. + */ void -cachemgrStart(int fd, HttpRequest * request, StoreEntry * entry) +CacheManager::Start(int fd, HttpRequest * request, StoreEntry * entry) { cachemgrStateData *mgr = NULL; ErrorState *err = NULL; CacheManagerAction *a; - debugs(16, 3, "objectcacheStart: '" << entry->url() << "'" ); + debugs(16, 3, "CacheManager::Start: '" << entry->url() << "'" ); - if ((mgr = cachemgrParseUrl(entry->url())) == NULL) { + if ((mgr = ParseUrl(entry->url())) == NULL) { err = errorCon(ERR_INVALID_URL, HTTP_NOT_FOUND, request); err->url = xstrdup(entry->url()); errorAppendEntry(entry, err); @@ -275,14 +284,14 @@ entry->lock(); entry->expires = squid_curtime; - debugs(16, 5, "CACHEMGR: " << fd_table[fd].ipaddr << " requesting '" << mgr->action << "'"); + debugs(16, 5, "CacheManager: " << fd_table[fd].ipaddr << " requesting '" << mgr->action << "'"); /* get additional info from request headers */ - cachemgrParseHeaders(mgr, request); + ParseHeaders(mgr, request); /* Check password */ - if (cachemgrCheckPassword(mgr) != 0) { + if (CheckPassword(mgr) != 0) { /* build error message */ ErrorState *err; HttpReply *rep; @@ -290,12 +299,12 @@ /* warn if user specified incorrect password */ if (mgr->passwd) - debugs(16, 1, "CACHEMGR: " << + debugs(16, DBG_IMPORTANT, "CacheManager: " << (mgr->user_name ? mgr->user_name : "") << "@" << fd_table[fd].ipaddr << ": incorrect password for '" << mgr->action << "'" ); else - debugs(16, 1, "CACHEMGR: " << + debugs(16, DBG_IMPORTANT, "CacheManager: " << (mgr->user_name ? mgr->user_name : "") << "@" << fd_table[fd].ipaddr << ": password needed for '" << mgr->action << "'" ); @@ -317,17 +326,17 @@ entry->complete(); - cachemgrStateFree(mgr); + StateFree(mgr); return; } - debugs(16, 1, "CACHEMGR: " << + debugs(16, DBG_IMPORTANT, "CacheManager: " << (mgr->user_name ? mgr->user_name : "") << "@" << fd_table[fd].ipaddr << " requesting '" << mgr->action << "'" ); /* retrieve object requested */ - a = cachemgrFindAction(mgr->action); + a = findAction(mgr->action); assert(a != NULL); entry->buffer(); @@ -345,51 +354,60 @@ entry->replaceHttpReply(rep); } - a->handler(entry); + a->run(entry); entry->flush(); if (a->flags.atomic) entry->complete(); - cachemgrStateFree(mgr); + StateFree(mgr); } /// \ingroup CacheManagerInternal -static void -cachemgrShutdown(StoreEntry * entryunused) +void CacheManager::ShutdownAction::run(StoreEntry *sentry) { - debugs(16, 0, "Shutdown by command."); + debugs(16, DBG_CRITICAL, "Shutdown by Cache Manager command."); shut_down(0); } +/// \ingroup CacheManagerInternal +CacheManager::ShutdownAction::ShutdownAction() : CacheManagerAction("shutdown","Shut Down the Squid Process", 1, 1) { } /// \ingroup CacheManagerInternal -static void -cachemgrReconfigure(StoreEntry * sentry) +void +CacheManager::ReconfigureAction::run(StoreEntry * sentry) { - debug(16, 0) ("Reconfigure by command.\n"); + debug(16, DBG_IMPORTANT) ("Reconfigure by Cache Manager command.\n"); storeAppendPrintf(sentry, "Reconfiguring Squid Process ...."); reconfigure(SIGHUP); } +/// \ingroup CacheManagerInternal +CacheManager::ReconfigureAction::ReconfigureAction() : CacheManagerAction("reconfigure","Reconfigure Squid", 1, 1) { } /// \ingroup CacheManagerInternal -static void -cachemgrOfflineToggle(StoreEntry * sentry) +void +CacheManager::OfflineToggleAction::run(StoreEntry * sentry) { Config.onoff.offline = !Config.onoff.offline; - debugs(16, 0, "offline_mode now " << (Config.onoff.offline ? "ON" : "OFF") << "."); + debugs(16, DBG_IMPORTANT, "offline_mode now " << (Config.onoff.offline ? "ON" : "OFF") << " by Cache Manager request."); storeAppendPrintf(sentry, "offline_mode is now %s\n", Config.onoff.offline ? "ON" : "OFF"); } +/// \ingroup CacheManagerInternal +CacheManager::OfflineToggleAction::OfflineToggleAction() : CacheManagerAction ("offline_toggle", "Toggle offline_mode setting", 1, 1) { } -/// \ingroup CacheManagerInternal -static const char * -cachemgrActionProtection(const CacheManagerAction * at) +/* + \ingroup CacheManagerInternal + * Renders the protection level text for an action. + * Also doubles as a check for the protection level. + */ +const char * +CacheManager::ActionProtection(const CacheManagerAction * at) { char *pwd; assert(at); - pwd = cachemgrPasswdGet(Config.passwd_list, at->action); + pwd = PasswdGet(Config.passwd_list, at->action); if (!pwd) return at->flags.pw_req ? "hidden" : "public"; @@ -404,20 +422,28 @@ } /// \ingroup CacheManagerInternal -static void -cachemgrMenu(StoreEntry * sentry) +void +CacheManager::MenuAction::run(StoreEntry * sentry) { - CacheManagerAction *a; + CacheManagerActionList::iterator a; - for (a = ActionTable; a != NULL; a = a->next) { + debugs(16, 4, "CacheManager::MenuCommand invoked"); + for (a = cmgr->ActionsList.begin(); a != cmgr->ActionsList.end(); ++a) { + debugs(16, 5, " showing action " << (*a)->action); storeAppendPrintf(sentry, " %-22s\t%-32s\t%s\n", - a->action, a->desc, cachemgrActionProtection(a)); + (*a)->action, (*a)->desc, cmgr->ActionProtection(*a)); } } +/// \ingroup CacheManagerInternal +CacheManager::MenuAction::MenuAction(CacheManager *aMgr) : CacheManagerAction ("menu", "Cache Manager Menu", 1, 1), cmgr(aMgr) { } -/// \ingroup CacheManagerInternal -static char * -cachemgrPasswdGet(cachemgr_passwd * a, const char *action) +/* + \ingroup CacheManagerInternal + * gets from the global Config the password the user would need to supply + * for the action she queried + */ +char * +CacheManager::PasswdGet(cachemgr_passwd * a, const char *action) { wordlist *w; @@ -435,3 +461,44 @@ return NULL; } + +CacheManager* CacheManager::instance=0; + +/** + \ingroup CacheManagerAPI + * Singleton accessor method. + */ +CacheManager* +CacheManager::GetInstance() { + if (instance == 0) { + debugs(16, 6, "CacheManager::GetInstance: starting cachemanager up"); + instance = new CacheManager; + } + return instance; +} + + +/// \ingroup CacheManagerInternal +void CacheManagerActionLegacy::run(StoreEntry *sentry) +{ + handler(sentry); +} +/// \ingroup CacheManagerInternal +CacheManagerAction::CacheManagerAction(char const *anAction, char const *aDesc, unsigned int isPwReq, unsigned int isAtomic) +{ + flags.pw_req = isPwReq; + flags.atomic = isAtomic; + action = xstrdup (anAction); + desc = xstrdup (aDesc); +} +/// \ingroup CacheManagerInternal +CacheManagerAction::~CacheManagerAction() +{ + xfree(action); + xfree(desc); +} + +/// \ingroup CacheManagerInternal +CacheManagerActionLegacy::CacheManagerActionLegacy(char const *anAction, char const *aDesc, unsigned int isPwReq, unsigned int isAtomic, OBJH *aHandler) : CacheManagerAction(anAction, aDesc, isPwReq, isAtomic), handler(aHandler) +{ +} === modified file 'src/carp.cc' --- src/carp.cc 2008-07-11 19:32:10 +0000 +++ src/carp.cc 2008-07-12 15:40:56 +0000 @@ -52,6 +52,13 @@ return (*p1)->weight - (*p2)->weight; } +static void +carpRegisterWithCacheManager(void) +{ + CacheManager::GetInstance()-> + registerAction("carp", "CARP information", carpCachemgr, 0, 1); +} + void carpInit(void) { @@ -70,6 +77,10 @@ safe_free(carp_peers); n_carp_peers = 0; + + /* initialize cache manager before we have a chance to leave the execution path */ + carpRegisterWithCacheManager(); + /* find out which peers we have */ for (p = Config.peers; p; p = p->next) { @@ -150,12 +161,6 @@ } } -void -carpRegisterWithCacheManager(CacheManager & manager) -{ - manager.registerAction("carp", "CARP information", carpCachemgr, 0, 1); -} - peer * carpSelectParent(HttpRequest * request) { === modified file 'src/cbdata.cc' --- src/cbdata.cc 2008-04-21 12:05:23 +0000 +++ src/cbdata.cc 2008-07-09 20:27:17 +0000 @@ -271,16 +271,17 @@ } void -cbdataRegisterWithCacheManager(CacheManager & manager) +cbdataRegisterWithCacheManager(void) { - manager.registerAction("cbdata", - "Callback Data Registry Contents", - cbdataDump, 0, 1); + CacheManager *manager=CacheManager::GetInstance(); + manager->registerAction("cbdata", + "Callback Data Registry Contents", + cbdataDump, 0, 1); #if CBDATA_DEBUG - manager.registerAction("cbdatahistory", - "Detailed call history for all current cbdata contents", - cbdataDumpHistory, 0, 1); + manager->registerAction("cbdatahistory", + "Detailed call history for all current cbdata contents", + cbdataDumpHistory, 0, 1); #endif } === modified file 'src/cbdata.h' --- src/cbdata.h 2008-02-27 04:49:32 +0000 +++ src/cbdata.h 2008-07-09 20:27:17 +0000 @@ -236,7 +236,7 @@ } cbdata_type; /// \ingroup CBDATAAPI -extern void cbdataRegisterWithCacheManager(CacheManager & manager); +extern void cbdataRegisterWithCacheManager(void); #if CBDATA_DEBUG extern void *cbdataInternalAllocDbg(cbdata_type type, const char *, int); === modified file 'src/client_db.cc' --- src/client_db.cc 2007-12-15 06:11:41 +0000 +++ src/client_db.cc 2008-07-12 15:40:56 +0000 @@ -75,26 +75,26 @@ return c; } +static void +clientdbRegisterWithCacheManager(void) +{ + CacheManager::GetInstance()-> + registerAction("client_list", "Cache Client List", clientdbDump, 0, 1); +} + void clientdbInit(void) { + clientdbRegisterWithCacheManager(); + if (client_table) return; client_table = hash_create((HASHCMP *) strcmp, CLIENT_DB_HASH_SIZE, hash_string); -} - -void -clientdbRegisterWithCacheManager(CacheManager & manager) -{ - manager.registerAction("client_list", - "Cache Client List", - clientdbDump, - 0, 1); -} - -void - + +} + +void clientdbUpdate(const IPAddress &addr, log_type ltype, protocol_t p, size_t size) { char key[MAX_IPSTRLEN]; === modified file 'src/comm_epoll.cc' --- src/comm_epoll.cc 2008-01-07 23:22:06 +0000 +++ src/comm_epoll.cc 2008-07-12 15:51:24 +0000 @@ -70,6 +70,7 @@ static struct epoll_event *pevents; +static void commEPollRegisterWithCacheManager(void); /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ @@ -97,6 +98,8 @@ if (kdpfd < 0) { fatalf("comm_select_init: epoll_create(): %s\n",xstrerror()); } + + commEPollRegisterWithCacheManager(); } static const char* epolltype_atoi(int x) @@ -214,12 +217,13 @@ static void commIncomingStats(StoreEntry * sentry); -void -commEPollRegisterWithCacheManager(CacheManager& manager) +static void +commEPollRegisterWithCacheManager(void) { - manager.registerAction("comm_epoll_incoming", - "comm_incoming() stats", - commIncomingStats, 0, 1); + CacheManager::GetInstance()-> + registerAction("comm_epoll_incoming", + "comm_incoming() stats", + commIncomingStats, 0, 1); } static void === modified file 'src/comm_epoll.h' --- src/comm_epoll.h 2006-05-29 06:14:59 +0000 +++ src/comm_epoll.h 2008-07-12 15:51:24 +0000 @@ -34,10 +34,4 @@ #ifndef SQUID_COMM_EPOLL_H #define SQUID_COMM_EPOLL_H -/* forward decls */ - -class CacheManager; - -extern void commEPollRegisterWithCacheManager(CacheManager & manager); - #endif /* SQUID_COMM_EPOLL_H */ === modified file 'src/comm_kqueue.cc' --- src/comm_kqueue.cc 2008-01-07 23:22:06 +0000 +++ src/comm_kqueue.cc 2008-07-12 15:51:24 +0000 @@ -91,6 +91,7 @@ static int kqoff; /* offset into the buffer */ static int max_poll_time = 1000; +static void commKQueueRegisterWithCacheManager(void); /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ /* Private functions */ @@ -177,6 +178,8 @@ kqlst = (struct kevent *)xmalloc(sizeof(*kqlst) * kqmax); zero_timespec.tv_sec = 0; zero_timespec.tv_nsec = 0; + + commKQueueRegisterWithCacheManager(); } /* @@ -324,8 +327,8 @@ max_poll_time = 10; } -void -commKQueueRegisterWithCacheManager(CacheManager & manager) +static void +commKQueueRegisterWithCacheManager(void) { } === modified file 'src/comm_kqueue.h' --- src/comm_kqueue.h 2006-05-29 06:14:59 +0000 +++ src/comm_kqueue.h 2008-07-12 15:51:24 +0000 @@ -34,10 +34,4 @@ #ifndef SQUID_COMM_KQUEUE_H #define SQUID_COMM_KQUEUE_H -/* forward decls */ - -class CacheManager; - -extern void commKQueueRegisterWithCacheManager(CacheManager & manager); - #endif /* SQUID_COMM_KQUEUE_H */ === modified file 'src/comm_poll.cc' --- src/comm_poll.cc 2008-02-13 06:02:13 +0000 +++ src/comm_poll.cc 2008-07-12 15:51:24 +0000 @@ -601,19 +601,22 @@ statHistCount(&statCounter.comm_dns_incoming, nevents); } + +static void +commPollRegisterWithCacheManager(void) +{ + CacheManager::GetInstance()-> + registerAction("comm_poll_incoming", + "comm_incoming() stats", + commIncomingStats, 0, 1); +} + void comm_select_init(void) -{} - -void -commPollRegisterWithCacheManager(CacheManager & manager) { - manager.registerAction("comm_poll_incoming", - "comm_incoming() stats", - commIncomingStats, 0, 1); + commPollRegisterWithCacheManager(); } - static void commIncomingStats(StoreEntry * sentry) { === modified file 'src/comm_poll.h' --- src/comm_poll.h 2006-05-29 06:14:59 +0000 +++ src/comm_poll.h 2008-07-12 15:51:24 +0000 @@ -34,10 +34,5 @@ #ifndef SQUID_COMM_POLL_H #define SQUID_COMM_POLL_H -/* forward decls */ - -class CacheManager; - -extern void commPollRegisterWithCacheManager(CacheManager & manager); #endif /* SQUID_COMM_POLL_H */ === modified file 'src/comm_select.cc' --- src/comm_select.cc 2008-03-16 21:48:45 +0000 +++ src/comm_select.cc 2008-07-12 15:51:24 +0000 @@ -654,6 +654,15 @@ statHistCount(&statCounter.comm_dns_incoming, nevents); } +static void +commSelectRegisterWithCacheManager(void) +{ + CacheManager::GetInstance()-> + registerAction("comm_select_incoming", + "comm_incoming() stats", + commIncomingStats, 0, 1); +} + void comm_select_init(void) { @@ -662,14 +671,8 @@ FD_ZERO(&global_readfds); FD_ZERO(&global_writefds); nreadfds = nwritefds = 0; -} -void -commSelectRegisterWithCacheManager(CacheManager & manager) -{ - manager.registerAction("comm_select_incoming", - "comm_incoming() stats", - commIncomingStats, 0, 1); + commSelectRegisterWithCacheManager(); } /* === modified file 'src/comm_select.h' --- src/comm_select.h 2006-05-29 06:14:59 +0000 +++ src/comm_select.h 2008-07-12 15:51:24 +0000 @@ -34,10 +34,5 @@ #ifndef SQUID_COMM_SELECT_H #define SQUID_COMM_SELECT_H -/* forward decls */ - -class CacheManager; - -extern void commSelectRegisterWithCacheManager(CacheManager & manager); #endif /* SQUID_COMM_SELECT_H */ === modified file 'src/comm_select_win32.cc' --- src/comm_select_win32.cc 2008-03-16 21:48:45 +0000 +++ src/comm_select_win32.cc 2008-07-11 12:40:57 +0000 @@ -684,12 +684,15 @@ FD_ZERO(&global_readfds); FD_ZERO(&global_writefds); nreadfds = nwritefds = 0; + + commSelectRegisterWithCacheManager(); } void -commSelectRegisterWithCacheManager(CacheManager & manager) +commSelectRegisterWithCacheManager(void) { - manager.registerAction("comm_select_incoming", + CacheManager::GetInstance()-> + registerAction("comm_select_incoming", "comm_incoming() stats", commIncomingStats, 0, 1); } === modified file 'src/debug.cc' (properties changed: +x to -x) === modified file 'src/delay_pools.cc' --- src/delay_pools.cc 2008-02-27 04:49:32 +0000 +++ src/delay_pools.cc 2008-07-13 08:37:43 +0000 @@ -550,16 +550,19 @@ unsigned short DelayPools::pools_ (0); void +DelayPools::RegisterWithCacheManager(void) +{ + CacheManager::GetInstance()-> + registerAction("delay", "Delay Pool Levels", Stats, 0, 1); +} + +void DelayPools::Init() { LastUpdate = getCurrentTime(); + RegisterWithCacheManager(); } -void -DelayPools::RegisterWithCacheManager(CacheManager & manager) -{ - manager.registerAction("delay", "Delay Pool Levels", Stats, 0, 1); -} void DelayPools::InitDelayData() === modified file 'src/dns.cc' --- src/dns.cc 2007-04-29 04:26:37 +0000 +++ src/dns.cc 2008-07-13 08:37:43 +0000 @@ -55,11 +55,20 @@ helperStats(sentry, dnsservers); } +static void +dnsRegisterWithCacheManager(void) +{ + CacheManager::GetInstance-> + registerAction("dns", "Dnsserver Statistics", dnsStats, 0, 1); +} + void dnsInit(void) { wordlist *w; + dnsRegisterWithCacheManager(); + if (!Config.Program.dnsserver) return; @@ -86,14 +95,6 @@ } void -dnsRegisterWithCacheManager(CacheManager & manager) -{ - manager.registerAction("dns", - "Dnsserver Statistics", - dnsStats, 0, 1); -} - -void dnsShutdown(void) { if (!dnsservers) === modified file 'src/dns_internal.cc' (properties changed: +x to -x) --- src/dns_internal.cc 2008-07-01 10:40:13 +0000 +++ src/dns_internal.cc 2008-07-12 15:40:56 +0000 @@ -1309,6 +1309,13 @@ /* ====================================================================== */ +static void +idnsRegisterWithCacheManager(void) +{ + CacheManager::GetInstance()-> + registerAction("idns", "Internal DNS Statistics", idnsStats, 0, 1); +} + void idnsInit(void) { @@ -1381,12 +1388,8 @@ idns_lookup_hash = hash_create((HASHCMP *) strcmp, 103, hash_string); init++; } -} -void -idnsRegisterWithCacheManager(CacheManager & manager) -{ - manager.registerAction("idns", "Internal DNS Statistics", idnsStats, 0, 1); + idnsRegisterWithCacheManager(); } void === modified file 'src/dnsserver.cc' (properties changed: +x to -x) === modified file 'src/event.cc' --- src/event.cc 2008-02-13 13:09:15 +0000 +++ src/event.cc 2008-07-09 21:34:13 +0000 @@ -149,9 +149,10 @@ } void -eventInit(CacheManager &manager) +eventInit(void) { - manager.registerAction("events", "Event Queue", eventDump, 0, 1); + CacheManager::GetInstance()-> + registerAction("events", "Event Queue", eventDump, 0, 1); } static void === modified file 'src/event.h' --- src/event.h 2008-02-13 06:27:42 +0000 +++ src/event.h 2008-07-09 21:34:13 +0000 @@ -49,7 +49,7 @@ 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 eventInit(void); SQUIDCEXTERN void eventFreeMemory(void); SQUIDCEXTERN int eventFind(EVH *, void *); === modified file 'src/external_acl.cc' --- src/external_acl.cc 2008-06-13 13:36:53 +0000 +++ src/external_acl.cc 2008-07-13 08:37:43 +0000 @@ -1293,6 +1293,15 @@ } } +static void +externalAclRegisterWithCacheManager(void) +{ + CacheManager::GetInstance()-> + registerAction("external_acl", + "External ACL stats", + externalAclStats, 0, 1); +} + void externalAclInit(void) { @@ -1323,14 +1332,8 @@ firstTimeInit = 0; CBDATA_INIT_TYPE_FREECB(externalAclState, free_externalAclState); } -} -void -externalAclRegisterWithCacheManager(CacheManager & manager) -{ - manager.registerAction("external_acl", - "External ACL stats", - externalAclStats, 0, 1); + externalAclRegisterWithCacheManager(); } void === modified file 'src/forward.cc' --- src/forward.cc 2008-06-29 02:03:22 +0000 +++ src/forward.cc 2008-07-12 15:11:10 +0000 @@ -256,7 +256,7 @@ return; case PROTO_CACHEOBJ: - cachemgrStart(client_fd, request, entry); + CacheManager::GetInstance()->Start(client_fd, request, entry); return; case PROTO_URN: @@ -1177,14 +1177,15 @@ logfile = logfileOpen(Config.Log.forward, 0, 1); #endif + + RegisterWithCacheManager(); } void -FwdState::RegisterWithCacheManager(CacheManager & manager) +FwdState::RegisterWithCacheManager(void) { - manager.registerAction("forward", - "Request Forwarding Statistics", - fwdStats, 0, 1); + CacheManager::GetInstance()-> + registerAction("forward", "Request Forwarding Statistics", fwdStats, 0, 1); } void === modified file 'src/forward.h' --- src/forward.h 2008-04-19 04:49:16 +0000 +++ src/forward.h 2008-07-13 08:37:43 +0000 @@ -3,7 +3,6 @@ /* forward decls */ -class CacheManager; class ErrorState; #include "comm.h" @@ -25,7 +24,6 @@ typedef RefCount Pointer; ~FwdState(); static void initModule(); - static void RegisterWithCacheManager(CacheManager & manager); static void fwdStart(int fd, StoreEntry *, HttpRequest *); void startComplete(FwdServer *); @@ -66,6 +64,7 @@ void updateHierarchyInfo(); void completed(); void retryOrBail(); + static void RegisterWithCacheManager(void); #if WIP_FWD_LOG === modified file 'src/fqdncache.cc' --- src/fqdncache.cc 2008-03-16 22:10:18 +0000 +++ src/fqdncache.cc 2008-07-12 15:40:56 +0000 @@ -582,6 +582,16 @@ #endif } +/// \ingroup FQDNCacheInternal +static void +fqdncacheRegisterWithCacheManager(void) +{ + CacheManager::GetInstance()-> + registerAction("fqdncache", "FQDN Cache Stats and Contents", + fqdnStats, 0, 1); + +} + /** \ingroup FQDNCacheAPI * @@ -593,6 +603,8 @@ { int n; + fqdncacheRegisterWithCacheManager(); + if (fqdn_table) return; @@ -616,16 +628,6 @@ sizeof(fqdncache_entry), 0); } -/// \ingroup FQDNCacheAPI -void -fqdncacheRegisterWithCacheManager(CacheManager & manager) -{ - manager.registerAction("fqdncache", - "FQDN Cache Stats and Contents", - fqdnStats, 0, 1); - -} - /** \ingroup FQDNCacheAPI * === modified file 'src/fs/Makefile.am' --- src/fs/Makefile.am 2008-04-14 13:51:31 +0000 +++ src/fs/Makefile.am 2008-07-13 21:40:50 +0000 @@ -36,7 +36,7 @@ ## Special Universal .h dependency test script ## aborts if error encountered -testHeaders: ufs/*.h coss/*.h +testHeaders: $(top_srcdir)/src/fs/ufs/*.h $(top_srcdir)/src/fs/coss/*.h $(SHELL) $(top_srcdir)/test-suite/testheaders.sh "$(CXXCOMPILE)" "ufs" || exit 1 $(SHELL) $(top_srcdir)/test-suite/testheaders.sh "$(CXXCOMPILE)" "coss" || exit 1 ## diskd/ has no .h files === modified file 'src/fs/coss/StoreFScoss.cc' --- src/fs/coss/StoreFScoss.cc 2006-09-04 03:05:19 +0000 +++ src/fs/coss/StoreFScoss.cc 2008-07-12 15:11:10 +0000 @@ -52,6 +52,7 @@ StoreFScoss::StoreFScoss() { FsAdd(*this); + registerWithCacheManager(); } char const * @@ -84,9 +85,9 @@ } void -StoreFScoss::registerWithCacheManager(CacheManager & manager) +StoreFScoss::registerWithCacheManager() { - manager.registerAction("coss", "COSS Stats", Stats, 0, 1); + CacheManager::GetInstance()->registerAction("coss", "COSS Stats", Stats, 0, 1); } void === modified file 'src/fs/coss/StoreFScoss.h' --- src/fs/coss/StoreFScoss.h 2008-03-20 23:20:58 +0000 +++ src/fs/coss/StoreFScoss.h 2008-07-09 14:28:16 +0000 @@ -86,7 +86,7 @@ virtual char const *type() const; virtual SwapDir *createSwapDir(); virtual void done(); - virtual void registerWithCacheManager(CacheManager & manager); + virtual void registerWithCacheManager(void); virtual void setup(); /* Not implemented */ StoreFScoss (StoreFScoss const &); === modified file 'src/ipcache.cc' --- src/ipcache.cc 2008-03-16 22:10:18 +0000 +++ src/ipcache.cc 2008-07-12 15:40:56 +0000 @@ -770,6 +770,17 @@ #endif } +/// \ingroup IPCacheInternal +static void +ipcacheRegisterWithCacheManager(void) +{ + CacheManager::GetInstance()-> + registerAction("ipcache", + "IP Cache Stats and Contents", + stat_ipcache_get, 0, 1); +} + + /** \ingroup IPCacheAPI * @@ -806,15 +817,8 @@ n = hashPrime(ipcache_high / 4); ip_table = hash_create((HASHCMP *) strcmp, n, hash4); memDataInit(MEM_IPCACHE_ENTRY, "ipcache_entry", sizeof(ipcache_entry), 0); -} -/// \ingroup IPCacheAPI -void -ipcacheRegisterWithCacheManager(CacheManager & manager) -{ - manager.registerAction("ipcache", - "IP Cache Stats and Contents", - stat_ipcache_get, 0, 1); + ipcacheRegisterWithCacheManager(); } /** === modified file 'src/main.cc' --- src/main.cc 2008-07-11 20:20:31 +0000 +++ src/main.cc 2008-07-14 13:35:09 +0000 @@ -35,7 +35,6 @@ #include "squid.h" #include "AccessLogEntry.h" #include "authenticate.h" -#include "CacheManager.h" #include "ConfigParser.h" #include "errorpage.h" #include "event.h" @@ -128,8 +127,6 @@ static void mainSetCwd(void); static int checkRunningPid(void); -static CacheManager manager; - #ifndef _SQUID_MSWIN_ static const char *squid_start_script = "squid_start"; #endif @@ -694,7 +691,7 @@ refererCloseLog(); errorClean(); enter_suid(); /* root to read config file */ - parseConfigFile(ConfigFile, manager); + parseConfigFile(ConfigFile); setUmask(Config.umask); Mem::Report(); setEffectiveUser(); @@ -731,7 +728,6 @@ serverConnectionsOpen(); neighbors_init(); - neighborsRegisterWithCacheManager(manager); storeDirOpenSwapLogs(); @@ -967,76 +963,17 @@ FwdState::initModule(); /* register the modules in the cache manager menus */ - accessLogRegisterWithCacheManager(manager); - asnRegisterWithCacheManager(manager); - authenticateRegisterWithCacheManager(&Config.authConfiguration, manager); - carpRegisterWithCacheManager(manager); - peerUserHashRegisterWithCacheManager(manager); - peerSourceHashRegisterWithCacheManager(manager); - cbdataRegisterWithCacheManager(manager); + + cbdataRegisterWithCacheManager(); /* These use separate calls so that the comm loops can eventually * coexist. */ -#ifdef USE_EPOLL - - commEPollRegisterWithCacheManager(manager); -#endif -#ifdef USE_KQUEUE - - commKQueueRegisterWithCacheManager(manager); -#endif -#ifdef USE_POLL - - commPollRegisterWithCacheManager(manager); -#endif -#if defined(USE_SELECT) || defined(USE_SELECT_WIN32) - - commSelectRegisterWithCacheManager(manager); -#endif - - clientdbRegisterWithCacheManager(manager); -#if DELAY_POOLS - - DelayPools::RegisterWithCacheManager(manager); -#endif - - DiskIOModule::RegisterAllModulesWithCacheManager(manager); -#if USE_DNSSERVERS - - dnsRegisterWithCacheManager(manager); -#endif - - eventInit(manager); - externalAclRegisterWithCacheManager(manager); - fqdncacheRegisterWithCacheManager(manager); - FwdState::RegisterWithCacheManager(manager); - httpHeaderRegisterWithCacheManager(manager); -#if !USE_DNSSERVERS - - idnsRegisterWithCacheManager(manager); -#endif - - ipcacheRegisterWithCacheManager(manager); - Mem::RegisterWithCacheManager(manager); - netdbRegisterWitHCacheManager(manager); - PconnModule::GetInstance()->registerWithCacheManager(manager); - redirectRegisterWithCacheManager(manager); - refreshRegisterWithCacheManager(manager); - statRegisterWithCacheManager(manager); - storeDigestRegisterWithCacheManager(manager); - StoreFileSystem::RegisterAllFsWithCacheManager(manager); - storeRegisterWithCacheManager(manager); - storeLogRegisterWithCacheManager(manager); -#if DEBUGSTRINGS - - StringRegistry::Instance().registerWithCacheManager(manager); -#endif - -#if USE_XPROF_STATS - - xprofRegisterWithCacheManager(manager); -#endif - + + eventInit(); + + // TODO: pconn is a good candidate for new-style registration + // PconnModule::GetInstance()->registerWithCacheManager(); + // moved to PconnModule::PconnModule() } #if USE_WCCP @@ -1053,7 +990,7 @@ neighbors_init(); - neighborsRegisterWithCacheManager(manager); + // neighborsRegisterWithCacheManager(); //moved to neighbors_init() if (Config.chroot_dir) no_suid(); @@ -1261,7 +1198,7 @@ /* we may want the parsing process to set this up in the future */ Store::Root(new StoreController); - parse_err = parseConfigFile(ConfigFile, manager); + parse_err = parseConfigFile(ConfigFile); Mem::Report(); === modified file 'src/mem.cc' --- src/mem.cc 2008-02-07 09:51:06 +0000 +++ src/mem.cc 2008-07-12 08:47:19 +0000 @@ -428,6 +428,8 @@ if (StrPools[i].pool->objectSize() != StrPoolsAttrs[i].obj_size) debugs(13, 1, "Notice: " << StrPoolsAttrs[i].name << " is " << StrPools[i].pool->objectSize() << " bytes instead of requested " << StrPoolsAttrs[i].obj_size << " bytes"); } + + RegisterWithCacheManager(); } void @@ -440,10 +442,9 @@ } void -Mem::RegisterWithCacheManager(CacheManager & manager) +Mem::RegisterWithCacheManager(void) { - manager.registerAction("mem", - "Memory Utilization", + CacheManager::GetInstance()->registerAction("mem", "Memory Utilization", Mem::Stats, 0, 1); } === modified file 'src/neighbors.cc' --- src/neighbors.cc 2008-07-11 20:20:31 +0000 +++ src/neighbors.cc 2008-07-14 13:35:09 +0000 @@ -488,6 +488,21 @@ first_ping = Config.peers; } +static void +neighborsRegisterWithCacheManager() +{ + CacheManager *manager = CacheManager::GetInstance(); + manager->registerAction("server_list", + "Peer Cache Statistics", + neighborDumpPeers, 0, 1); + + if (theInIcpConnection >= 0) { + manager->registerAction("non_peers", + "List of Unknown sites sending ICP messages", + neighborDumpNonPeers, 0, 1); + } +} + void neighbors_init(void) { @@ -499,6 +514,8 @@ peer *next = NULL; int fd = theInIcpConnection; + neighborsRegisterWithCacheManager(); + /* setup addrinfo for use */ nul.InitAddrInfo(AI); @@ -549,28 +566,6 @@ nul.FreeAddrInfo(AI); } -void -neighborsRegisterWithCacheManager(CacheManager & manager) -{ - manager.registerAction("server_list", - "Peer Cache Statistics", - neighborDumpPeers, 0, 1); - - if (theInIcpConnection >= 0) { - manager.registerAction("non_peers", - "List of Unknown sites sending ICP messages", - neighborDumpNonPeers, 0, 1); - } - - /* XXX FIXME: unregister if we were registered. Something like: - * else { - * CacheManagerAction * action = manager.findAction("non_peers"); - * if (action != NULL) - * manager.unregisterAction(action); - * } - */ -} - int neighborsUdpPing(HttpRequest * request, StoreEntry * entry, === modified file 'src/net_db.cc' --- src/net_db.cc 2008-03-16 22:10:18 +0000 +++ src/net_db.cc 2008-07-12 15:40:56 +0000 @@ -886,6 +886,15 @@ #endif /* USE_ICMP */ +static void +netdbRegisterWitHCacheManager(void) +{ +#if USE_ICMP + CacheManager::GetInstance()-> + registerAction("netdb", "Network Measurement Database", netdbDump, 0, 1); +#endif +} + /* PUBLIC FUNCTIONS */ void @@ -894,6 +903,8 @@ #if USE_ICMP int n; + netdbRegisterWitHCacheManager(); + if (addr_table) return; @@ -913,17 +924,6 @@ } void -netdbRegisterWitHCacheManager(CacheManager & manager) -{ -#if USE_ICMP - manager.registerAction("netdb", - "Network Measurement Database", - netdbDump, 0, 1); - -#endif -} - -void netdbPingSite(const char *hostname) { #if USE_ICMP === modified file 'src/pconn.cc' --- src/pconn.cc 2008-04-07 22:38:10 +0000 +++ src/pconn.cc 2008-07-12 15:11:10 +0000 @@ -328,6 +328,7 @@ pools = (PconnPool **) xcalloc(MAX_NUM_PCONN_POOLS, sizeof(*pools)); pconn_fds_pool = memPoolCreate("pconn_fds", PCONN_FDS_SZ * sizeof(int)); debugs(48, 0, "persistent connection module initialized"); + registerWithCacheManager(); } PconnModule * @@ -340,11 +341,12 @@ } void -PconnModule::registerWithCacheManager(CacheManager & manager) +PconnModule::registerWithCacheManager(void) { - manager.registerAction("pconn", - "Persistent Connection Utilization Histograms", - DumpWrapper, 0, 1); + CacheManager::GetInstance()-> + registerAction("pconn", + "Persistent Connection Utilization Histograms", + DumpWrapper, 0, 1); } void === modified file 'src/pconn.h' --- src/pconn.h 2008-03-20 11:30:19 +0000 +++ src/pconn.h 2008-07-13 08:37:43 +0000 @@ -11,7 +11,6 @@ \todo CLEANUP: Break multiple classes out of the generic pconn.h header */ -class CacheManager; class PconnPool; /* for CBDATA_CLASS2() macros */ @@ -90,7 +89,6 @@ }; -class CacheManager; class StoreEntry; class PconnPool; @@ -107,7 +105,7 @@ static void DumpWrapper(StoreEntry *e); PconnModule(); - void registerWithCacheManager(CacheManager & manager); + void registerWithCacheManager(void); void add(PconnPool *); === modified file 'src/peer_sourcehash.cc' --- src/peer_sourcehash.cc 2008-07-11 20:43:43 +0000 +++ src/peer_sourcehash.cc 2008-07-14 13:35:09 +0000 @@ -44,6 +44,7 @@ static int n_sourcehash_peers = 0; static peer **sourcehash_peers = NULL; static OBJH peerSourceHashCachemgr; +static void peerSourceHashRegisterWithCacheManager(void); static int peerSortWeight(const void *a, const void *b) @@ -87,6 +88,8 @@ W += p->weight; } + peerSourceHashRegisterWithCacheManager(); + if (n_sourcehash_peers == 0) return; @@ -151,10 +154,12 @@ } } -void -peerSourceHashRegisterWithCacheManager(CacheManager & manager) +static void +peerSourceHashRegisterWithCacheManager(void) { - manager.registerAction("sourcehash", "peer sourcehash information", peerSourceHashCachemgr, 0, 1); + CacheManager::GetInstance()-> + registerAction("sourcehash", "peer sourcehash information", + peerSourceHashCachemgr, 0, 1); } peer * === modified file 'src/peer_userhash.cc' --- src/peer_userhash.cc 2008-07-11 20:43:43 +0000 +++ src/peer_userhash.cc 2008-07-14 13:35:09 +0000 @@ -45,6 +45,7 @@ static int n_userhash_peers = 0; static peer **userhash_peers = NULL; static OBJH peerUserHashCachemgr; +static void peerUserHashRegisterWithCacheManager(void); static int peerSortWeight(const void *a, const void *b) @@ -74,6 +75,9 @@ n_userhash_peers = 0; /* find out which peers we have */ + + peerUserHashRegisterWithCacheManager(); + for (p = Config.peers; p; p = p->next) { if (!p->options.userhash) continue; @@ -152,10 +156,12 @@ } } -void -peerUserHashRegisterWithCacheManager(CacheManager & manager) +static void +peerUserHashRegisterWithCacheManager(void) { - manager.registerAction("userhash", "peer userhash information", peerUserHashCachemgr, 0, 1); + CacheManager::GetInstance()-> + registerAction("userhash", "peer userhash information", peerUserHashCachemgr, + 0, 1); } peer * === modified file 'src/pinger.cc' (properties changed: +x to -x) === modified file 'src/protos.h' --- src/protos.h 2008-07-11 20:26:11 +0000 +++ src/protos.h 2008-07-14 13:35:09 +0000 @@ -43,7 +43,6 @@ /* some parameters stil need this */ #include "wordlist.h" -class CacheManager; class HttpRequestMethod; @@ -83,7 +82,6 @@ /* client_side.c - FD related client side routines */ SQUIDCEXTERN void clientdbInit(void); -extern void clientdbRegisterWithCacheManager(CacheManager & manager); SQUIDCEXTERN void clientdbUpdate(const IPAddress &, log_type, protocol_t, size_t); @@ -135,13 +133,11 @@ SQUIDCEXTERN void dnsShutdown(void); SQUIDCEXTERN void dnsInit(void); -extern void dnsRegisterWithCacheManager(CacheManager & manager); SQUIDCEXTERN void dnsSubmit(const char *lookup, HLPCB * callback, void *data); /* dns_internal.c */ SQUIDCEXTERN void idnsInit(void); SQUIDCEXTERN void idnsShutdown(void); -extern void idnsRegisterWithCacheManager(CacheManager & manager); SQUIDCEXTERN void idnsALookup(const char *, IDNSCB *, void *); SQUIDCEXTERN void idnsPTRLookup(const IPAddress &, IDNSCB *, void *); @@ -167,7 +163,6 @@ SQUIDCEXTERN const char *fqdncache_gethostbyaddr(IPAddress &, int flags); SQUIDCEXTERN void fqdncache_init(void); -extern void fqdncacheRegisterWithCacheManager(CacheManager & manager); SQUIDCEXTERN void fqdnStats(StoreEntry *); SQUIDCEXTERN void fqdncacheReleaseInvalid(const char *); @@ -342,7 +337,6 @@ SQUIDCEXTERN void ipcacheInvalidate(const char *); SQUIDCEXTERN void ipcacheInvalidateNegative(const char *); SQUIDCEXTERN void ipcache_init(void); -extern void ipcacheRegisterWithCacheManager(CacheManager & manager); SQUIDCEXTERN void stat_ipcache_get(StoreEntry *); SQUIDCEXTERN void ipcacheCycleAddr(const char *name, ipcache_addrs *); @@ -391,7 +385,6 @@ SQUIDCEXTERN void neighborsUdpAck(const cache_key *, icp_common_t *, const IPAddress &); SQUIDCEXTERN void neighborAdd(const char *, const char *, int, int, int, int, int); SQUIDCEXTERN void neighbors_init(void); -extern void neighborsRegisterWithCacheManager(CacheManager & manager); SQUIDCEXTERN peer *peerFindByName(const char *); SQUIDCEXTERN peer *peerFindByNameAndPort(const char *, unsigned short); SQUIDCEXTERN peer *getDefaultParent(HttpRequest * request); @@ -415,7 +408,6 @@ SQUIDCEXTERN peer *whichPeer(const IPAddress &from); SQUIDCEXTERN void netdbInit(void); -extern void netdbRegisterWitHCacheManager(CacheManager & manager); SQUIDCEXTERN void netdbHandlePingReply(const IPAddress &from, int hops, int rtt); SQUIDCEXTERN void netdbPingSite(const char *hostname); @@ -453,7 +445,6 @@ SQUIDCEXTERN void urnStart(HttpRequest *, StoreEntry *); SQUIDCEXTERN void redirectInit(void); -extern void redirectRegisterWithCacheManager(CacheManager & manager); SQUIDCEXTERN void redirectShutdown(void); extern void refreshAddToList(const char *, int, time_t, int, time_t); @@ -464,7 +455,6 @@ extern int refreshCheckDigest(const StoreEntry *, time_t delta); extern time_t getMaxAge(const char *url); extern void refreshInit(void); -extern void refreshRegisterWithCacheManager(CacheManager & manager); extern const refresh_t *refreshLimits(const char *url); extern void serverConnectionsClose(void); @@ -477,7 +467,6 @@ extern void waisStart(FwdState *); SQUIDCEXTERN void statInit(void); -extern void statRegisterWithCacheManager(CacheManager & manager); SQUIDCEXTERN void statFreeMemory(void); SQUIDCEXTERN double median_svc_get(int, int); SQUIDCEXTERN void pconnHistCount(int, int); @@ -538,7 +527,6 @@ SQUIDCEXTERN void storeLogRotate(void); SQUIDCEXTERN void storeLogClose(void); SQUIDCEXTERN void storeLogOpen(void); -SQUIDCEXTERN void storeLogRegisterWithCacheManager(CacheManager &); /* @@ -563,7 +551,6 @@ * store_digest.c */ SQUIDCEXTERN void storeDigestInit(void); -extern void storeDigestRegisterWithCacheManager(CacheManager & manager); SQUIDCEXTERN void storeDigestNoteStoreReady(void); SQUIDCEXTERN void storeDigestScheduleRebuild(void); SQUIDCEXTERN void storeDigestDel(const StoreEntry * entry); @@ -588,7 +575,8 @@ */ SQUIDCEXTERN store_client *storeClientListAdd(StoreEntry * e, void *data); SQUIDCEXTERN int storeClientCopyPending(store_client *, StoreEntry * e, void *data); -SQUIDCEXTERN int storeUnregister(store_client * sc, StoreEntry * e, void *data); +SQUIDCEXTERN int storeUnregister(store_client * sc, StoreEntry * e, void *data) +; SQUIDCEXTERN int storePendingNClients(const StoreEntry * e); SQUIDCEXTERN int storeClientIsThisAClient(store_client * sc, void *someClient); @@ -729,15 +717,12 @@ SQUIDCEXTERN int internalHostnameIs(const char *); SQUIDCEXTERN void carpInit(void); -SQUIDCEXTERN void carpRegisterWithCacheManager(CacheManager & manager); SQUIDCEXTERN peer *carpSelectParent(HttpRequest *); SQUIDCEXTERN void peerUserHashInit(void); -SQUIDCEXTERN void peerUserHashRegisterWithCacheManager(CacheManager & manager); SQUIDCEXTERN peer * peerUserHashSelectParent(HttpRequest * request); SQUIDCEXTERN void peerSourceHashInit(void); -SQUIDCEXTERN void peerSourceHashRegisterWithCacheManager(CacheManager & manager); SQUIDCEXTERN peer * peerSourceHashSelectParent(HttpRequest * request); #if USE_LEAKFINDER === modified file 'src/redirect.cc' --- src/redirect.cc 2008-03-16 22:10:18 +0000 +++ src/redirect.cc 2008-07-12 15:40:56 +0000 @@ -176,11 +176,20 @@ helperSubmit(redirectors, buf, redirectHandleReply, r); } +static void +redirectRegisterWithCacheManager(void) +{ + CacheManager::GetInstance()-> + registerAction("redirector", "URL Redirector Stats", redirectStats, 0, 1); +} + void redirectInit(void) { static int init = 0; + redirectRegisterWithCacheManager(); + if (!Config.Program.redirect) return; @@ -204,14 +213,6 @@ } void -redirectRegisterWithCacheManager(CacheManager & manager) -{ - manager.registerAction("redirector", - "URL Redirector Stats", - redirectStats, 0, 1); -} - -void redirectShutdown(void) { if (!redirectors) === modified file 'src/refresh.cc' --- src/refresh.cc 2008-03-16 22:10:18 +0000 +++ src/refresh.cc 2008-07-12 15:40:56 +0000 @@ -574,6 +574,13 @@ refreshCountsStats(sentry, &refreshCounts[i]); } +static void +refreshRegisterWithCacheManager(void) +{ + CacheManager::GetInstance()-> + registerAction("refresh", "Refresh Algorithm Statistics", refreshStats, 0, 1); +} + void refreshInit(void) { @@ -596,14 +603,6 @@ DefaultRefresh.min = REFRESH_DEFAULT_MIN; DefaultRefresh.pct = REFRESH_DEFAULT_PCT; DefaultRefresh.max = REFRESH_DEFAULT_MAX; -} -void -refreshRegisterWithCacheManager(CacheManager & manager) -{ - manager.registerAction("refresh", - "Refresh Algorithm Statistics", - refreshStats, - 0, - 1); + refreshRegisterWithCacheManager(); } === modified file 'src/repl/Makefile.am' --- src/repl/Makefile.am 2008-04-14 13:51:31 +0000 +++ src/repl/Makefile.am 2008-07-13 21:40:50 +0000 @@ -22,7 +22,7 @@ ## Special Universal .h dependency test script ## aborts if error encountered -testHeaders: heap/*.h +testHeaders: $(top_srcdir)/src/repl/heap/*.h $(SHELL) $(top_srcdir)/test-suite/testheaders.sh "$(CXXCOMPILE)" "heap" || exit 1 ## ./ has no .h files. ## ./lru/ has no .h files. === modified file 'src/stat.cc' --- src/stat.cc 2008-07-02 03:49:07 +0000 +++ src/stat.cc 2008-07-12 15:40:56 +0000 @@ -1006,102 +1006,70 @@ storeAppendPrintf(sentry, "cpu_usage = %f%%\n", dpercent(ct, dt)); } - -void -statInit(void) -{ - int i; - debugs(18, 5, "statInit: Initializing..."); - - for (i = 0; i < N_COUNT_HIST; i++) - statCountersInit(&CountHist[i]); - - for (i = 0; i < N_COUNT_HOUR_HIST; i++) - statCountersInit(&CountHourHist[i]); - - statCountersInit(&statCounter); - - eventAdd("statAvgTick", statAvgTick, NULL, (double) COUNT_INTERVAL, 1); - - ClientActiveRequests.head = NULL; - - ClientActiveRequests.tail = NULL; -} - -void -statRegisterWithCacheManager(CacheManager & manager) -{ - manager.registerAction("info", - "General Runtime Information", - info_get, 0, 1); - - manager.registerAction("service_times", - "Service Times (Percentiles)", +static void +statRegisterWithCacheManager(void) +{ + CacheManager *manager = CacheManager::GetInstance(); + manager->registerAction("info", "General Runtime Information", + info_get, 0, 1); + manager->registerAction("service_times", "Service Times (Percentiles)", service_times, 0, 1); - - manager.registerAction("filedescriptors", - "Process Filedescriptor Allocation", + manager->registerAction("filedescriptors", "Process Filedescriptor Allocation", fde::DumpStats, 0, 1); - - manager.registerAction("objects", - "All Cache Objects", - stat_objects_get, 0, 0); - - manager.registerAction("vm_objects", - "In-Memory and In-Transit Objects", + manager->registerAction("objects", "All Cache Objects", stat_objects_get, 0, 0); + manager->registerAction("vm_objects", "In-Memory and In-Transit Objects", stat_vmobjects_get, 0, 0); - -#if DEBUG_OPENFD - - manager.registerAction("openfd_objects", - "Objects with Swapout files open", - statOpenfdObj, 0, 0); - -#endif - - manager.registerAction("io", - "Server-side network read() size histograms", + manager->registerAction("io", "Server-side network read() size histograms", stat_io_get, 0, 1); - - manager.registerAction("counters", - "Traffic and Resource Counters", + manager->registerAction("counters", "Traffic and Resource Counters", statCountersDump, 0, 1); - - manager.registerAction("peer_select", - "Peer Selection Algorithms", + manager->registerAction("peer_select", "Peer Selection Algorithms", statPeerSelect, 0, 1); - - manager.registerAction("digest_stats", - "Cache Digest and ICP blob", + manager->registerAction("digest_stats", "Cache Digest and ICP blob", statDigestBlob, 0, 1); - - manager.registerAction("5min", - "5 Minute Average of Counters", + manager->registerAction("5min", "5 Minute Average of Counters", statAvg5min, 0, 1); - - manager.registerAction("60min", - "60 Minute Average of Counters", + manager->registerAction("60min", "60 Minute Average of Counters", statAvg60min, 0, 1); - - manager.registerAction("utilization", - "Cache Utilization", + manager->registerAction("utilization", "Cache Utilization", statUtilization, 0, 1); - -#if STAT_GRAPHS - - manager.registerAction("graph_variables", - "Display cache metrics graphically", - statGraphDump, 0, 1); - -#endif - - manager.registerAction("histograms", - "Full Histogram Counts", + manager->registerAction("histograms", "Full Histogram Counts", statCountersHistograms, 0, 1); - - manager.registerAction("active_requests", + manager->registerAction("active_requests", "Client-side Active Requests", statClientRequests, 0, 1); +#if DEBUG_OPENFD + manager->registerAction("openfd_objects", "Objects with Swapout files open", + statOpenfdObj, 0, 0); +#endif +#if STAT_GRAPHS + manager->registerAction("graph_variables", "Display cache metrics graphically", + statGraphDump, 0, 1); +#endif +} + + +void +statInit(void) +{ + int i; + debugs(18, 5, "statInit: Initializing..."); + + for (i = 0; i < N_COUNT_HIST; i++) + statCountersInit(&CountHist[i]); + + for (i = 0; i < N_COUNT_HOUR_HIST; i++) + statCountersInit(&CountHourHist[i]); + + statCountersInit(&statCounter); + + eventAdd("statAvgTick", statAvgTick, NULL, (double) COUNT_INTERVAL, 1); + + ClientActiveRequests.head = NULL; + + ClientActiveRequests.tail = NULL; + + statRegisterWithCacheManager(); } static void === modified file 'src/store.cc' --- src/store.cc 2008-06-05 12:01:09 +0000 +++ src/store.cc 2008-07-13 08:37:43 +0000 @@ -1387,6 +1387,16 @@ return 0; } +static void +storeRegisterWithCacheManager(void) +{ + CacheManager *manager=CacheManager::GetInstance(); + manager->registerAction("storedir", "Store Directory Stats", Store::Stats, 0, 1); + manager->registerAction("store_io", "Store IO Interface Stats", storeIOStats, 0, 1); + manager->registerAction("store_check_cachable_stats", "storeCheckCachable() Stats", + storeCheckCachableStats, 0, 1); +} + void storeInit(void) { @@ -1397,20 +1407,8 @@ eventAdd("storeLateRelease", storeLateRelease, NULL, 1.0, 1); Store::Root().init(); storeRebuildStart(); -} -void -storeRegisterWithCacheManager(CacheManager & manager) -{ - manager.registerAction("storedir", - "Store Directory Stats", - Store::Stats, 0, 1); - manager.registerAction("store_check_cachable_stats", - "storeCheckCachable() Stats", - storeCheckCachableStats, 0, 1); - manager.registerAction("store_io", - "Store IO Interface Stats", - storeIOStats, 0, 1); + storeRegisterWithCacheManager(); } void === modified file 'src/store_digest.cc' --- src/store_digest.cc 2008-03-16 22:10:18 +0000 +++ src/store_digest.cc 2008-07-12 15:40:56 +0000 @@ -101,6 +101,13 @@ #endif /* USE_CACHE_DIGESTS */ +static void +storeDigestRegisterWithCacheManager(void) +{ + CacheManager::GetInstance()-> + registerAction("store_digest", "Store Digest", storeDigestReport, 0, 1); +} + /* * PUBLIC FUNCTIONS */ @@ -108,6 +115,8 @@ void storeDigestInit(void) { + storeDigestRegisterWithCacheManager(); + #if USE_CACHE_DIGESTS const int cap = storeDigestCalcCap(); @@ -130,13 +139,6 @@ #endif } -void -storeDigestRegisterWithCacheManager(CacheManager & manager) -{ - manager.registerAction("store_digest", "Store Digest", - storeDigestReport, 0, 1); -} - /* called when store_rebuild completes */ void storeDigestNoteStoreReady(void) === modified file 'src/store_log.cc' --- src/store_log.cc 2008-01-20 15:54:28 +0000 +++ src/store_log.cc 2008-07-12 15:40:56 +0000 @@ -124,9 +124,19 @@ storelog = NULL; } +static void +storeLogRegisterWithCacheManager(void) +{ + CacheManager::GetInstance()-> + registerAction("store_log_tags", "Histogram of store.log tags", + storeLogTagsHist, 0, 1); +} + void storeLogOpen(void) { + storeLogRegisterWithCacheManager(); + if (strcmp(Config.Log.store, "none") == 0) { debugs(20, 1, "Store logging disabled"); return; @@ -136,14 +146,6 @@ } void -storeLogRegisterWithCacheManager(CacheManager & manager) -{ - manager.registerAction("store_log_tags", - "Histogram of store.log tags", - storeLogTagsHist, 0, 1); -} - -void storeLogTagsHist(StoreEntry *e) { int tag; === modified file 'src/structs.h' (properties changed: +x to -x) === added file 'src/tests/stub_cache_manager.cc' --- src/tests/stub_cache_manager.cc 1970-01-01 00:00:00 +0000 +++ src/tests/stub_cache_manager.cc 2008-07-13 21:40:50 +0000 @@ -0,0 +1,70 @@ +/* + * AUTHOR: Francesco Chemolli + * + * 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 "CacheManager.h" +#include "squid.h" + +CacheManager::CacheManager() +{ +} + +void +CacheManager::registerAction(char const * action, char const * desc, OBJH * handler, int pw_req_flag, int atomic) +{ + fatal("Not implemented"); +} + +void +CacheManager::registerAction(CacheManagerAction *anAction) +{ + fatal("Not implemented"); +} + +CacheManagerAction * +CacheManager::findAction(char const * action) +{ + fatal("Not implemented"); + return 0; //notreached +} + +void +CacheManager::Start(int fd, HttpRequest * request, StoreEntry * entry) +{ + fatal("Not implemented"); +} + +CacheManager* +CacheManager::GetInstance() +{ + fatal("Not implemented"); + return 0; //notreached +} + === modified file 'src/tests/testCacheManager.cc' --- src/tests/testCacheManager.cc 2008-05-01 15:59:41 +0000 +++ src/tests/testCacheManager.cc 2008-07-13 21:40:50 +0000 @@ -32,7 +32,7 @@ void testCacheManager::testCreate() { - CacheManager(); + CacheManager()::GetInstance(); //it's a singleton.. } /* an action to register */ === modified file 'tools/squidclient.cc' (properties changed: +x to -x) # Begin bundle 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 a4KtaBDIRxlChDWUhu26ZeLqLxEThFnDaOEZIjR1m09U+N2Vr14dVVjHibj5W1V0pSz1N7SROSLu Ept+VG7tV2+mjVhY1WbqqJJPGXfey7p9PhAtBiHDQUTMnGQLIwwuvzNQMlQ4oYVFir2DRTp+f4mL iz7vUNW2hwqiGyPGbsyzKaPeIiOk3WriNm7bXbaIvCLNV4uXS6mshg0ePTtVQ00ONO3bC0VnHPfT 7fajlE12+mklNZNlqwz9TNUvbxEplEoiI6bNXT/Vg11ucMq1lL07Up7cKvb8Pb26W5z5HrudO3qe b0qRKtaF1t8w03AOAlVgOzGo1LQNWq8HWLTA4jC9jiYUIANamigTggMpRURCDgtKQlbgomVVTpdL GDVHGi0+OF4ZceNVFK7PcJ8h5OQDJN+fNDk7O5ab95smDuLBntv6Tmx26UXK9OGz0ttu9bXVhZv7 YcPyIQRlJEIOJDdyp3o9Payj2UapvSz0uqu9JKPrgWRKIhs7EIh9Kua/Tl6WUXTdHCTRu5el11Xp d23emTdRs/wij7aJNVjlqq5cuVXT44VVTWVN1GiTDp+8/wjy/q6TlWdfnyjhWtZ+JNm7V45WeN3b Ldlllq5aNDQmw1VTWYckniiSThw4WJN1Gjdw4TauurNuNHKlNWMcJz0XartnCTVuSSWapLN3KThN o6ZSc88um7Lhw6e3t/JVw8enjdV3bZdwsr6dPvh04bul02zVo5bPXqbpV21e1m6bd4kwqw2aOVmW F1H7mz1ERGWN20seIwkrSunvDhh7ej+lW748cJo2juW8okknu4Pnzpos7UfTxq4TeHp8UcMrvSb6 emDhy1TJC7huos773bOnLZqoymko7cpqLvaSaTtZvvNw0YdpNE26q7VhdNwH0lgHmHUtTOt5QHil wMLUTEvruy3WlRoZk5zaeKPQNV6LNI+OYOWoBYjzNwCeC41CpjEyhvAbROm3yTKKNiPDoUfUeAB2 IEOJAu5EAnU13TkrIwQgxirleZWcHuhBznnS35nTw0+lQZFUUWIyKB+MaMWKPCZOiNoECDIvT6xM Soaq2siECxFoJu1o9V4lXH4PsabbIPpwYVtCMEAQiATERAhXoVDXPiAzGEaYA8QAG1a92VFwaxGS PSKPTG5WI+nrehn3goNVs3QRgaQiLAAiVAghStqwoRcGcV9E+vc9iMyb7KHdEhmwVQy5sCowd2Qc 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 PTOamqT3vs9v2G7VeLvTSPt2k9Lqppzh4l4pNF11KLPbzzLh+UD8j8aftr6/n/XqXdlI1dNCz9T8 3irph+b6fSuiGtX3F6P0lS1MQw0imu6+H5tycccySdkhOTZKBnzH0Lu1nDCyb0427cdER0o407XT /zgNkna+hZw15W4Vj07UYcPEn6fptR41enT02nWspdqvjS7ddlOOFWqSjD9Shqwq7VYSSXSP4x7h Fmps88s2LPEnjZl9HTpu1ZSdKqrtlFk1mzR2uuws8VatFGGFmUmzyiVG6jRonrpwsnWuzKSii6rC hNoqkZcruEnCzRsw3VVTaNHDDVw3csNHbtN7Zbt2jZNnO7/JEOo688bNmqbo5Yxh4u8brniirxou myk4cNWGi7Vs/JJ55NZs4YVOHD2skoqmk8VXTZYTZXVYJvHjx2s559umGy1vGxhlRw5Uelniiazh 2w5SNVnT/OEVD96N02yzLcmTTTe27dv/SXtRl69dvFnL29qtFVXSSrV2y3avFGqTKrpqy+KvSbZq 1SVTXf1IdbtVnSs12zldw1cNXDVV/Y0bJOWqjDKj161bKviTdqyk9pLNNLqrNdnjVnN3artd7cs5 1Nkiytf7/SIioas3FHQGY6QXH2o9r6I4x5L8F0Ccg2ujk5nx4Caxh3HVbuCogqbAHMCcytR8EK9C CQDKzEQBWKAxUsH8Xm3BcSfCMDQCMFNUEUDololewfqwwyCFd8Yj66BpuNaE6CvGpzVqHtgGd+PZ fOAr2cF7cu5ujYEC3JFjyiXaSzogCxFhodY2xeePumpHrZHjfbIEn2MT4bPcsyE/H1OWGaVOYoYZ Kr1zOQh0o3d0K69XYTNBsdByuhOA4Acbuk7uTlnKsaUZARBMBraFzXtl7Sk+6R3qsiHo0PZ8+TRA cPF1MKenrQqtFYKvTe8zNJg3s21qsMtE4xjSBcGgxz8/f1fnGwA85wZ5vFtw8tJ2lRxirovAaP8y FYgkXqIhINkKnRAmSSzuQkF7M5geHk8A6zOaGDKMSfunXbNruF36q00iMZ1aLsrybIQiG7KS7f+G VcxskZScP0Czf4smzE0JyhA1pNGjlqg0VIJtbmtUapZf0ss/t/j0xBy+N0Jjqoh4q+13t9untZZR Zyq9NW76e3Tlw6/ofN9tfjaSalKUJ0rOpvOUqdVsRpeIPRFkmFknijSIvCvKa8qorOV1HjU7eb3e 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 qWtWfAbUWhU9o8wgIE7r5efbwf3Rv2kYPbYVEm8JvWcpegB4gAyA+KOh00Qa2PNEpY1NZpG01urF be3mGeaVOnt6QO0nYBQ+LW3rLa0+hihIwt7y3DvvxksrHKvAxBtIHxUqUq6FCfZ1YPtPtPzD4WA8 7gY2+tGZ8KmRXkCjv9KOL2Z6lsbLlTtgMiSJIKJCALCIMkgISDICSIyJzX2bsXsdPIaszlz95QUP 7JmJ/ed2M927KbZnsApPd+VnqDwPXJCEB6j4psB/YPu3IlS4iEEofFAq0P3pjrdPn0n0pKVEv8qB SAkCKIRgwJAQYMEBkgoRawqMQsgSFkqAwgEIKyjGhQYUIkBFYixjNEJjCgVPljKhEKlCIgjYgdrU 1BvaqkYSBZooh7Am5xu6h3NSB+eB+gOIaJAPZJ348d9yAczvwjIiCxYooiAsBZFJFgKiRRRYKRYA oCxYLEVkWKCkVYoQRkWRQFJGJIoKKAsGICyCgKsIqiigsISBoPWQvR6HH9QyHAd8E/hP4j/QfYTR A/bo/vn7ZRMPwqm7RtBQfxMsEcKddd+Pm/y+zjY8Ioz27P4bxhr+LfH6m4wWH8/82zPi+yqq/pGo 1BkRhQMxmYTmAPvCjcXiTgjdsbxKT+fv5RVV7VtSb0/5n06g+2z8Nlmqrdu/9DhouZNk1nCRoq0X aJJMuH4ZXbP9v/s1fqaJNHL9VHhVy4Xxh2sqVlGWEnTSJZ0vpjqnlZeeVb74b72Xz33+wQiHLDow 4buGy7t6PSrBRZsIRDZrGEpv6nirZZNI7TbNnpo0ms0cOWjRoq4asrLsN1Ht2u3dtGq7pZl7UTUb KKtnLRwk0anB0jdu5VVZVVdJJOGGjhuq6Zf71Zsk6tUlGXDko6YbN27ZdZN2s5cdJUduWi5lldYm amqgMpOXSdFGrVu4YSNG7dlRw0WbPtVwSaJNXbLtw7bNFlEnCzdZky1VNlWFnTD+MN5HTtVVRZPh 4k0WbKsNVVeXbVsk3XTZXapuFVVlEna7lwmy3TctUi7pw5VZSbMNWy7Zy0bOEupQl21cKNU0mhsm 5dq2UTk5YSVdNk12jRh22aMpNklmjtJl/OEMqvx+NLqUonOceG5om9JKPR02Y9JWTct1Th03ZbtG WFGj066u2dHDL00arKJtXCbDg4fZF0ekd3UT2atWXfd3b29JJPSr2q8bKKvaq72kusqw4WWZe00m zKayj1HjR2k1ZMuH/qiNGrRhJRw4f86PizCzDh797GrxHpy1ZUaHtNJ8bbeGGrUmw0cvaaSSiRVq km9NtvbZy3UaN3C7VRVppzwly/D9spSl/F/D+NKFVJxKcRV1d2y7avtf6Pwmuy9O+8PT09qJNn02 bkmrCrh9pN9//C1aMuG7dJqukk4cPwsqm7f8+U/U2Xb05WvHDDdVNw9untlZZZs6TbO3bpTVNDhR Zy+ghjMR0owxGBqN27eB805WHWZiSFm/VNpoKKfHp+4fk7SfhdJ4k9vtNd+Sia6j6ScripcWFAwM xgQsKhsfHvp+6Qrxf6WNhRo0wMD1hA9+Uzm44Gg1nn+j1sFYCKCRFVCCqVKFEUgRBS7HzFPzByhq DUHQa1PyIePCgFCNUJIeNEolCBSoUBum4VCeqOp6TnOk2Hgcpccp1FpcXlheZDsN5UxmBhdllo1f taP5MLv4uGiqbLhlJddo/0xq/ee/z4UZZPFHLZ+3T+vSERq9MnKLLRA+EwcEzTq2IzF4gKzYODho MRQGJUUqIjJ7jVyGc3B9qLvt08bLruHxNq+NX0q0bPGV0m6ho3buW7Kbl4i5/4oSGSJUnELJMulb TbOGFXThoysu4WWOCTDhy3dpstFGjRJNRku1bqKrNE27KTaPnydHZaVLiH2IjpNRv6xDuA56nzAV iII/RUVGhe9wXvqUD2B0AFPYYAKaQqB+/r+xEQj+n/N+2YUIfvLiYYfjUH/O/lNN8PoV5iiLSF6U QsFbaItg+73gHJhJWIUYvQWUrsHmFcMOkcifoA8CloYkiqKfpDsHthqBW55XOYEpKOg9r7yBY8Di ARhESMFRYCwJICBAYDAkUhCKEBCICEAigBiHCCKYgUbYG4iqiIgJJE72fwCsmp8vzwmB9/rNLTFk h+IYn65br1++BedR4ZgF+HX8fLEq4LKgII0O0mURssQ/aoxkd4mkuTJdQpPJHIlQeAFBD+mLru5w +gQNIFfu+2n3yFaNrag8BXUjrQgSRfwyFihrDS4iHXRdqFgCsFPuBOUZJCBEYEQgT2pxOQqy2HUF iEYMaNRpEQqhTIAaaVr+OqjwSSK/XtJRBEwuYegsyGeNm26zCHnnf9iWt4WiAYidApkqAWb9v5Ac wbgzJY7NCCIIgjFFFFVGDGCJ6HNzPMVdl+TRyAHHnKNt55g/fgPKFu8LD5lgZSDGCIfIeXfzERLq 9cPnev1srQb7PrEne14X4wh+tH7Kw+kwEnffIQj5rQCtGIlmQ2tDgWEOY3LoNBcWsuFHtw0e2Xpl dVR/vMOGiTVuw9GXxoso6GsoiXS7hVFlWjVok5fx/6cpWfZu0emCqN+XbCl25l09a0pmWdqc64v5 vizi9tJYUSdrN0ZcpPTBVVw5ZXVJNnThyy6VVauU1HD6Cvbp8dKKxswoo5auSyqqaTldhu8YSaF1 1VU2U3bDxy0ZUeFEmqbVJNs5XjVKGWzla6XjVRMsws1bMuUm67DLlw6SUSNGWyrlyu6ctFlk10nv 30Tnsw7eddLOXDte+S7hZub78FHbpJJs1UaOBR0o6UTXVdsOUkkk0myiTp28ZaN3KrDVw5aMu+5u 1nTLDGOnblhJw5drO3SyTDxVRR05eOmXB45cOXKbLRyy3UcO+/C67Dpq6dO83bPGVFbTVWScPFHS aS6yTRsoqoZarvFEmF2zls2WVWZcrpJmqpswoo0XKuVlzhoaMqOFGjZ40dKsMrNFnLZs5UbKsqrL rtUnBRsoq0wunUsy0TXeeVcOWrVs4Zzow8dpG0IRtLhOezddYw2UeNVnwPDtV6asJtF0npwoo1cG HLZVq6dFGzdok3eeaLuHCiTx6Sf64pKK7zh08WVeP2kTpjR4mu8UbEk03t4mwsyu0Zmy2Zeyxqu5 UFlV2zodG7MMJt1XaREfnD5evKU6Scpo1bptFWqaj580e5MJ5bPCbV4scLN27RJ0uqy9Jv1ZaqtV mWyb9PWAenVsDzB8ajXnNJynKaDYajQUNxUMXGhvOQ4k0n24bvb8Pwy4cOlnaSjZ+bZJhNo3Ybpu HC7R33V24PHjprukFLbPGV1bTbbTYcNTDRJq7YcvCajRw5dqNUmh4syoZddYVUpPpLLDpo0auVlH DR+HqEfpEIhvFUrMMHTRl6bu+6sqUq8WdtGrZs3UYe1mF3tRV6e3SESeKtU2OEqG5lZwcN0vqEPX bJ+iMK948eJHKrhL6/xilMLvRZ29PbpdJ6avr65WdmHDLR2u4fKpqqP+u/wl/Mj9yFf19tkn5vyd t3Lp+CH09NU34UXaNWj7+/1Mt2VrTfhJyu1cLJH2u3XXWaabu2z9V8JfkolHcf9Tn8f8fYfkRNKJ Sw/LKKc4HejgeFQeUgyZEaAvPyvwUyAET0BecAuDkBXyUOpcV35j5Zd4oWhoLEM4Gt4gvAtG5AuG 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 QikVfbQSi0hYZSqaaLEPzGj/+LuSKcKEhfkM3xA=