summaryrefslogtreecommitdiff
path: root/TAO/tao/TAO_Singleton_Manager.h
blob: 3e8b3d729adcfd593cd593847caf8db0578b1d57 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
// -*- C++ -*-


//=============================================================================
/**
 *  @file    TAO_Singleton_Manager.h
 *
 *  $Id$
 *
 *   Header file for the TAO-specific Singleton Manager.  Based
 *   entirely on ace/Object_Manager.{h,i,cpp}.
 *
 *  @author  Ossama Othman <ossama@uci.edu>
 */
//=============================================================================

#ifndef TAO_SINGLETON_MANAGER_H
#define TAO_SINGLETON_MANAGER_H

#include /**/ "ace/pre.h"
#include "ace/config-all.h"

#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */

#include "tao/TAO_Export.h"
#include "tao/orbconf.h"
#include "ace/Object_Manager_Base.h"

#if (defined (ACE_HAS_VERSIONED_NAMESPACE) \
     && ACE_HAS_VERSIONED_NAMESPACE == 1) \
  && !(defined (_MSC_VER) && _MSC_VER <= 1200)
// MSVC++ 6's preprocessor can't handle macro expansions required by
// the versioned namespace support.  *sigh*

# define TAO_SINGLETON_MANAGER_CLEANUP_DESTROYER_NAME ACE_PREPROC_CONCATENATE(TAO_VERSIONED_NAMESPACE_NAME, _TAO_Singleton_Manager_cleanup_destroyer)

#else

# define TAO_SINGLETON_MANAGER_CLEANUP_DESTROYER_NAME TAO_Singleton_Manager_cleanup_destroyer

#endif  /* ACE_HAS_VERSIONED_NAMESPACE == 1 */

/// Adapter for cleanup, used to register cleanup function with the
/// ACE_Object_Manager.
extern "C"
void
TAO_SINGLETON_MANAGER_CLEANUP_DESTROYER_NAME (void *, void *);


TAO_BEGIN_VERSIONED_NAMESPACE_DECL

#if defined (ACE_HAS_EXCEPTIONS)
typedef void (*TAO_unexpected_handler)(void);
#endif  /* ACE_HAS_EXCEPTIONS */


/**
 * @class TAO_Singleton_Manager
 *
 * @brief Manager for TAO library services and singleton cleanup.
 *
 * The TAO_Singleton_Manager is basically simplified version of the
 * ACE_Object_Manager.  It is designed specifically to manage
 * singletons created by TAO.  For example, singleton instances
 * created by TAO will be automatically registered with the singleton
 * instance of this Singleton Manager.
 * @par
 * This class is necessary to ensure that TAO-specific
 * singletons are isolated to TAO itself, not ACE, for example.  The
 * idea is that destruction of the instance of the
 * TAO_Singleton_Manager triggers destruction of all objects/services
 * registered with it.
 */
class TAO_Export TAO_Singleton_Manager : public ACE_Object_Manager_Base
{

  friend void ::TAO_SINGLETON_MANAGER_CLEANUP_DESTROYER_NAME (void *, void *);

public:
  /// Explicitly initialize.
  virtual int init (void);

  /**
   * Explicitly initialize the TAO_Singleton_Manager, in addition to
   * explicitly registering (or not registering) with the
   * ACE_Object_Manager.
   */
  int init (int register_with_object_manager);

  /// Explicitly destroy.
  virtual int fini (void);

  /**
   * Returns 1 before the TAO_Singleton_Manager has been constructed.
   * See ACE_Object_Manager::starting_up for more information.
   */
  static int starting_up (void);

  /// Returns 1 after the TAO_Singleton_Manager has been destroyed.
  /// See ACE_Object_Manager::shutting_down for more information.
  static int shutting_down (void);

  /// Unique identifiers for preallocated Objects.
  enum Preallocated_Object
    {
# if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
      /// @@ No MT-specific preallocated objects (yet).  Remove the
      ///    below dummy enum once a preallocated object is added.
      TAO_EMPTY_PREALLOCATED_OBJECT,
# else
      /// Without ACE_MT_SAFE, There are no preallocated objects.
      /// Make sure that the preallocated_array size is at least one
      /// by declaring this dummy ...
      TAO_EMPTY_PREALLOCATED_OBJECT,
# endif /* ACE_MT_SAFE */

      /// This enum value must be last!
      TAO_PREALLOCATED_OBJECTS
    };

  /// Accesses a default signal set used, for example, in
  /// ACE_Sig_Guard methods.
  static sigset_t *default_mask (void);

  /// Returns the current thread hook for the process.
  static ACE_Thread_Hook *thread_hook (void);

  /// Returns the existing thread hook and assign a new_thread_hook.
  static ACE_Thread_Hook *thread_hook (ACE_Thread_Hook *new_thread_hook);

  /// Accessor to singleton instance.
  static TAO_Singleton_Manager *instance (void);

  /// Register an ACE_Cleanup object for cleanup at process
  /// termination.
  /**
   * The object is deleted via the ace_cleanup_destroyer.  If you need
   * more flexiblity, see the other at_exit method below.  For OS's
   * that do not have processes, cleanup takes place  at the end of
   * main.  Returns 0 on success.  On failure, returns -1 and sets
   * errno to: EAGAIN if shutting down, ENOMEM if insufficient virtual
   * memory, or EEXIST if the object (or array) had already been
   * registered.
   */
  static int at_exit (ACE_Cleanup *object, void *param = 0);

  /// Register an object (or array) for cleanup at process
  /// termination.
  /**
   * cleanup_hook points to a (global, or static member) function that
   * is called for the object or array when it to be destroyed.  It
   * may perform any necessary cleanup specific for that object or its
   * class.  param is passed as the second parameter to the
   * cleanup_hook function; the first parameter is the object (or
   * array) to be destroyed.  cleanup_hook, for example, may delete
   * the object (or array).  For OS's that do not have processes, this
   * function is the same as <at_thread_exit>.  Returns 0 on success.
   * On failure, returns -1 and sets errno to: EAGAIN if shutting
   * down, ENOMEM if insufficient virtual memory, or EEXIST if the
   * object (or array) had already been registered.
   */
  static int at_exit (void *object,
                      ACE_CLEANUP_FUNC cleanup_hook,
                      void *param);

#if defined (ACE_HAS_EXCEPTIONS)
  /// Set a new unexpected exception handler.
  /**
   * The old one will be stored for restoration later on.
   *
   * @note Calling this method multiple times will cause the stored
   *       old unexpected exception handler pointer to be lost.
   */
  void _set_unexpected (TAO_unexpected_handler u);
#endif /* ACE_HAS_EXCEPTIONS */

private:
  /// Force allocation on the heap.
  //@{
  TAO_Singleton_Manager (void);
  ~TAO_Singleton_Manager (void);
  //@}

  /// Disallow copying by not implementing the following ...
  //@{
  TAO_Singleton_Manager (const TAO_Singleton_Manager &);
  TAO_Singleton_Manager &operator= (const TAO_Singleton_Manager &);
  //@}

  /// Register an object or array for deletion at program termination.
  /// See description of static version above for return values.
  int at_exit_i (void *object, ACE_CLEANUP_FUNC cleanup_hook, void *param);

private:
  /// Singleton instance pointer.
  static TAO_Singleton_Manager *instance_;

  /// Table of preallocated objects.
  static void *preallocated_object[TAO_PREALLOCATED_OBJECTS];

  /// Default signal set used, for example, in ACE_Sig_Guard.
  sigset_t *default_mask_;

  /// Thread hook that's used by this process.
  ACE_Thread_Hook *thread_hook_;

  /// For at_exit support.
  ACE_OS_Exit_Info exit_info_;

  /// Indicates if TAO_Singleton_Manager is registered with the
  /// ACE_Object_Manager.
  int registered_with_object_manager_;

#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
  /// Lock that is used to guard internal structures.
  TAO_SYNCH_RECURSIVE_MUTEX *internal_lock_;
#endif /* ACE_MT_SAFE */

#if defined (ACE_HAS_EXCEPTIONS)
  /// The old unexpected exception handler.
  /**
   * A pointer to the old unexpected exception handler is stored so
   * that it can be restored when TAO is unloaded, for example.
   * Otherwise, any unexpected exceptions will result in a call to
   * TAO's unexpected exception handler which may no longer exist if
   * TAO was unloaded.
   */
  TAO_unexpected_handler old_unexpected_;
#endif  /* ACE_HAS_EXCEPTIONS */
};

TAO_END_VERSIONED_NAMESPACE_DECL

#if defined (__ACE_INLINE__)
# include "tao/TAO_Singleton_Manager.inl"
#endif /* __ACE_INLINE__ */

#include /**/ "ace/post.h"

#endif  /* TAO_SINGLETON_MANAGER_H */