From: Alex Rousskov Date: Thu, 14 Apr 2011 04:22:25 +0000 (-0600) Subject: Added RunnersRegistry, an API to register and, later, run a group of actions. X-Git-Tag: take06~29 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6d57128b2cc5d8dc7307438bdea1b0fd496206dc;p=thirdparty%2Fsquid.git Added RunnersRegistry, an API to register and, later, run a group of actions. Useful for keeping general initialization management code (e.g., main.cc) independent from specific initialization code (e.g., Ipc::Mem::Init) during staged initialization and cleaning. --- diff --git a/src/base/Makefile.am b/src/base/Makefile.am index 408d20984b..cd38376ceb 100644 --- a/src/base/Makefile.am +++ b/src/base/Makefile.am @@ -15,6 +15,8 @@ libbase_la_SOURCES = \ TidyPointer.h \ CbcPointer.h \ InstanceId.h \ + RunnersRegistry.cc \ + RunnersRegistry.h \ Subscription.h \ TextException.cc \ TextException.h diff --git a/src/base/RunnersRegistry.cc b/src/base/RunnersRegistry.cc new file mode 100644 index 0000000000..87ac733f7b --- /dev/null +++ b/src/base/RunnersRegistry.cc @@ -0,0 +1,58 @@ +#include "config.h" +#include "base/RunnersRegistry.h" +#include +#include + +typedef std::list Runners; +typedef std::map Registries; + +/// all known registries +static Registries *TheRegistries = NULL; + +/// returns the requested runners list, initializing structures as needed +static Runners & +GetRunners(const RunnerRegistry ®istryId) +{ + if (!TheRegistries) + TheRegistries = new Registries; + + if (TheRegistries->find(registryId) == TheRegistries->end()) + (*TheRegistries)[registryId] = new Runners; + + return *(*TheRegistries)[registryId]; +} + +int +RegisterRunner(const RunnerRegistry ®istryId, RegisteredRunner *rr) +{ + Runners &runners = GetRunners(registryId); + runners.push_back(rr); + return runners.size(); +} + +int +ActivateRegistered(const RunnerRegistry ®istryId) +{ + Runners &runners = GetRunners(registryId); + typedef Runners::iterator RRI; + for (RRI i = runners.begin(); i != runners.end(); ++i) + (*i)->run(registryId); + return runners.size(); +} + +void +DeactivateRegistered(const RunnerRegistry ®istryId) +{ + Runners &runners = GetRunners(registryId); + typedef Runners::iterator RRI; + while (!runners.empty()) { + delete runners.back(); + runners.pop_back(); + } +} + +bool +UseThisStatic(const void *) +{ + return true; +} diff --git a/src/base/RunnersRegistry.h b/src/base/RunnersRegistry.h new file mode 100644 index 0000000000..4203a88573 --- /dev/null +++ b/src/base/RunnersRegistry.h @@ -0,0 +1,49 @@ +#ifndef SQUID_BASE_RUNNERSREGISTRY_H +#define SQUID_BASE_RUNNERSREGISTRY_H + +/** + * This API allows different modules to register with a well-known registry, + * be activated by some central processor at some registry-specific time, and + * be deactiveated by some central processor at some registry-specific time. + * + * For example, main.cc may activate registered I/O modules after parsing + * squid.conf and deactivate them before exiting. + * + */ + +/// well-known registries (currently, deactivation is not performed for these) +typedef enum { + rrAfterConfig, ///< activated by main.cc after parsing squid.conf + rrEnd ///< not a real registry, just a label to mark the end of enum +} RunnerRegistry; + +/// a runnable registrant API +class RegisteredRunner { +public: + // called when this runner's registry is deactivated + virtual ~RegisteredRunner() {} + + // called when this runner's registry is activated + virtual void run(const RunnerRegistry &r) = 0; +}; + + +/// registers a given runner with the given registry and returns registry count +int RegisterRunner(const RunnerRegistry ®istry, RegisteredRunner *rr); + +/// calls run() methods of all runners in the given registry +int ActivateRegistered(const RunnerRegistry ®istry); +/// deletes all runners in the given registry +void DeactivateRegistered(const RunnerRegistry ®istry); + + +/// convenience function to "use" an otherwise unreferenced static variable +bool UseThisStatic(const void *); + +/// convenience macro: register one RegisteredRunner kid as early as possible +#define RunnerRegistrationEntry(Registry, Who) \ + static const bool Who ## _RegisteredWith_ ## Registry = \ + RegisterRunner(Registry, new Who) > 0 && \ + UseThisStatic(& Who ## _RegisteredWith_ ## Registry); + +#endif /* SQUID_BASE_RUNNERSREGISTRY_H */ diff --git a/src/main.cc b/src/main.cc index de345a1790..6459439e99 100644 --- a/src/main.cc +++ b/src/main.cc @@ -38,6 +38,7 @@ #include "adaptation/icap/icap_log.h" #endif #include "auth/Gadgets.h" +#include "base/RunnersRegistry.h" #include "base/TextException.h" #if USE_DELAY_POOLS #include "ClientDelayConfig.h" @@ -64,7 +65,6 @@ #include "StoreFileSystem.h" #include "DiskIO/DiskIOModule.h" #include "ipc/Kids.h" -#include "ipc/mem/Pages.h" #include "ipc/Coordinator.h" #include "ipc/Strand.h" #include "ip/tools.h" @@ -1412,12 +1412,9 @@ SquidMain(int argc, char **argv) /* NOTREACHED */ } - // XXX: this logic should probably be moved into Ipc::Mem::Init() - if (IamMasterProcess()) - Ipc::Mem::Init(); - else - if (UsingSmp() && IamWorkerProcess()) - Ipc::Mem::Attach(); + debugs(1,2, HERE << "Doing post-config initialization\n"); + ActivateRegistered(rrAfterConfig); + // TODO: find a place to call DeactivateRegistered(rrAfterConfig); if (!opt_no_daemon && Config.workers > 0) watch_child(argv);