Mobile API Reference  MicroStrategy 2019
ModuleMainPtr.h
Go to the documentation of this file.
1 //==============================================================================================
2 // FILENAME : ModuleMainPtr.h
3 // AUTHOR : vovechkin
4 // CREATION : 2001-12-05
5 // Copyright (C) MicroStrategy Incorporated 2001
6 //==============================================================================================
7 #ifndef MBase_ModuleMainPtr_h
8 #define MBase_ModuleMainPtr_h
9 
10 #include "Asserte.h"
11 
12 #include "../Interfaces/BaseException.h"
13 #include "SpinLock.h"
14 
15 namespace MBase
16 {
28  template< class I /* interface */, class T = I /* class implementing I */ >
30  {
31  public:
32 
33  // 2002-08-29 vovechkin -- IMPORTANT:
34  // We can't initialize member variables in this contructor
35  // because (at least on AIX w/VisualAge) this contructor
36  // might be called **after** somebody have called Initialize()
37  // i.e. if they use a static C++ object as an initializer.
39  {
40  // C/C++ compiler guarantees that all global variables without
41  // explicit initializers will be initialized to 0 at program load time.
42 
43  // Since a typical variable of this template is a global variable,
44  // then we should expect that mnUsageCounter and mpModuleMain are both 0
45  }
46 
47  inline void Initialize();
48 
49  inline void Finalize() throw();
50 
51  inline I* operator->()
52  {
53  I* lpModuleMain = mpModuleMain;
54  _ASSERTE( lpModuleMain != NULL );
55  return lpModuleMain;
56  }
57 
58  inline I& operator*()
59  {
60  return *(operator->());
61  }
62 
63  private:
64  SpinLock mSpinLock;
65  unsigned Int32 mnUsageCounter;
66  I* mpModuleMain;
67  };
68 
69  template< class I, class T >
71  {
72  SpinLock::SmartLock lLock(mSpinLock);
73 
74  // sanity check
75  _ASSERT( mnUsageCounter >= 0 && mnUsageCounter < 10000 );
76 
77  if( ++mnUsageCounter == 1 )
78  {
79  try
80  {
81  mpModuleMain = new T;
82  }
83  catch (MBase::BaseException& e)
84  {
85  --mnUsageCounter;
86  _ASSERT( mnUsageCounter == 0 );
87 
88  // module initialization failed!
89  _ASSERT( false );
90 
91  throw;
92  }
93  catch(...)
94  {
95  --mnUsageCounter;
96  _ASSERT( mnUsageCounter == 0 );
97 
98  // module initialization failed!
99  _ASSERT( false );
100 
101  throw;
102  }
103  }
104  }
105 
106  template< class I, class T >
107  inline void ModuleMainPtr< I, T >::Finalize() throw()
108  {
109  SpinLock::SmartLock lLock(mSpinLock);
110 
111  // sanity check
112  _ASSERT( mnUsageCounter > 0 && mnUsageCounter <= 10000 );
113 
114  if( --mnUsageCounter == 0 )
115  {
116  // delete as T, which was used for operator new
117  // this way, I does not have to have a virtual destructor
118  delete static_cast< T* >( mpModuleMain );
119 
120  // ground the pointer
121  mpModuleMain = NULL;
122  }
123  }
124 }
125 
126 #endif // MBase_ModuleMainPtr_h
127 
I & operator*()
Definition: ModuleMainPtr.h:58
#define _ASSERT(x)
Definition: Asserte.h:34
#define I(x, y, z)
Definition: rmd160.h:49
void Finalize()
Definition: ModuleMainPtr.h:107
#define _ASSERTE(x)
Definition: Asserte.h:40
void Initialize()
Definition: ModuleMainPtr.h:70
Definition: SpinLock.h:34
#define Int32
Definition: BasicTypes.h:20
Definition: SpinLock.h:22
Definition: Message.h:32
Definition: Allocator.h:47
I * operator->()
Definition: ModuleMainPtr.h:51
ModuleMainPtr()
Definition: ModuleMainPtr.h:38
#define NULL
Definition: Null.h:10
Definition: ModuleMainPtr.h:29