summaryrefslogtreecommitdiff
path: root/ace/Framework_Component.h
blob: 318867773ba3033ff9ef275f2e6efe981998ebf9 (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
/* -*- C++ -*- */
//=============================================================================
/**
 *  @file    Framework_Component.h
 *
 *  $Id$
 *
 * A prototype mechanism that allows framework components, singletons
 * such as ACE_Reactor, ACE_Proactor, etc, to be registered with a
 * central repository managed by the <ACE_Object_Manager> or
 * <ACE_Service_Config> that will handle destruction.
 *
 * This technique obviates changing ACE_Object_Manager and
 * ACE_Service_Config everytime a new framework is added.  Which also
 * means that unused framework components don't need to linked into
 * the final application which is important for applications with
 * stringent footprint requirements.
 *
 * Framework components need only provide a static method,
 * close_singleton() and add the ACE_REGISTER_FRAMEWORK_COMPONENT macro
 * call to their instance() methods in order to participate.  Components
 * that don't have a close_singleton() method can also participate via
 * template specialization of ACE_Framework_Component_T.
 *
 * This design uses the External Polymorphism pattern to avoid having
 * to derive all framework components from a common base class that
 * has virtual methods (this is crucial to avoid unnecessary overhead),
 * and is based on the dump debugging implementation found in
 * <ace/Dump.h>.
 *
 *  @author Don Hinton <dhinton@ieee.org>.
 */
//=============================================================================

#ifndef ACE_FRAMEWORK_COMPONENT_H
#define ACE_FRAMEWORK_COMPONENT_H
#include /**/ "ace/pre.h"

#include "ace/ACE_export.h"

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

#include "ace/os_include/os_signal.h"
#include "ace/Thread_Mutex.h"

#define ACE_DEFAULT_FRAMEWORK_REPOSITORY_SIZE 1024

/**
 * @class ACE_Framework_Component
 *
 * @brief Base class that defines a uniform interface for all managed
 * framework components.
 */
class ACE_Export ACE_Framework_Component
{
public:
  friend class ACE_Framework_Repository;

  /// Constructor.
  ACE_Framework_Component (void *_this,
                           const ACE_TCHAR *dll_name = 0,
                           const ACE_TCHAR *name = 0);

  /// Close the contained singleton.
  virtual void close_singleton (void) = 0;

protected:
  /// Destructor.
  virtual ~ACE_Framework_Component (void);

private:
  /// Pointer to the actual component.
  const void *this_;

  /// Library associated with this component
  const ACE_TCHAR *dll_name_;

  /// Component name
  const ACE_TCHAR *name_;
};

/**
 * @class ACE_Framework_Repository
 *
 * @brief Contains all framework components used by an application.
 *
 * This class contains a vector of ACE_Framework_Component *'s.  On
 * destruction, framework components are destroyed in the reverse order
 * that they were added originally.
 */
class ACE_Export ACE_Framework_Repository
{
public:
  // This is just to silence a compiler warning about no public ctors
  friend class ACE_Framework_Component;

  enum
  {
    DEFAULT_SIZE = ACE_DEFAULT_FRAMEWORK_REPOSITORY_SIZE
  };

  /// Close down the repository and free up dynamically allocated
  /// resources.
  ~ACE_Framework_Repository (void);

  /// Initialize the repository.
  int open (int size = DEFAULT_SIZE);

  /// Close down the repository and free up dynamically allocated
  /// resources, also called by dtor.
  int close (void);

  /// Get pointer to a process-wide <ACE_Framework_Repository>.
  static ACE_Framework_Repository *instance
    (int size = ACE_Framework_Repository::DEFAULT_SIZE);

  /// Delete the dynamically allocated Singleton.
  static void close_singleton (void);

  // = Search structure operations (all acquire locks as necessary).

  /// Insert a new component.  Returns -1 when the repository is full
  /// and 0 on success.
  int register_component (ACE_Framework_Component *fc);

  /// Remove a component.  Returns -1 on error or if component not found
  /// and 0 on success.
  int remove_component (const ACE_TCHAR *name);

  /// Remove all components associated with a particular dll.
  int remove_dll_components (const ACE_TCHAR *dll_name);

  /// Return the current size of the repository.
  int current_size (void) const;

  /// Return the total size of the repository.
  int total_size (void) const;

  /// Dump the state of an object.
  void dump (void) const;

  /// Declare the dynamic allocation hooks.
  ACE_ALLOC_HOOK_DECLARE;

private:
  // = Initialization and termination methods.

  /// Initialize the repository.
  ACE_Framework_Repository (int size = ACE_Framework_Repository::DEFAULT_SIZE);

  /// Actually removes the dll components, must be called with locks held.
  int remove_dll_components_i (const ACE_TCHAR *dll_name);

  /// Compact component_vector_ after components have been removed__maintains
  /// order.
  void compact (void);

  /// Contains all the framework components.
  ACE_Framework_Component **component_vector_;

  /// Current number of components.
  int current_size_;

  /// Maximum number of components.
  int total_size_;

  /// Pointer to a process-wide ACE_Framework_Repository.
  static ACE_Framework_Repository *repository_;

  /// Flag set when repository is the process of shutting down.  This
  /// is necessary to keep from self-deadlocking since some of
  /// the components might make calls back to the repository to
  /// unload their components, e.g., ACE_DLL_Manager.
  static sig_atomic_t shutting_down_;

#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
  /// Synchronization variable for the MT_SAFE Repository
  ACE_Thread_Mutex lock_;
#endif /* ACE_MT_SAFE */

  /// Don't allow these to be called.
  ACE_UNIMPLEMENTED_FUNC (ACE_Framework_Repository (const ACE_Framework_Repository &))
  ACE_UNIMPLEMENTED_FUNC (ACE_Framework_Repository &operator= (const ACE_Framework_Repository &))
};

#if defined (__ACE_INLINE__)
#include "ace/Framework_Component.inl"
#endif /* __ACE_INLINE__ */

// Include the templates classes at this point.
#include "ace/Framework_Component_T.h"

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