diff options
Diffstat (limited to '')
-rw-r--r-- | src/common/Initialize.h | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/src/common/Initialize.h b/src/common/Initialize.h new file mode 100644 index 000000000..78ad5ec69 --- /dev/null +++ b/src/common/Initialize.h @@ -0,0 +1,96 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2014 UnitedStack <haomai@unitedstack.com> + * + * Author: Haomai Wang <haomaiwang@gmail.com> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ +/* Copyright (c) 2011 Stanford University + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef CEPH_INITIALIZE_H +#define CEPH_INITIALIZE_H + +/** + * This class is used to manage once-only initialization that should occur + * before main() is invoked, such as the creation of static variables. It + * also provides a mechanism for handling dependencies (where one class + * needs to perform its once-only initialization before another). + * + * The simplest way to use an Initialize object is to define a static + * initialization method for a class, say Foo::init(). Then, declare + * a static Initialize object in the class: + * "static Initialize initializer(Foo::init);". + * The result is that Foo::init will be invoked when the object is + * constructed (before main() is invoked). Foo::init can create static + * objects and perform any other once-only initialization needed by the + * class. Furthermore, if some other class needs to ensure that Foo has + * been initialized (e.g. as part of its own initialization) it can invoke + * Foo::init directly (Foo::init should contain an internal guard so that + * it only performs its functions once, even if invoked several times). + * + * There is also a second form of constructor for Initialize that causes a + * new object to be dynamically allocated and assigned to a pointer, instead + * of invoking a function. This form allows for the creation of static objects + * that are never destructed (thereby avoiding issues with the order of + * destruction). + */ +class Initialize { + public: + /** + * This form of constructor causes its function argument to be invoked + * when the object is constructed. When used with a static Initialize + * object, this will cause \p func to run before main() runs, so that + * \p func can perform once-only initialization. + * + * \param func + * This function is invoked with no arguments when the object is + * constructed. Typically the function will create static + * objects and/or invoke other initialization functions. The + * function should normally contain an internal guard so that it + * only performs its initialization the first time it is invoked. + */ + explicit Initialize(void (*func)()) { + (*func)(); + } + + /** + * This form of constructor causes a new object of a particular class + * to be constructed with a no-argument constructor and assigned to a + * given pointer. This form is typically used with a static Initialize + * object: the result is that the object will be created and assigned + * to the pointer before main() runs. + * + * \param p + * Pointer to an object of any type. If the pointer is NULL then + * it is replaced with a pointer to a newly allocated object of + * the given type. + */ + template<typename T> + explicit Initialize(T*& p) { + if (p == NULL) { + p = new T; + } + } +}; + +#endif // CEPH_INITIALIZE_H |