From: Alex Rousskov Date: Tue, 30 Mar 2010 21:54:40 +0000 (-0600) Subject: Moved Kid and Kids classes from src/main.cc to src/ipc/, creating libipc. X-Git-Tag: SQUID_3_2_0_1~93^2~33 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=40daaeb8dbb4f6b69100d55d2e69596269ec1962;p=thirdparty%2Fsquid.git Moved Kid and Kids classes from src/main.cc to src/ipc/, creating libipc. Removed update_port hack(). Squid.conf macros and conditionals can now be used to specify unique http_ports, cache_dirs, etc. for Squid processes. --- diff --git a/configure.in b/configure.in index 741a5a9821..535ebf5fbe 100644 --- a/configure.in +++ b/configure.in @@ -4233,6 +4233,7 @@ AC_CONFIG_FILES([\ src/ident/Makefile \ src/ip/Makefile \ src/log/Makefile \ + src/ipc/Makefile \ contrib/Makefile \ snmplib/Makefile \ icons/Makefile \ diff --git a/src/Makefile.am b/src/Makefile.am index c99c58b8c1..b4d2730cca 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -34,7 +34,7 @@ LOADABLE_MODULES_SOURCES = \ LoadableModules.h \ LoadableModules.cc -SUBDIRS = base comm eui acl fs repl auth ip icmp ident log +SUBDIRS = base comm eui acl fs repl auth ip icmp ident log ipc if USE_ADAPTATION SUBDIRS += adaptation @@ -164,7 +164,8 @@ COMMON_LIBS = \ auth/libauth.la \ acl/libapi.la \ ip/libip.la \ - fs/libfs.la + fs/libfs.la \ + ipc/libipc.la EXTRA_PROGRAMS = \ DiskIO/DiskDaemon/diskd \ diff --git a/src/cache_cf.cc b/src/cache_cf.cc index 7facb536a4..e78fc63b60 100644 --- a/src/cache_cf.cc +++ b/src/cache_cf.cc @@ -69,6 +69,7 @@ #include "StoreFileSystem.h" #include "SwapDir.h" #include "wordlist.h" +#include "ipc/Kids.h" #if HAVE_GLOB_H #include @@ -3092,9 +3093,6 @@ parse_http_port_specification(http_port_list * s, char *token) self_destruct(); } - extern void update_port(unsigned short* port); - update_port(&port); - if (NULL == host) { s->s.SetAnyAddr(); s->s.SetPort(port); diff --git a/src/globals.h b/src/globals.h index d912d20d13..38a38de7f3 100644 --- a/src/globals.h +++ b/src/globals.h @@ -173,8 +173,6 @@ extern "C" { extern const char *external_acl_message; /* NULL */ extern int opt_send_signal; /* -1 */ extern int opt_no_daemon; /* 0 */ - extern char KidName[NAME_MAX]; - extern int KidIdentifier; /* 0 */ #ifdef __cplusplus diff --git a/src/ipc/Kid.cc b/src/ipc/Kid.cc new file mode 100644 index 0000000000..8150fee41a --- /dev/null +++ b/src/ipc/Kid.cc @@ -0,0 +1,122 @@ +/* + * $Id$ + * + * DEBUG: section 54 Interprocess Communication + * + */ + +#include "config.h" +#include "ipc/Kid.h" + +Kid::Kid(): + badFailures(0), + pid(-1), + startTime(0), + isRunning(false) +{ +} + +Kid::Kid(const String& kid_name): + theName(kid_name), + badFailures(0), + pid(-1), + startTime(0), + isRunning(false) +{ +} + +/// called when this kid got started, records PID +void Kid::start(pid_t cpid) +{ + assert(!running()); + assert(cpid > 0); + + isRunning = true; + pid = cpid; + time(&startTime); +} + +/// called when kid terminates, sets exiting status +void Kid::stop(status_type exitStatus) +{ + assert(running()); + assert(startTime != 0); + + isRunning = false; + + time_t stop_time; + time(&stop_time); + if ((stop_time - startTime) < fastFailureTimeLimit) + badFailures++; + else + badFailures = 0; // the failures are not "frequent" [any more] + + status = exitStatus; +} + +/// returns true if tracking of kid is stopped +bool Kid::running() const +{ + return isRunning; +} + +/// returns current pid for a running kid and last pid for a stopped kid +pid_t Kid::getPid() const +{ + assert(pid > 0); + return pid; +} + +/// whether the failures are "repeated and frequent" +bool Kid::hopeless() const +{ + return badFailures > badFailureLimit; +} + +/// returns true if the process terminated normally +bool Kid::calledExit() const +{ + return (pid > 0) && !running() && WIFEXITED(status); +} + +/// returns the exit status of the process +int Kid::exitStatus() const +{ + return WEXITSTATUS(status); +} + +/// whether the process exited with a given exit status code +bool Kid::calledExit(int code) const +{ + return calledExit() && (exitStatus() == code); +} + +/// whether the process exited with code 0 +bool Kid::exitedHappy() const +{ + return calledExit(0); +} + +/// returns true if the kid was terminated by a signal +bool Kid::signaled() const +{ + return (pid > 0) && !running() && WIFSIGNALED(status); +} + +/// returns the number of the signal that caused the kid to terminate +int Kid::termSignal() const +{ + return WTERMSIG(status); +} + +/// whether the process was terminated by a given signal +bool Kid::signaled(int sgnl) const +{ + return signaled() && (termSignal() == sgnl); +} + +/// returns kid name +const String& Kid::name() const +{ + return theName; +} diff --git a/src/ipc/Kid.h b/src/ipc/Kid.h new file mode 100644 index 0000000000..fbdf189dd3 --- /dev/null +++ b/src/ipc/Kid.h @@ -0,0 +1,85 @@ +/* + * $Id$ + * + */ + +#ifndef SQUID_IPC_KID_H +#define SQUID_IPC_KID_H + +#include "SquidString.h" + + +/// Squid child, including current forked process info and +/// info persistent across restarts +class Kid +{ +public: +#ifdef _SQUID_NEXT_ + typedef union wait status_type; +#else + typedef int status_type; +#endif + + /// keep restarting until the number of bad failures exceed this limit + enum { badFailureLimit = 4 }; + + /// slower start failures are not "frequent enough" to be counted as "bad" + enum { fastFailureTimeLimit = 10 }; // seconds + +public: + Kid(); + + Kid(const String& kid_name); + + /// called when this kid got started, records PID + void start(pid_t cpid); + + /// called when kid terminates, sets exiting status + void stop(status_type exitStatus); + + /// returns true if tracking of kid is stopped + bool running() const; + + /// returns current pid for a running kid and last pid for a stopped kid + pid_t getPid() const; + + /// whether the failures are "repeated and frequent" + bool hopeless() const; + + /// returns true if the process terminated normally + bool calledExit() const; + + /// returns the exit status of the process + int exitStatus() const; + + /// whether the process exited with a given exit status code + bool calledExit(int code) const; + + /// whether the process exited with code 0 + bool exitedHappy() const; + + /// returns true if the kid was terminated by a signal + bool signaled() const; + + /// returns the number of the signal that caused the kid to terminate + int termSignal() const; + + /// whether the process was terminated by a given signal + bool signaled(int sgnl) const; + + /// returns kid name + const String& name() const; + +private: + // Information preserved across restarts + String theName; ///< process name + int badFailures; ///< number of "repeated frequent" failures + + // Information specific to a running or stopped kid + pid_t pid; ///< current (for a running kid) or last (for stopped kid) PID + time_t startTime; ///< last start time + bool isRunning; ///< whether the kid is assumed to be alive + status_type status; ///< exit status of a stopped kid +}; + +#endif /* SQUID_IPC_KID_H */ diff --git a/src/ipc/Kids.cc b/src/ipc/Kids.cc new file mode 100644 index 0000000000..cf97689b45 --- /dev/null +++ b/src/ipc/Kids.cc @@ -0,0 +1,90 @@ +/* + * $Id$ + * + * DEBUG: section 54 Interprocess Communication + * + */ + +#include "config.h" +#include "ipc/Kids.h" + +Kids TheKids; +char KidName[NAME_MAX]; +int KidIdentifier; + +Kids::Kids() +{ +} + +/// maintain n kids +void Kids::init(size_t n) +{ + assert(n > 0); + + if (storage.size() > 0) + storage.clean(); + + storage.reserve(n); + + for (size_t i = 1; i <= n; ++i) { + char kid_name[32]; + snprintf(kid_name, sizeof(kid_name), "(squid-%d)", (int)i); + storage.push_back(Kid(kid_name)); + } +} + +/// returns kid by pid +Kid* Kids::find(pid_t pid) +{ + assert(pid > 0); + assert(count() > 0); + + for (size_t i = 0; i < storage.size(); ++i) { + if (storage[i].getPid() == pid) + return &storage[i]; + } + return NULL; +} + +/// returns the kid by index, useful for kids iteration +Kid& Kids::get(size_t i) +{ + assert(i >= 0 && i < count()); + return storage[i]; +} + +/// whether all kids are hopeless +bool Kids::allHopeless() const +{ + for (size_t i = 0; i < storage.size(); ++i) { + if (!storage[i].hopeless()) + return false; + } + return true; +} + +/// whether all kids called exited happy +bool Kids::allExitedHappy() const +{ + for (size_t i = 0; i < storage.size(); ++i) { + if (!storage[i].exitedHappy()) + return false; + } + return true; +} + +/// whether all kids died from a given signal +bool Kids::allSignaled(int sgnl) const +{ + for (size_t i = 0; i < storage.size(); ++i) { + if (!storage[i].signaled(sgnl)) + return false; + } + return true; +} + +/// returns the number of kids +size_t Kids::count() const +{ + return storage.size(); +} diff --git a/src/ipc/Kids.h b/src/ipc/Kids.h new file mode 100644 index 0000000000..dce7f14fbc --- /dev/null +++ b/src/ipc/Kids.h @@ -0,0 +1,55 @@ +/* + * $Id$ + * + */ + +#ifndef SQUID_IPC_KIDS_H +#define SQUID_IPC_KIDS_H + +#include "Array.h" +#include "ipc/Kid.h" + + +/// a collection of kids +class Kids +{ +public: + Kids (); + +private: + Kids (const Kids&); ///< not implemented + Kids& operator= (const Kids&); ///< not implemented + +public: + /// maintain n kids + void init(size_t n); + + /// returns kid by pid + Kid* find(pid_t pid); + + /// returns the kid by index, useful for kids iteration + Kid& get(size_t i); + + /// whether all kids are hopeless + bool allHopeless() const; + + /// whether all kids called exited happy + bool allExitedHappy() const; + + /// whether all kids died from a given signal + bool allSignaled(int sgnl) const; + + /// returns the number of kids + size_t count() const; + +private: + Vector storage; +}; + +extern Kids TheKids; ///< All kids being maintained + +extern char KidName[NAME_MAX]; ///< current Squid process name (e.g., squid2) +extern int KidIdentifier; ///< current Squid process number (e.g., 4) + + +#endif /* SQUID_IPC_KIDS_H */ diff --git a/src/ipc/Makefile.am b/src/ipc/Makefile.am new file mode 100644 index 0000000000..c2bcb17ad1 --- /dev/null +++ b/src/ipc/Makefile.am @@ -0,0 +1,10 @@ +include $(top_srcdir)/src/Common.am +include $(top_srcdir)/src/TestHeaders.am + +noinst_LTLIBRARIES = libipc.la + +libipc_la_SOURCES = \ + Kid.cc \ + Kid.h \ + Kids.cc \ + Kids.h diff --git a/src/main.cc b/src/main.cc index 7a867bafdd..46d56db140 100644 --- a/src/main.cc +++ b/src/main.cc @@ -55,6 +55,7 @@ #include "StoreFileSystem.h" #include "DiskIO/DiskIOModule.h" #include "comm.h" +#include "ipc/Kids.h" #if USE_EPOLL #include "comm_epoll.h" #endif @@ -1530,249 +1531,6 @@ checkRunningPid(void) return 1; } -/// XXX: temporary hack to avoid http_port conflicts among listening kids -void update_port(unsigned short* port) -{ - if (KidIdentifier > 0) - *port += KidIdentifier - 1; -} - -/// Squid child, including current forked process info and -/// info persistent across restarts -class Kid -{ -public: -#ifdef _SQUID_NEXT_ - typedef union wait status_type; -#else - typedef int status_type; -#endif - - /// keep restarting until the number of bad failures exceed this limit - enum { badFailureLimit = 4 }; - - /// slower start failures are not "frequent enough" to be counted as "bad" - enum { fastFailureTimeLimit = 10 }; // seconds - -public: - Kid(): - badFailures(0), - pid(-1), - startTime(0), - isRunning(false) - { - } - - Kid(const String& kid_name): - theName(kid_name), - badFailures(0), - pid(-1), - startTime(0), - isRunning(false) - { - } - - /// called when this kid got started, records PID - void start(pid_t cpid) - { - assert(!running()); - assert(cpid > 0); - - isRunning = true; - pid = cpid; - time(&startTime); - } - - /// called when kid terminates, sets exiting status - void stop(status_type exitStatus) - { - assert(running()); - assert(startTime != 0); - - isRunning = false; - - time_t stop_time; - time(&stop_time); - if ((stop_time - startTime) < fastFailureTimeLimit) - badFailures++; - else - badFailures = 0; // the failures are not "frequent" [any more] - - status = exitStatus; - } - - /// returns true if tracking of kid is stopped - bool running() const - { - return isRunning; - } - - /// returns current pid for a running kid and last pid for a stopped kid - pid_t getPid() const - { - assert(pid > 0); - return pid; - } - - /// whether the failures are "repeated and frequent" - bool hopeless() const - { - return badFailures > badFailureLimit; - } - - /// returns true if the process terminated normally - bool calledExit() const - { - return (pid > 0) && !running() && WIFEXITED(status); - } - - /// returns the exit status of the process - int exitStatus() const - { - return WEXITSTATUS(status); - } - - /// whether the process exited with a given exit status code - bool calledExit(int code) const - { - return calledExit() && (exitStatus() == code); - } - - /// whether the process exited with code 0 - bool exitedHappy() const - { - return calledExit(0); - } - - /// returns true if the kid was terminated by a signal - bool signaled() const - { - return (pid > 0) && !running() && WIFSIGNALED(status); - } - - /// returns the number of the signal that caused the kid to terminate - int termSignal() const - { - return WTERMSIG(status); - } - - /// whether the process was terminated by a given signal - bool signaled(int sgnl) const - { - return signaled() && (termSignal() == sgnl); - } - - /// returns kid name - const String& name() const - { - return theName; - } - -private: - // Information preserved across restarts - String theName; ///< process name - int badFailures; ///< number of "repeated frequent" failures - - // Information specific to a running or stopped kid - pid_t pid; ///< current (for a running kid) or last (for stopped kid) PID - time_t startTime; ///< last start time - bool isRunning; ///< whether the kid is assumed to be alive - status_type status; ///< exit status of a stopped kid -}; - -/// a collection of kids -class Kids -{ -public: - Kids (): - storage() - { - } - -private: - Kids (const Kids&); ///< not implemented - Kids& operator= (const Kids&); ///< not implemented - -public: - /// maintain n kids - void init(size_t n) - { - assert(n > 0); - - if (storage.size() > 0) - storage.clean(); - - storage.reserve(n); - - for (size_t i = 1; i <= n; ++i) { - char kid_name[32]; - snprintf(kid_name, sizeof(kid_name), "(squid-%d)", (int)i); - storage.push_back(Kid(kid_name)); - } - } - - /// returns kid by pid - Kid* find(pid_t pid) - { - assert(pid > 0); - assert(count() > 0); - - for (size_t i = 0; i < storage.size(); ++i) { - if (storage[i].getPid() == pid) - return &storage[i]; - } - return NULL; - } - - /// returns the kid by index, useful for kids iteration - Kid& get(size_t i) - { - assert(i >= 0 && i < count()); - return storage[i]; - } - - /// whether all kids are hopeless - bool allHopeless() const - { - for (size_t i = 0; i < storage.size(); ++i) { - if (!storage[i].hopeless()) - return false; - } - return true; - } - - /// whether all kids called exited happy - bool allExitedHappy() const - { - for (size_t i = 0; i < storage.size(); ++i) { - if (!storage[i].exitedHappy()) - return false; - } - return true; - } - - /// whether all kids died from a given signal - bool allSignaled(int sgnl) const - { - for (size_t i = 0; i < storage.size(); ++i) { - if (!storage[i].signaled(sgnl)) - return false; - } - return true; - } - - /// returns the number of kids - size_t count() const - { - return storage.size(); - } - -private: - Vector storage; -}; - -static Kids TheKids; ///< All kids being maintained - static void watch_child(char *argv[]) {