diff options
Diffstat (limited to 'third_party/cld/base')
-rw-r--r-- | third_party/cld/base/callback.h | 308 | ||||
-rw-r--r-- | third_party/cld/base/closure.h | 12 | ||||
-rw-r--r-- | third_party/cld/base/google.h | 212 | ||||
-rw-r--r-- | third_party/cld/base/googleinit.h | 384 |
4 files changed, 0 insertions, 916 deletions
diff --git a/third_party/cld/base/callback.h b/third_party/cld/base/callback.h deleted file mode 100644 index d4f4644..0000000 --- a/third_party/cld/base/callback.h +++ /dev/null @@ -1,308 +0,0 @@ -// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Callback classes provides a generic interface for classes requiring -// callback from other classes. -// We support callbacks with 0, 1, 2, 3, and 4 arguments. -// Closure -- provides "void Run()" -// Callback1<T1> -- provides "void Run(T1)" -// Callback2<T1,T2> -- provides "void Run(T1, T2)" -// Callback3<T1,T2,T3> -- provides "void Run(T1, T2, T3)" -// Callback4<T1,T2,T3,T4> -- provides "void Run(T1, T2, T3, T4)" -// -// In addition, ResultCallback classes provide a generic interface for -// callbacks that return a value. -// ResultCallback<R> -- provides "R Run()" -// ResultCallback1<R,T1> -- provides "R Run(T1)" -// ResultCallback2<R,T1,T2> -- provides "R Run(T1, T2)" -// ResultCallback3<R,T1,T2,T3> -- provides "R Run(T1, T2, T3)" -// ResultCallback4<R,T1,T2,T3,T4> -- provides "R Run(T1, T2, T3, T4)" - -// We provide a convenient mechanism, NewCallback, for generating one of these -// callbacks given an object pointer, a pointer to a member -// function with the appropriate signature in that object's class, -// and some optional arguments that can be bound into the callback -// object. The mechanism also works with just a function pointer. -// -// Note: there are two types of arguments passed to the callback method: -// * "pre-bound arguments" - supplied when the callback object is created -// * "call-time arguments" - supplied when the callback object is invoked -// -// These two types correspond to "early binding" and "late -// binding". An argument whose value is known when the callback is -// created ("early") can be pre-bound (a.k.a. "Curried"), You can -// combine pre-bound and call-time arguments in different ways. For -// example, invoking a callback with 3 pre-bound arguments and 1 -// call-time argument will have the same effect as invoking a callback -// with 2 pre-bound arguments and 2 call-time arguments, or 4 -// pre-bound arguments and no call-time arguments. This last case is -// often useful; a callback with no call-time arguments is a Closure; -// these are used in many places in the Google libraries, e.g., "done" -// closures. See the examples below. -// -// WARNING: In the current implementation (or perhaps with the current -// compiler) NewCallback() is pickier about the types of pre-bound arguments -// than you might expect. The types must match exactly, rather than merely -// being compatible. -// For example, if you pre-bind an argument with the "const" specifier, -// make sure that the actual parameter passed to NewCallback also has the -// const specifier. If you don't you'll get an error about -// passing a your function "as argument 1 of NewCallback(void (*)())". -// Using a method or function that has reference arguments among its pre-bound -// arguments may not always work. -// -// Examples: -// -// void Call0(Closure* cb) { cb->Run(); } -// void Call1(Callback1<int>* cb, int a) { cb->Run(a); } -// void Call2(Callback2<int, float>* cb, int a, float f) { cb->Run(a, f); } -// float Call3(ResultCallback1<float, int>* cb, int a) { return cb->Run(a); } -// -// class Foo { -// public: -// void A(int a); -// void B(int a, float f); -// void C(const char* label, int a, float f); -// float D(int a); -// }; -// void F0(int a); -// void F1(int a, float f); -// void F2(const char *label, int a, float f); -// float F3(int a); -// float v; -// -// // Run stuff immediately -// // calling a method -// Foo* foo = new Foo; -// -// NewCallback(foo, &Foo::A) ->Run(10); // 0 [pre-bound] + 1 [call-time] -// == NewCallback(foo, &Foo::A, 10) ->Run(); // 1 + 0 -// == foo->A(10); -// -// NewCallback(foo, &Foo::B) ->Run(10, 3.0f); // 0 + 2 -// == NewCallback(foo, &Foo::B, 10) ->Run(3.0f); // 1 + 1 -// == NewCallback(foo, &Foo::B, 10, 3.0f) ->Run(); // 2 + 0 -// == foo->B(10, 3.0f); -// -// NewCallback(foo, &Foo::C) ->Run("Y", 10, 3.0f); // 0 + 3 -// == NewCallback(foo, &Foo::C, "Y") ->Run(10, 3.0f); // 1 + 2 -// == NewCallback(foo, &Foo::C, "Y", 10) ->Run(3.0f); // 2 + 1 -// == NewCallback(foo, &Foo::C, "Y", 10, 3.0f) ->Run(); // 3 + 0 -// == foo->C("Y", 10, 3.0f); -// -// v = NewCallback(foo, &Foo::D) ->Run(10); == v = foo->D(10) -// -// // calling a function -// NewCallback(F0) ->Run(10); // == F0(10) // 0 + 1 -// NewCallback(F0, 10) ->Run(); // == F0(10) // 1 + 0 -// NewCallback(F1) ->Run(10, 3.0f); // == F1(10, 3.0f) -// NewCallback(F2, "X") ->Run(10, 3.0f); // == F2("X", 10, 3.0f) -// NewCallback(F2, "Y") ->Run(10, 3.0f); // == F2("Y", 10, 3.0f) -// v = NewCallback(F3) ->Run(10); // == v = F3(10) -// -// -// // Pass callback object to somebody else, who runs it. -// // Calling a method: -// Call1(NewCallback(foo, &Foo::A), 10); // 0 + 1 -// == Call0(NewCallback(foo, &Foo::A, 10) ); // 1 + 0 -// == foo->A(10) -// -// Call2(NewCallback(foo, &Foo::B), 10, 3.0f); // 0 + 2 -// == Call1(NewCallback(foo, &Foo::B, 10), 3.0f); // 1 + 1 -// == Call0(NewCallback(foo, &Foo::B, 10, 30.f) ); // 2 + 0 -// == foo->B(10, 3.0f) -// -// Call2(NewCallback(foo, &Foo::C, "X"), 10, 3.0f); == foo->C("X", 10, 3.0f) -// Call2(NewCallback(foo, &Foo::C, "Y"), 10, 3.0f); == foo->C("Y", 10, 3.0f) -// -// // Calling a function: -// Call1(NewCallback(F0), 10); // 0 + 1 -// == Call0(NewCallback(F0, 10) ); // 1 + 0 -// == F0(10); -// -// Call2(NewCallback(F1), 10, 3.0f); // == F1(10, 3.0f) -// Call2(NewCallback(F2, "X"), 10, 3.0f); // == F2("X", 10, 3.0f) -// Call2(NewCallback(F2, "Y"), 10, 3.0f); // == F2("Y", 10, 3.0f) -// v = Call3(NewCallback(F3), 10); // == v = F3(10) -// -// Example of a "done" closure: -// -// SelectServer ss; -// Closure* done = NewCallback(&ss, &SelectServer::MakeLoopExit); -// ProcessMyControlFlow(..., done); -// ss.Loop(); -// ... -// -// The following WILL NOT WORK: -// NewCallback(F2, (char *) "Y") ->Run(10, 3.0f); -// It gets the error: -// passing `void (*)(const char *, int, float)' as argument 1 of -// `NewCallback(void (*)())' -// The problem is that "char *" is not an _exact_ match for -// "const char *", even though it's normally a legal implicit -// conversion. -// -// -// The callback objects generated by NewCallback are self-deleting: -// i.e., they call the member function, and then delete themselves. -// If you want a callback that does not delete itself every time -// it runs, use "NewPermanentCallback" instead of "NewCallback". -// -// All the callback/closure classes also provide -// virtual void CheckIsRepeatable() const; -// It crashes if (we know for sure that) the callback's Run method -// can not be called an arbitrary number of times (including 0). -// It crashes for all NewCallback() generated callbacks, -// does not crash for NewPermanentCallback() generated callbacks, -// and although by default it does not crash for all callback-derived classes, -// for these new types of callbacks, the callback writer is encouraged to -// redefine this method appropriately. -// -// CAVEAT: Interfaces that accept callback pointers should clearly document -// if they might call Run methods of those callbacks multiple times -// (and use "c->CheckIsRepeatable();" as an active precondition check), -// or if they call the callbacks exactly once or potentially not at all, -// as well as if they take ownership of the passed callbacks -// (i.e. might manually deallocate them without calling their Run methods). -// The clients can then provide properly allocated and behaving callbacks -// (e.g. choose between NewCallback, NewPermanentCallback, or a custom object). -// Obviously, one should also be careful to ensure that the data a callback -// points to and needs for its Run method is still live when -// the Run method might be called. -// -// MOTIVATION FOR CALLBACK OBJECTS -// ------------------------------- -// It frees service providers from depending on service requestors by -// calling a generic callback other than a callback which depends on -// the service requestor (typically its member function). As a -// result, service provider classes can be developed independently. -// -// Typical usage: Suppose class A wants class B to do something and -// notify A when it is done. As part of the notification, it wants -// to be given a boolean that says what happened. -// -// class A { -// public: -// void RequestService(B* server) { -// ... -// server->StartService(NewCallback(this, &A::ServiceDone), other_args)); -// // the new callback deletes itself after it runs -// } -// void ServiceDone(bool status) {...} -// }; -// -// Class B { -// public: -// void StartService(Callback1<bool>* cb, other_args) : cb_(cb) { ...} -// void FinishService(bool result) { ...; cb_->Run(result); } -// private: -// Callback1<bool>* cb_; -// }; -// -// As can be seen, B is completely independent of A. (Of course, they -// have to agree on callback data type.) -// -// The result of NewCallback() is thread-compatible. The result of -// NewPermanentCallback() is thread-safe if the call its Run() method -// represents is thread-safe and thread-compatible otherwise. -// -// Other modules associated with callbacks may be found in //util/callback -// -// USING CALLBACKS WITH TRACECONTEXT -// --------------------------------- -// Callbacks generated by NewCallback() automatically propagate trace -// context. Callbacks generated by NewPermanentCallback() do not. For -// manually-derived subclasses of Closure and CallbackN, you may decide -// to propagate TraceContext as follows. -// -// struct MyClosure : public Closure { -// MyClosure() -// : Closure(TraceContext::THREAD) { } -// -// void Run() { -// TraceContext *tc = TraceContext::Thread(); -// tc->Swap(&trace_context_); -// DoMyOperation() -// tc->Swap(&trace_context_); -// delete this; -// } -// }; - -#ifndef _CALLBACK_H_ -#define _CALLBACK_H_ - -#include <functional> - -// The actual callback classes and various NewCallback() implementations -// are automatically generated by base/generate-callback-specializations.py. -// We include that output here. -#include "base/callback-specializations.h" - -// A new barrier closure executes another closure after it has been -// invoked N times, and then deletes itself. -// -// If "N" is zero, the supplied closure is executed immediately. -// Barrier closures are thread-safe. They use an atomic operation to -// guarantee a correct count. -// -// REQUIRES N >= 0. -extern Closure* NewBarrierClosure(int N, Closure* done_closure); - -// Function that does nothing; can be used to make new no-op closures: -// NewCallback(&DoNothing) -// NewPermanentCallback(&DoNothing) -// This is a replacement for the formerly available TheNoopClosure() primitive. -extern void DoNothing(); - -// AutoClosureRunner executes a closure upon deletion. This class -// is similar to scoped_ptr: it is typically stack-allocated and can be -// used to perform some type of cleanup upon exiting a block. -// -// Note: use of AutoClosureRunner with Closures that must be executed at -// specific points is discouraged, since the point at which the Closure -// executes is not explicitly marked. For example, consider a Closure -// that should execute after a mutex has been released. The following -// code looks correct, but executes the Closure too early (before release): -// { -// MutexLock l(...); -// AutoClosureRunner r(run_after_unlock); -// ... -// } -// AutoClosureRunner is primarily intended for cleanup operations that -// are relatively independent from other code. -// -// The Reset() method replaces the callback with a new callback. The new -// callback can be supplied as NULL to disable the AutoClosureRunner. This is -// intended as part of a strategy to execute a callback at all exit points of a -// method except where Reset() was called. This method must be used only with -// non-permanent callbacks. The Release() method disables and returns the -// callback, instead of deleting it. -class AutoClosureRunner { - private: - Closure* closure_; - public: - explicit AutoClosureRunner(Closure* c) : closure_(c) {} - ~AutoClosureRunner() { if (closure_) closure_->Run(); } - void Reset(Closure *c) { delete closure_; closure_ = c; } - Closure* Release() { Closure* c = closure_; closure_ = NULL; return c; } - private: - DISALLOW_EVIL_CONSTRUCTORS(AutoClosureRunner); -}; - -// DeletePointerClosure can be used to create a closure that calls delete -// on a pointer. Here is an example: -// -// thread->Add(DeletePointerClosure(expensive_to_delete)); -// -template<typename T> -void DeletePointer(T* p) { - delete p; -} - -template<typename T> -Closure* DeletePointerClosure(T* p) { - return NewCallback(&DeletePointer<T>, p); -} - -#endif /* _CALLBACK_H_ */ diff --git a/third_party/cld/base/closure.h b/third_party/cld/base/closure.h deleted file mode 100644 index d20f065..0000000 --- a/third_party/cld/base/closure.h +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef _CLOSURE_H -#define _CLOSURE_H - -// The Closure class is described in "base/callback.h". - -#include "third_party/cld/base/callback.h" - -#endif /* _CLOSURE_H */ diff --git a/third_party/cld/base/google.h b/third_party/cld/base/google.h deleted file mode 100644 index 082058d2..0000000 --- a/third_party/cld/base/google.h +++ /dev/null @@ -1,212 +0,0 @@ -// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file contains a very small number of declarations that should be -// included in most programs. -// -// Sets the usage message to "*usage", parses the command-line flags, -// and initializes various other pieces of global state. If running -// as root, this routine attempts to setuid to FLAGS_uid, which defaults -// to "nobody". -// -// It also logs all the program's command-line flags to the INFO log file. -// -// If the global variable FLAGS_uid is not equal to the empty string, -// then InitGoogle also does an 'su' to the user specified in -// FLAGS_uid, and sets the group equal to FLAGS_gid. -// -// The functions in here are thread-safe unless specified otherwise, -// but they must be called after InitGoogle() (or the -// InitGoogleExceptChangeRootAndUser/ChangeRootAndUser pair). - -#ifndef _GOOGLE_H_ -#define _GOOGLE_H_ - -#include <iosfwd> // to forward declare ostream -#include "base/basictypes.h" -#include "third_party/cld/base/closure.h" -#include "third_party/cld/base/googleinit.h" - -class Closure; - -// A more-convenient way to access gethostname() -const char* Hostname(); -// Return kernel version string in /proc/version -const char* GetKernelVersionString(); -// Return true and set kernel version (x.y.z), patch level and revision (#p.r), -// false, if not known. -struct KernelVersion { - int major; // Major release - int minor; // Minor release - int micro; // Whatever the third no. is called ... - int patch; // Patch level - int revision; // Patch revision -}; -bool GetKernelVersion(KernelVersion* kv); -// A string saying when InitGoogle() was called -- probably program start -const char* GetStartTime(); -// time in ms since InitGoogle() was called -- -int64 GetUptime(); -// the pid for the startup thread -int32 GetMainThreadPid(); - -// the resource limit for core size when InitGoogle() was called. -const struct rlimit* GetSavedCoreLimit(); - -// Restore the core size limit saved in InitGoogle(). This is a no-op if -// FLAGS_allow_kernel_coredumps is true. -int32 RestoreSavedCoreLimit(); - -// Return true if we have determined that all CPUs have the same timing -// (same model, clock rate, stepping). Returns true if there is only one -// CPU. Returns false if we cannot read or parse /proc/cpuinfo. -bool CPUsHaveSameTiming( - const char *cpuinfo = "/proc/cpuinfo", - const char *cpuinfo_max_freq = "/sys/devices/system/cpu/cpu%d/" - "cpufreq/cpuinfo_max_freq"); - -// FlagsParsed is called once for every run VLOG() call site. -// Returns true if command line flags have been parsed -bool FlagsParsed(); - -// A place-holder module initializer to declare initialization ordering -// with respect to it to make chosen initalizers run before command line flag -// parsing (see googleinit.h for more details). -DECLARE_MODULE_INITIALIZER(command_line_flags_parsing); - -// Checks (only in debug mode) if main() has been started and crashes if not -// i.e. makes sure that we are out of the global constructor execution stage. -// Intended to for checking that some code should not be executed during -// global object construction (only specially crafted code might be safe -// to execute at that time). -void AssertMainHasStarted(); - -// Call this from main() if AssertMainHasStarted() is incorrectly failing -// for your code (its current implmentation relies on a call to InitGoogle() -// as the signal that we have reached main(), hence it is not 100% accurate). -void SetMainHasStarted(); - -// Checks (only in debug mode) if InitGoogle() has been fully executed -// and crashes if it has not been. -// Indtended for checking that code that depends on complete execution -// of InitGoogle() for its proper functioning is safe to execute. -void AssertInitGoogleIsDone(); - -// Initializes misc google-related things in the binary. -// In particular it does REQUIRE_MODULE_INITIALIZED(command_line_flags_parsing) -// parses command line flags and does RUN_MODULE_INITIALIZERS() (in that order). -// If a flag is defined more than once in the command line or flag -// file, the last definition is used. -// Typically called early on in main() and must be called before other -// threads start using functions from this file. -// -// 'usage' provides a short usage message passed to SetUsageMessage(). -// 'argc' and 'argv' are the command line flags to parse. -// If 'remove_flags' then parsed flags are removed. -void InitGoogle(const char* usage, int* argc, char*** argv, bool remove_flags); - -// Normally, InitGoogle will chroot (if requested with the --chroot flag) -// and setuid to --uid and --gid (default nobody). -// This version will not, and you will be responsible for calling -// ChangeRootAndUser -// This option is provided for applications that need to read files outside -// the chroot before chrooting. -void InitGoogleExceptChangeRootAndUser(const char* usage, int* argc, - char*** argv, bool remove_flags); -// Thread-hostile. -void ChangeRootAndUser(); - -// if you need to flush InitGoogle's resources from a sighandler -void SigHandlerFlushInitGoogleResources(); - -// Alter behavior of error to not dump core on an error. -// Simply cleanup and exit. Thread-hostile. -void SetNoCoreOnError(); - -// limit the amount of physical memory used by this process to a -// fraction of the available physical memory. The process is killed if -// it tries to go beyond this limit. If randomize is set, we reduce -// the fraction a little in a sort-of-random way. randomize is meant -// to be used for applications which run many copies -- by randomizing -// the limit, we can avoid having all copies of the application hit -// the limit (and die) at the same time. -void LimitPhysicalMemory(double fraction, bool randomize); - -// Return the limit set on physical memory, zero if error or no limit set. -uint64 GetPhysicalMemoryLimit(); - -// Add specified closure to the set of closures which are executed -// when the program dies a horrible death (signal, etc.) -// -// Note: These are not particularly efficient. Use sparingly. -// Note: you can't just use atexit() because functions registered with -// atexit() are supposedly only called on normal program exit, and we -// want to do things like flush logs on failures. -void RunOnFailure(Closure* closure); - -// Remove specified closure references from the set created by RunOnFailure. -void CancelRunOnFailure(Closure* closure); - -// Adds specified Callback2 instances to a set of callbacks that are -// executed when the program crashes. Two values: signo and ucontext_t* -// will be passed into these callback functions. We use void* to avoid the -// use of ucontext_t on non-POSIX systems. -// -// Note: it is recommended that these callbacks are signal-handler -// safe. Also, the calls of these callbacks are not protected by -// a mutex, so they are better to be multithread-safe. -void RunOnFailureCallback2(Callback2<int, void*>* callback); -void CancelRunOnFailureCallback2(Callback2<int, void*>* callback); - -// Return true if the google default signal handler is running, false -// otherwise. Sometimes callbacks specified with -// RunOnFailure{,Callback2} are not called because the process hangs -// or takes too long to symbolize callstacks. Users may want to -// augment the RunOnFailure mechanism with a dedicated thread which -// polls the below function periodically (say, every second) and runs -// their failure closures when it returns true. -bool IsFailureSignalHandlerRunning(); - -// Type of function used for printing in stack trace dumping, etc. -// We avoid closures to keep things simple. -typedef void DebugWriter(const char*, void*); - -// A few useful DebugWriters -DebugWriter DebugWriteToStderr; -DebugWriter DebugWriteToStream; -DebugWriter DebugWriteToFile; -DebugWriter DebugWriteToString; - -// Dump current stack trace omitting the topmost 'skip_count' stack frames. -void DumpStackTrace(int skip_count, DebugWriter *w, void* arg); - -// Dump given pc and stack trace. -void DumpPCAndStackTrace(void *pc, void *stack[], int depth, - DebugWriter *writerfn, void *arg); - -// Returns the program counter from signal context, NULL if unknown. -// vuc is a ucontext_t *. We use void* to avoid the use -// of ucontext_t on non-POSIX systems. -void* GetPC(void* vuc); - -// Dump current address map. -void DumpAddressMap(DebugWriter *w, void* arg); - -// Dump information about currently allocated memory. -void DumpMallocStats(DebugWriter *w, void* arg); - -// Return true if currently executing in the google failure signal -// handler. If this returns true you should: -// -// - avoid allocating anything via malloc/new -// - assume that your stack limit is SIGSTKSZ -// - assume that no other thread can be executing in the failure handler -bool InFailureSignalHandler(); - -// Return the alternate signal stack size (in bytes) needed in order to -// safely run the failure signal handlers. The returned value will -// always be a multiple of the system page size. -int32 GetRequiredAlternateSignalStackSize(); - -#endif // _GOOGLE_H_ diff --git a/third_party/cld/base/googleinit.h b/third_party/cld/base/googleinit.h deleted file mode 100644 index 0ccef8b..0000000 --- a/third_party/cld/base/googleinit.h +++ /dev/null @@ -1,384 +0,0 @@ -// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_GOOGLEINIT_H_ -#define BASE_GOOGLEINIT_H_ - -//------------------------------------------------------------------------ - -// Initialization sequence in C++ and Google. -// -// This library provides helpers to arrange pieces of initialization code -// for some global objects/state to be executed at well-defined -// moment in time and in a well-defined order. -// -// This library is flexible enough and should be used to do all -// initialization for global/static objects -// except maybe for a few very-low level libraries (mainly inside //base). -// Comments in googleinit.cc discuss the reasons for this. -// -// For the default *MODULE* macros provided below, -// the initialization happens automatically -// during execution of InitGoogle() -- see google.h, -// a call to which should normally be the first statement of main(). -// -// A module can register code to be executed by InitGoogle(). -// For example, one could place the following in common/hostname.cc: -// -// static const char* my_hostname = NULL; -// REGISTER_MODULE_INITIALIZER(hostname, { -// // Code to initialize "my_hostname" -// }); -// -// (Note that, due to preprocessor weirdness, there may be issues with -// the use of commas in your initialization code. If you run into them, -// try using parens around the commas, or use a helper function as follows: -// -// static const char* my_hostname = NULL; -// static void InitMyHostname() { -// // Code to initialize "my_hostname" -// } -// REGISTER_MODULE_INITIALIZER(my_hostname, InitMyHostname()); -// -// This also helps the compiler to accurately attribute compilation errors -// to pieces of your initialization code. -// -// Note that each piece of registered initialized code is tagged -// with an identifier ('my_hostname' in the previous example). This -// is useful to control the order of initialization. For example, -// if we want file initialization to occur after hostname -// initialization, we can place the following in file/base/file.cc: -// -// REGISTER_MODULE_INITIALIZER(file, { -// // File initialization goes here -// }); -// REGISTER_MODULE_INITIALIZER_SEQUENCE(my_hostname, file); -// // requires my_hostname's initializer to run before file's -// -// Alternatively the following *deprecated* method is also supported -// to accomplish the same ordering of initialization: -// -// REGISTER_MODULE_INITIALIZER(file, { -// REQUIRE_MODULE_INITIALIZED(my_hostname); -// // File initialization goes here -// }); -// -// REQUIRE_MODULE_INITIALIZED should really be used only when -// REGISTER_MODULE_INITIALIZER_SEQUENCE can not be e.g. to explicitly make -// a subset of initializers executed from some non-initializer code or -// to define run-time-dependent module dependencies. -// -// For either of the above to compile we should also place the following -// into common/hostname.h and #include that file into file/base/file.cc: -// -// DECLARE_MODULE_INITIALIZER(my_hostname); -// -// Initialization dependencies defined via REGISTER_MODULE_INITIALIZER_SEQUENCE -// are more flexible: unlike with REQUIRE_MODULE_INITIALIZED, one can also -// require that the initialization code defined in the current .cc file -// be executed before some other initializer, e.g.: -// -// In foo_factory.h: -// DECLARE_MODULE_INITIALIZER(foo_factory_init); -// DECLARE_MODULE_INITIALIZER(foo_factory); -// -// In foo_factory.cc: -// static FooFactory* foo_factory = NULL -// REGISTER_MODULE_INITIALIZER(foo_factory_init, { -// foo_factory = new FooFactory(...); -// }); -// REGISTER_MODULE_INITIALIZER(foo_factory, { -// // e.g. code for some final assimilation of all things registered -// // with foo_factory can go here -// }); -// REGISTER_MODULE_INITIALIZER_SEQUENCE(foo_factory_init, foo_factory); -// -// In my_foo_maker.cc: -// REGISTER_MODULE_INITIALIZER(my_registerer, { -// // registration of some my_method with foo_factory goes here -// }); -// REGISTER_MODULE_INITIALIZER_SEQUENCE_3( -// foo_factory_init, my_registerer, foo_factory); -// // my_registerer runs after foo_factory_init, but before foo_factory -// -// In foo_factory_user.cc: -// REGISTER_MODULE_INITIALIZER(foo_user, { -// // use of foo_factory goes here -// }); -// REGISTER_MODULE_INITIALIZER_SEQUENCE(foo_factory, foo_user); -// -// In the above example the initializer execution order will be -// foo_factory_init, my_registerer, foo_factory, foo_user -// even though both foo_factory.cc and foo_factory_user.cc do not have -// explicit dependencies on my_foo_maker.cc (they do not have to know/care -// if it exists). -// -// It is an error to introduce cycles in the initialization -// dependencies. The program will die with an error message -// if the initialization code encounters cyclic dependencies. -// -// Normally all the registered initializers are executed after -// command-line flags have been parsed. -// If you need your initializer to run before parsing of the command-line flags, -// e.g. to adjust the (default) value of certain flags, then include google.h -// and add a directive like this to your .cc file: -// -// REGISTER_MODULE_INITIALIZER_SEQUENCE( -// my_foo_init, command_line_flags_parsing); -// -// Note that you can't instead call -// REQUIRE_MODULE_INITIALIZED(command_line_flags_parsing); -// in the code of your initializer: actual command-line parsing -// is executed by InitGoogle() not in a registered initializer. -// -// A piece of code can declare a dependency on a module using the -// REQUIRE_MODULE macro. This macro creates a link time dependency -// between the .o which the macro is compiled in and the specified -// module. This can be useful in making link time dependencies -// explicit in the code instead of relying on the correctness of the -// BUILD files. For example, foo.cc can declare (see -// file/base/file.h for the REQUIRE_FILE_MODULE definition): -// -// REQUIRE_FILE_MODULE(localfile); -// -// Similarly to other uses, DECLARE_FILE_INITIALIZER(localfile) -// should be #include-d for the above to compile. -// The above will guarantee that the localfile module will be linked into -// an application which foo.cc is linked into. Specifically, a link -// error will occur if the localfile module is not linked in. The -// preferred usage of REQUIRE_*_MODULE is for the module writer to -// provide an external .h which contains the REQUIRE_* macro. In the -// above example, the localfile module writer would provide localfile.h: -// -// #ifndef FILE_LOCALFILE_H_ -// #define FILE_LOCALFILE_H_ -// -// #include "file/base/file.h" -// -// DECLARE_FILE_INITIALIZER(localfile); -// REQUIRE_FILE_MODULE(localfile); -// -// #endif // FILE_LOCALFILE_H_ -// -// Now a user of localfile can declare their dependence on it by -// #including "localfile.h". - -//------------------------------------------------------------------------ - -// The following code is mostly ugly details about how the -// initialization is implemented, and can be safely ignored -// by users of the initialization facility. - -#include <string> - -#include "base/basictypes.h" - -// A static instance of 'GoogleInitializer' is declared for every -// piece of initialization code. The constructor registers the -// code in the initialization table. This class is thread-safe. -class GoogleInitializer { - public: - typedef void (*Initializer)(); - - // Register the specified initialization "function" as the - // initialization code for "name". The "type" parameter controls - // which initializer set this initializer will added to. Note that - // an initializer might end up being run from a different set if it - // is required using the REQUIRE_GOOGLE_INITIALIZED macro. Normally - // the type parameter is "module". Its existence allows the - // specification of other "initializer sets." See file/base/file.h - // and File::Init() for an example of such a set. It's unlikely this - // additional functionality will be used very often. - GoogleInitializer(const char* type, const char* name, Initializer function); - - // Invoke all registered initializers that have not yet been - // executed. The "type" parameter specifies which set of - // initializers to run. The initializers are invoked in - // lexicographically increasing order by name, except as necessary - // to satisfy dependencies. This routine is invoked by InitGoogle(), - // so application code should not call it except in special - // circumstances. - static void RunInitializers(const char* type); - - // If this initialization has not yet been executed, runs it - // right after running all the initializers registered to come before it, - // these initializers are invoked in lexicographically increasing order - // by name, except as necessary to satisfy dependencies. - // It is an error to call this method if the corresponding - // initializer method is currently active (i.e., we do not - // allow cycles in the requirement graph). - void Require(); - - // Helper data-holder struct that is passed into - // DependencyRegisterer's c-tor below. - struct Dependency { - Dependency(const char* n, GoogleInitializer* i) : name(n), initializer(i) {} - const char* const name; - GoogleInitializer* const initializer; - }; - - // A static instance of 'DependencyRegisterer' is declared for every - // piece of initializer ordering definition. The constructor registers the - // ordering relation in the initialization table. This class is thread-safe. - struct DependencyRegisterer { - // Ask to run initializer specified by 'dependency' - // before the 'initializer' with 'name'. - // Both initializers are supposed to be of type 'type'. - DependencyRegisterer(const char* type, - const char* name, - GoogleInitializer* initializer, - const Dependency& dependency); - private: - void SharedConstructorCode(const char* type, - const char* name, - GoogleInitializer* initializer, - const Dependency& dependency); - - DISALLOW_EVIL_CONSTRUCTORS(DependencyRegisterer); - }; - - // Side note: If we happen to decide that connecting all initializers into an - // explicit DAG with one/few sink node(s) that depend on everything else - // is important (to explicitly specify in code all the - // required initializers of a binary) we can provide something like - // static bool DoneAllInitializers(const char *type); - // to check that all registered initializers have been executed. - // Going this route does not seem worth it though: - // it's equivalent to mandating creation of a third complete - // module dependency DAG, the first two being via #include-s and BUILD - // dependencies. - - // Helper structs in .cc; public to declare file-level globals. - struct InitializerData; - struct TypeData; - - private: - void SharedConstructorCode(const char* type, - const char* name, - Initializer function); - - const string type_; // Initializer type - const string name_; // Initializer name - Initializer function_; // The actual initializer - bool done_; // Finished initializing? - bool is_active_; // Is currently running - - // Implementation helper for Require() and RunInitializers: - // Runs initializer *this and all its dependencies - // if that has not happened yet. - // Assumes table_lock is reader-held and TypeData::lock for type_ is held. - void RunIfNecessary_Locked(); - - // Helper to initialize/create and return data for a given initializer type. - static TypeData* InitializerTypeData(const char* type); - - DISALLOW_EVIL_CONSTRUCTORS(GoogleInitializer); -}; - -//------------------------------------------------------------------------ - -// Implementation Internals (most users should ignore) -// -// The *_GOOGLE_* macros are used to make separate initializer -// sets. They should not be used directly by application code, but are -// useful to library writers who want to create a new registration -// mechanism. (See google2file.h and the *_FILE_* macros for an -// example). - -// TODO(maxim): When DECLARE_GOOGLE_INITIALIZER is not used in -// REQUIRE_GOOGLE_INITIALIZED and REQUIRE_GOOGLE_MODULE -// put google_initializer_##type##_##name (and google_init_##type##_##name) -// into a gI##type namespace to force our users to use -// DECLARE_GOOGLE_INITIALIZER not reimplement it -// to manually declare an initializer. - -#define DECLARE_GOOGLE_INITIALIZER(type, name) \ - extern GoogleInitializer google_initializer_##type##_##name - -#define REGISTER_GOOGLE_INITIALIZER(type, name, body) \ - static void google_init_##type##_##name() { body; } \ - GoogleInitializer google_initializer_##type##_##name( \ - #type, #name, google_init_##type##_##name) - -// Require initializer name1 of 'type' to run before initializer -// initializer name2 of same 'type' (i.e. in the order they are written out). -// "Sequence" only means ordering, not direct executions sequence -// without any other initializer executed in between. -// Initializers for both modules must be declared -// with DECLARE_GOOGLE_INITIALIZER at this point. -#define REGISTER_GOOGLE_INITIALIZER_SEQUENCE(type, name1, name2) \ - namespace { \ - static GoogleInitializer::DependencyRegisterer \ - google_initializer_dependency_##type##_##name1##_##name2( \ - #type, #name2, &google_initializer_##type##_##name2, \ - GoogleInitializer::Dependency( \ - #name1, &google_initializer_##type##_##name1)); \ - } -// Require initializers name1, name2, name3 of 'type' to run in the above order. -// Added to support this frequent use case more conveniently. -#define REGISTER_GOOGLE_INITIALIZER_SEQUENCE_3(type, name1, name2, name3) \ - REGISTER_GOOGLE_INITIALIZER_SEQUENCE(type, name1, name2); \ - REGISTER_GOOGLE_INITIALIZER_SEQUENCE(type, name2, name3) - -// Calling REQUIRE_GOOGLE_INITIALIZED(type, foo) means to make sure intializer -// for foo and everything it depends on have executed, and as such -// it can be used to e.g. pre-execute subsets of initializers -// e.g. before everything is executed via RUN_GOGLE_INITIALIZERS(type). -// The initializer must be declared with DECLARE_GOOGLE_INITIALIZER(type, name). -// TODO : remove DECLARE_GOOGLE_INITIALIZER here -// when all old code makes use of DECLARE_GOOGLE_INITIALIZER. -#define REQUIRE_GOOGLE_INITIALIZED(type, name) \ - do { \ - DECLARE_GOOGLE_INITIALIZER(type, name); \ - google_initializer_##type##_##name.Require(); \ - } while (0) - -#define RUN_GOOGLE_INITIALIZERS(type) \ - do { \ - GoogleInitializer::RunInitializers(#type); \ - } while (0) - -// We force the dependant module to be loaded by taking the -// address of an object inside the dependency -// (created by REGISTER_GOOGLE_INITIALIZER). The rest -// is required to avoid warnings about unused variables and -// make sure gcc doesn't optimize it out of existence. -// The initializer must be declared with DECLARE_GOOGLE_INITIALIZER(type, name). -// TODO : remove DECLARE_GOOGLE_INITIALIZER here -// when all old code makes use of DECLARE_GOOGLE_INITIALIZER. -#define REQUIRE_GOOGLE_MODULE(type, name) \ - DECLARE_GOOGLE_INITIALIZER(type, name); \ - static struct GoogleModuleRef_##name { \ - GoogleModuleRef_##name(GoogleInitializer* r) : ref(r) {} \ - GoogleInitializer* ref; \ - } google_module_ref_##name(&google_initializer_##type##_##name) - - -// External Interface (most users should use these macros) - -#define DECLARE_MODULE_INITIALIZER(name) \ - DECLARE_GOOGLE_INITIALIZER(module, name) - -#define REGISTER_MODULE_INITIALIZER(name, body) \ - REGISTER_GOOGLE_INITIALIZER(module, name, body) - -#define REGISTER_MODULE_INITIALIZER_SEQUENCE(name1, name2) \ - REGISTER_GOOGLE_INITIALIZER_SEQUENCE(module, name1, name2) - -#define REGISTER_MODULE_INITIALIZER_SEQUENCE_3(name1, name2, name3) \ - REGISTER_GOOGLE_INITIALIZER_SEQUENCE_3(module, name1, name2, name3) - -#define REQUIRE_MODULE_INITIALIZED(name) \ - REQUIRE_GOOGLE_INITIALIZED(module, name) - -#define RUN_MODULE_INITIALIZERS() \ - RUN_GOOGLE_INITIALIZERS(module) - -// TODO : maybe rename this as REQUIRE_MODULE_LINKED -#define REQUIRE_MODULE(name) \ - REQUIRE_GOOGLE_MODULE(module, name) - -//------------------------------------------------------------------------ - -#endif // BASE_GOOGLEINIT_H_ |