summaryrefslogtreecommitdiff
path: root/ace/Object_Manager.h
blob: 9f05c5e744d79e1fd67209111e1ad41c223a7fb8 (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
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
/* -*- C++ -*- */
// $Id$

// ============================================================================
//
// = LIBRARY
//    ace
//
// = FILENAME
//    Object_Manager.h
//
// = AUTHORS
//    David L. Levine, Matthias Kerkhoff, and Per Andersson
//
// ============================================================================

#if !defined (ACE_OBJECT_MANAGER_H)
#define ACE_OBJECT_MANAGER_H

#include "ace/OS.h"

#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
  class ACE_Mutex;
  class ACE_Null_Mutex;
  class ACE_Thread_Mutex;
  class ACE_Recursive_Thread_Mutex;
  class ACE_RW_Thread_Mutex;
#endif /* ACE_MT_SAFE */
class ACE_Sig_Set;

// Forward declaration.
template <class T> class ACE_Unbounded_Queue;

#if !defined (ACE_MAX_MANAGED_OBJECTS)
# define ACE_MAX_MANAGED_OBJECTS 128
#endif /* ! ACE_MAX_MANAGED_OBJECTS */

#if !defined (ACE_APPLICATION_PREALLOCATED_OBJECT_DECLARATIONS)
# define ACE_APPLICATION_PREALLOCATED_OBJECT_DECLARATIONS
#endif /* ! ACE_APPLICATION_PREALLOCATED_OBJECT_DECLARATIONS */

#if !defined (ACE_APPLICATION_PREALLOCATED_ARRAY_DECLARATIONS)
# define ACE_APPLICATION_PREALLOCATED_ARRAY_DECLARATIONS
#endif /* ! ACE_APPLICATION_PREALLOCATED_ARRAY_DECLARATIONS */

class ACE_Export ACE_Object_Manager
{
  // = TITLE
  //     Manager for ACE library services and singleton cleanup.
  //
  // = DESCRIPTION
  //     The <ACE_Object_Manager> manages cleanup of objects, typically
  //     singletons, at program termination.  In addition to managing
  //     the cleanup of the ACE library, it provides an interface for
  //     application to register objects to be cleaned up.
  //
  //     This class also shuts down ACE library services, so that they
  //     can reclaim their storage, at program termination.  It works
  //     by creating a static instance whose destructor gets called
  //     along with those of all other static objects.  Hooks are
  //     provided for application code to register objects and arrays
  //     for cleanup, e.g., destruction.  The order of such cleanup
  //     calls is in the reverse order of registration, i.e., that
  //     last object/array to register gets cleaned up first.
  //
  //     The <ACE_Object_Manager> API includes <ACE_Managed_Object>.  That
  //     class is contained in a separate file because it is a
  //     template class, and some compilers require that template and
  //     non-template class definitions appear in separate files.
  //     Please see ace/Managed_Object.h for a description of that
  //     part of the API.  In summary, <ACE_Managed_Object> provides two
  //     adapters, the <ACE_Cleanup_Adapter> and <ACE_Managed_Object>
  //     template classes for adapting objects of any type to be
  //     easily managed by the <ACE_Object_Manager>.  There are several
  //     mechanisms for adapting objects and arrays for cleanup at
  //     program termination, in roughly increasing order of ease-of-use:
  //
  //     1) Derive the object's class from <ACE_Cleanup>.
  //     2) Allow the <ACE_Object_Manager> to both dynamically allocate
  //        and deallocate the object.
  //     3) Provide an <ACE_CLEANUP_FUNC> cleanup hook for the object or
  //        array.
  //     4) Allow the <ACE_Object_Manager> to both preallocate the object
  //        or array, either statically in global data or dynamically on
  //        the heap, when its singleton instance is construction.
  //
  //     There are also several mechanisms for registering objects and
  //     arrays for cleanup.  In decreasing order of flexibility and
  //     complexity (with the exception of the last mechanism):
  //
  //      1) ACE_Object_Manager::at_exit (void *object,
  //                                      ACE_CLEANUP_FUNC cleanup_hook,
  //                                      void *param);
  //         can be used to register any object or array for any
  //         cleanup activity at program termination.
  //
  //      2) ACE_Object_Manager::at_exit (ACE_Cleanup *object,
  //                                      void *param = 0);
  //         can be used to register an <ACE_Cleanup> object
  //         for any cleanup activity at program termination.
  //
  //      The final mechanism is not general purpose, but can only
  //      be used to allocate objects and arrays at program startup:
  //
  //      3) ACE_Managed_Object::get_preallocated_object
  //           (ACE_Object_Manager::Preallocated_Object id);
  //         and
  //         ACE_Managed_Object::get_preallocated_array
  //           (ACE_Object_Manager::Preallocated_Array id);
  //         can only be used to allocate objects at program startup,
  //         either in global data or on the heap (selected at compile
  //         time).  These are intended to replace static locks, etc.
  //
  //     Instead of creating a static <ACE_Object_Manager> instance, one
  //     can alternatively be created on the stack of the main program
  //     thread.  It is created just after entry to ::main (int, char
  //     *[]), and before any existing code in that function is
  //     executed.  To enable this alternative, add #define
  //     ACE_HAS_NONSTATIC_OBJECT_MANAGER to ace/config.h prior to
  //     building the ACE library and your applications.  This #define
  //     is enabled in the VxWorks config files that are supplied with
  //     ACE.
  //
  //     By default (except on VxWorks), the ACE library creates a
  //     static, singleton <ACE_Object_Manager> instance.  The
  //     instance is placed in global program data, and constructed
  //     via a static object constructor.  Optionally, the
  //     <ACE_Object_Manager> instance can be created on the stack of
  //     the main program thread.  This option is enabled by added
  //     "#define ACE_HAS_NONSTATIC_OBJECT_MANAGER" to ace/config.h
  //     before building libACE.  This option is enabled by default on
  //     VxWorks.
  //
  //     With ACE_HAS_NONSTATIC_OBJECT_MANAGER enabled, the ACE
  //     library has no static objects that require destruction.
  //     However, there are two drawbacks to using it:
  //
  //     1) main (int, char *[]) must be declared with arguments, even
  //        if they're not used.  All of ACE is converted to this, so
  //        just applications have to be concerned with it.
  //
  //     2) If there any static objects that depend on those that are
  //        cleaned up by the Object_Manager, they'll get cleaned up too
  //        late.  The ACE tests do not violate this requirement.
  //        However, applications may have trouble with it.
public:
  static int at_exit (ACE_Cleanup *object, void *param = 0);
  // 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 (void *object,
                      ACE_CLEANUP_FUNC cleanup_hook,
                      void *param);
  // 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.

#if 0 /* not implemented yet */
  static int at_thread_exit (void *object,
                             ACE_CLEANUP_FUNC cleanup_hook,
                             void *param);
  // Similar to at_exit (), except that the cleanup_hook is called
  // when the current thread exits instead of when the program terminates.
#endif /* 0 */

  enum Preallocated_Object
    {
      ACE_FILECACHE_LOCK,
#if defined (ACE_HAS_THREADS)
      ACE_STATIC_OBJECT_LOCK,
#endif /* ACE_HAS_THREADS */
#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
      ACE_LOG_MSG_INSTANCE_LOCK,
      ACE_MT_CORBA_HANDLER_LOCK,
      ACE_DUMP_LOCK,
      ACE_OS_MONITOR_LOCK,
      ACE_SIG_HANDLER_LOCK,
      ACE_SINGLETON_NULL_LOCK,
      ACE_SINGLETON_RECURSIVE_THREAD_LOCK,
      ACE_THREAD_EXIT_LOCK,
      ACE_TOKEN_MANAGER_CREATION_LOCK,
      ACE_TOKEN_INVARIANTS_CREATION_LOCK,
      ACE_TSS_CLEANUP_LOCK,
#endif /* ACE_MT_SAFE */

      // Hook for preallocated objects provided by application.
      ACE_APPLICATION_PREALLOCATED_OBJECT_DECLARATIONS

      ACE_PREALLOCATED_OBJECTS  // This enum value must be last!
    };
  // Unique identifiers for preallocated objects.  Please see
  // ace/Managed_Object.h for information on accessing preallocated
  // objects.

  enum Preallocated_Array
    {
      // There currently are no preallocated arrays in the ACE
      // library.  If the application doesn't have any, make sure
      // the the preallocated_array size is at least one by declaring
      // this dummy . . .
      ACE_EMPTY_PREALLOCATED_ARRAY,

      // Hook for preallocated arrays provided by application.
      ACE_APPLICATION_PREALLOCATED_ARRAY_DECLARATIONS

      ACE_PREALLOCATED_ARRAYS  // This enum value must be last!
    };
  // Unique identifiers for preallocated arrays.  Please see
  // ace/Managed_Object.h for information on accessing preallocated
  // arrays.

  static int starting_up ();
  // Returns 1 before ACE_Object_Manager has been constructed.  This
  // flag can be used to determine if the program is constructing
  // static objects.  If no static object spawns any threads, the
  // program will be single-threaded when this flag returns 1.  (Note
  // that the program still might construct some static objects when
  // this flag returns 0, if ACE_HAS_NON_STATIC_OBJECT_MANAGER is not
  // defined.)

  static int shutting_down ();
  // Returns 1 after ACE_Object_Manager has been destroyed.  This flag
  // can be used to determine if the program is in the midst of
  // destroying static objects.  (Note that the program might destroy
  // some static objects before this flag can return 1, if
  // ACE_HAS_NON_STATIC_OBJECT_MANAGER is not defined.)

  static ACE_Sig_Set &default_mask (void);
  // Accesses a default signal set used in ACE_Sig_Guard methods.

private:

#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
public:
  // = The <get_singleton_lock> accessors are for internal use by ACE_Singleton _only_.

  static int get_singleton_lock (ACE_Null_Mutex *&);
  // Accesses an <ACE_Null_Mutex> to be used for construction of
  // <ACE_Singletons>.  Returns 0, and the lock in the argument, on
  // success; returns -1 on failure.  The argument is ignored -- it is
  // only used for overload resolution.

  static int get_singleton_lock (ACE_Thread_Mutex *&);
  // Accesses a non-recursive <ACE_Thread_Mutex> to be used for
  // construction of <ACE_Singletons>.  Returns 0, and the lock in the
  // argument, on success; returns -1 on failure.  The argument is
  // ignored -- it is only used for overload resolution.

  static int get_singleton_lock (ACE_Mutex *&);
  // Accesses a non-recursive <ACE_Mutex> to be used for construction
  // of <ACE_Singletons>.  Returns 0, and the lock in the argument, on
  // success; returns -1 on failure.  The argument is ignored -- it is
  // only used for overload resolution.

  static int get_singleton_lock (ACE_Recursive_Thread_Mutex *&);
  // Accesses a recursive <ACE_Recursive_Thread_Mutex> to be used for
  // construction of <ACE_Singletons>.  Returns 0, and the lock in the
  // argument, on success; returns -1 on failure.

  static int get_singleton_lock (ACE_RW_Thread_Mutex *&);
  // Accesses a readers/writer <ACE_RW_Thread_Mutex> to be used for
  // construction of <ACE_Singletons>.  Returns 0, and the lock in the
  // argument, on success; returns -1 on failure.

private:

#endif /* ACE_MT_SAFE */

  ACE_Unbounded_Queue<ACE_Cleanup_Info> *registered_objects_;
  // Keeps track of all registered objects.

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

  static ACE_Object_Manager *instance_;
  // Singleton pointer.

  static int starting_up_;
  // Flag indicating whether the program is starting up.

  static int shutting_down_;
  // Flag indicating whether the program is shutting down.

  static ACE_Sig_Set *default_mask_p_;
  // Default signal set used in ACE_Sig_Guard.

public:
  // For internal use only by ACE_Managed_Objects.

#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
  ACE_Recursive_Thread_Mutex *lock_;
  // Lock that is used to guard internal structures.  Just a pointer
  // is declared here in order to minimize the headers that this one
  // includes.
#endif /* ACE_MT_SAFE */

  static ACE_Object_Manager *instance (void);
  // Accessor to singleton instance.  Because static member functions
  // are provided in the interface, this should not be public.  However,
  // it is public so that ACE_Managed_Object<TYPE> can access it.

  static void *managed_object[ACE_MAX_MANAGED_OBJECTS];
  // Table of managed objects.

  static u_int next_managed_object;
  // Index of the next available managed object table slot.

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

  static void *preallocated_array[ACE_PREALLOCATED_ARRAYS];
  // Table of preallocated arrays.

public:
  // Application code should not use these explicitly, so they're
  // hidden here.  They're public so that the ACE_Object_Manager can
  // be constructed/destructed in main () with
  // ACE_HAS_NONSTATIC_OBJECT_MANAGER.
  ACE_Object_Manager (void);
  ~ACE_Object_Manager (void);

private:
#if defined (ACE_HAS_TSS_EMULATION)
  // Main thread's thread-specific storage array.
  void *ts_storage_[ACE_TSS_Emulation::ACE_TSS_THREAD_KEYS_MAX];
#endif /* ACE_HAS_TSS_EMULATION */

#if !defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER)
  friend class ACE_Object_Manager_Destroyer;
#endif /* ACE_HAS_NONSTATIC_OBJECT_MANAGER */

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

#if defined (ACE_HAS_THREADS)

class ACE_Recursive_Thread_Mutex;

class ACE_Export ACE_Static_Object_Lock
{
  // = TITLE
  //     Provide an interface to access a global lock.
  //
  // = DESCRIPTION
  //     This class is used to serialize the creation of static
  //     singleton objects.  It really isn't needed any more, because
  //     anyone can access ACE_STATIC_OBJECT_LOCK directly.  But, it
  //     is retained for backward compatibility.
public:
  static ACE_Recursive_Thread_Mutex *instance (void);
  // Static lock access point.

  static void cleanup_lock (void);
  // For use only by ACE_Object_Manager to clean up lock if it
  // what dynamically allocated.
};

#endif /* ACE_HAS_THREADS */

#if defined (__ACE_INLINE__)
#include "ace/Object_Manager.i"
#endif /* __ACE_INLINE__ */

#include "ace/Managed_Object.h"

#endif /* ACE_OBJECT_MANAGER_H */