Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / common / Initialize.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
2 /*
3  * Ceph - scalable distributed file system
4  *
5  * Copyright (C) 2014 UnitedStack <haomai@unitedstack.com>
6  *
7  * Author: Haomai Wang <haomaiwang@gmail.com>
8  *
9  * This is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License version 2.1, as published by the Free Software
12  * Foundation.  See file COPYING.
13  *
14  */
15 /* Copyright (c) 2011 Stanford University
16  *
17  * Permission to use, copy, modify, and distribute this software for any
18  * purpose with or without fee is hereby granted, provided that the above
19  * copyright notice and this permission notice appear in all copies.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
22  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
23  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
24  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
25  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
26  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
27  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
28  */
29
30 #ifndef CEPH_INITIALIZE_H
31 #define CEPH_INITIALIZE_H
32
33 /**
34  * This class is used to manage once-only initialization that should occur
35  * before main() is invoked, such as the creation of static variables.  It
36  * also provides a mechanism for handling dependencies (where one class
37  * needs to perform its once-only initialization before another).
38  * 
39  * The simplest way to use an Initialize object is to define a static
40  * initialization method for a class, say Foo::init().  Then, declare
41  * a static Initialize object in the class:
42  * "static Initialize initializer(Foo::init);".
43  * The result is that Foo::init will be invoked when the object is
44  * constructed (before main() is invoked).  Foo::init can create static
45  * objects and perform any other once-only initialization needed by the
46  * class.  Furthermore, if some other class needs to ensure that Foo has
47  * been initialized (e.g. as part of its own initialization) it can invoke
48  * Foo::init directly (Foo::init should contain an internal guard so that
49  * it only performs its functions once, even if invoked several times).
50  *
51  * There is also a second form of constructor for Initialize that causes a
52  * new object to be dynamically allocated and assigned to a pointer, instead
53  * of invoking a function. This form allows for the creation of static objects
54  * that are never destructed (thereby avoiding issues with the order of
55  * destruction).
56  */
57 class Initialize {
58  public:
59   /**
60    * This form of constructor causes its function argument to be invoked
61    * when the object is constructed.  When used with a static Initialize
62    * object, this will cause \p func to run before main() runs, so that
63    * \p func can perform once-only initialization.
64    *
65    * \param func
66    *      This function is invoked with no arguments when the object is
67    *      constructed.  Typically the function will create static
68    *      objects and/or invoke other initialization functions.  The
69    *      function should normally contain an internal guard so that it
70    *      only performs its initialization the first time it is invoked.
71    */
72   explicit Initialize(void (*func)()) {
73     (*func)();
74   }
75
76   /**
77    * This form of constructor causes a new object of a particular class
78    * to be constructed with a no-argument constructor and assigned to a
79    * given pointer.  This form is typically used with a static Initialize
80    * object: the result is that the object will be created and assigned
81    * to the pointer before main() runs.
82    *
83    * \param p
84    *      Pointer to an object of any type. If the pointer is NULL then
85    *      it is replaced with a pointer to a newly allocated object of
86    *      the given type.
87    */
88   template<typename T>
89   explicit Initialize(T*& p) {
90     if (p == NULL) {
91       p = new T;
92     }
93   }
94 };
95
96 #endif  // CEPH_INITIALIZE_H