(file) Return to instance.h CVS log (file) (dir) Up to [OMI] / omi / micxx

  1 mike  1.1 /*
  2           **==============================================================================
  3           **
  4           ** Open Management Infrastructure (OMI)
  5           **
  6           ** Copyright (c) Microsoft Corporation
  7           ** 
  8           ** Licensed under the Apache License, Version 2.0 (the "License"); you may not 
  9           ** use this file except in compliance with the License. You may obtain a copy 
 10           ** of the License at 
 11           **
 12           **     http://www.apache.org/licenses/LICENSE-2.0 
 13           **
 14           ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15           ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 
 16           ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 
 17           ** MERCHANTABLITY OR NON-INFRINGEMENT. 
 18           **
 19           ** See the Apache 2 License for the specific language governing permissions 
 20           ** and limitations under the License.
 21           **
 22 mike  1.1 **==============================================================================
 23           */
 24           
 25           #ifndef _micxx_instance_h
 26           #define _micxx_instance_h
 27           
 28           #include <MI.h>
 29           #include "linkage.h"
 30           #include "atomic.h"
 31           #include "memory.h"
 32 krisbash 1.3 #include "micxx_string.h"
 33 mike     1.1 #include "field.h"
 34              #include "array.h"
 35              #include "types.h"
 36              
 37              MI_BEGIN_NAMESPACE
 38              
 39              //////////////////////////
 40              //  Base class for C++ MI_Instance representation
 41              class MICXX_LINKAGE Instance
 42              {
 43              public:
 44              
 45                  Instance();
 46              
 47                  Instance(const Instance& x);
 48              
 49                  ~Instance();
 50              
 51                  Instance& operator=(const Instance& x);
 52              
 53 krisbash 1.3     inline MI_Instance* GetInstance() const
 54                  {
 55                      return m_instance;
 56                  }
 57              
 58 mike     1.1     String GetNamespace() const;
 59              
 60                  void SetNamespace(const String& nameSpace);
 61              
 62                  void Print(FILE* os = stdout, MI_Uint32 level = 0) const;
 63              
 64                  static const MI_ClassDecl* GetClassDecl();
 65              
 66 krisbash 1.3     // Sets whether to use copy-on-write behavior. This function is 
 67                  // experimental (as indicated by the leading double underscore).
 68                  void __setCopyOnWrite(bool flag)
 69                  {
 70                      GetHeader(m_instance)->u.s.m_disableCopyOnWrite = flag ? 0 : 1;
 71                  }
 72              
 73                  // Gets the copy-on-write flag from the MI_Instance header.
 74                  bool __getCopyOnWrite() const
 75                  {
 76                      return GetHeader(m_instance)->u.s.m_disableCopyOnWrite ? false : true;
 77                  }
 78              
 79                  // Forces a copy-on-write operation (if refrence count is not 1). After
 80                  // calling this function, the instance will have a pointer to its own
 81                  // copy of MI_Instance whose reference count is 1.
 82                  void __forceCopyOnWrite()
 83                  {
 84                      Header* header = GetHeader(m_instance);
 85              
 86                      // Avoid the copy on write if sharing has been enabled.
 87 krisbash 1.3 
 88                      if (AtomicGet(header->u.s.m_refCounter) != 1)
 89                      {
 90                          MI_Instance* current = m_instance;
 91                          m_instance = Clone();
 92                          AddRef(m_instance);
 93                          Release(current);
 94                      }
 95                  }
 96              
 97 mike     1.1 protected:
 98              
 99                  Instance(
100                      const MI_ClassDecl* clDecl, 
101                      const MI_Instance* instance, 
102                      bool keysOnly);
103              
104                  Instance(
105                      const MI_ClassDecl* clDecl);
106              
107                  Instance(
108                      const MI_MethodDecl* methodDecl);
109              
110                  Instance(
111                      const MI_MethodDecl* methodDecl, 
112                      const MI_Instance* instance, 
113                      bool keysOnly);
114              
115                  void CopyRef(
116                      const Instance& x);
117              
118 mike     1.1     void COW()
119                  {
120 krisbash 1.3         Header* header = GetHeader(m_instance);
121              
122                      // Avoid the copy on write if sharing has been enabled.
123              
124                      if (header->u.s.m_disableCopyOnWrite == 0 && 
125                          AtomicGet(header->u.s.m_refCounter) != 1)
126 mike     1.1         {
127                          MI_Instance* current = m_instance;
128                          m_instance = Clone();
129                          AddRef(m_instance);
130                          Release(current);
131                      }
132                  }
133              
134                  template<typename T>
135                  Field<T>& GetField(size_t offset)
136                  {
137                      COW();
138                      void* ptr = reinterpret_cast<char*>(m_instance) + offset;
139                      return *(reinterpret_cast<Field<T>*>(ptr));
140                  }
141              
142                  template<typename T>
143                  const Field<T>& GetField(size_t offset) const
144                  {
145                      const void* ptr = reinterpret_cast<const char*>(m_instance) + offset;
146                      return *(reinterpret_cast<const Field<T>*>(ptr));
147 mike     1.1     }
148              
149              private:
150              
151 krisbash 1.3     // helper data - placed before MI_Instance structure
152 mike     1.1     struct Header
153                  {
154                      union 
155                      {
156                          struct _HeaderData
157                          {
158 krisbash 1.3                 AtomicType m_refCounter;
159                              unsigned int m_disableCopyOnWrite;
160 mike     1.1             } 
161                          s;
162 krisbash 1.3             char alignment[(sizeof(struct _HeaderData) + 15) & ~15];
163 mike     1.1         }
164                      u;
165                  };
166              
167                  void Initialize(
168                      const MI_ClassDecl* clDecl, 
169                      const MI_Instance* instance, 
170                      bool keysOnly);
171              
172                  static Header* GetHeader(MI_Instance* instance) 
173                  {
174                      return reinterpret_cast<Header*>(
175                          reinterpret_cast<char*>(instance) - sizeof(Header));
176                  }
177              
178                  static void AddRef(MI_Instance* instance) 
179                  { 
180                      AtomicInc(GetHeader(instance)->u.s.m_refCounter); 
181                  }
182              
183                  static void Release(MI_Instance* instance);
184 mike     1.1 
185                  static MI_Instance* Create(const MI_ClassDecl* clDecl);
186              
187                  MI_Instance* Clone() const;
188              
189                  MI_Instance* m_instance;
190              
191                  friend class Context;
192                  friend class DInstance;
193              
194                  MICXX_LINKAGE
195                  friend bool __IsA(const MI_ClassDecl*, const Instance*);
196              };
197              
198              inline Instance::Instance() : m_instance(0) 
199              {
200              }
201              
202              inline Instance::Instance(const Instance& x) : m_instance(0)
203              {
204                  CopyRef(x);
205 mike     1.1 }
206              
207              inline Instance::~Instance()
208              {
209                  Release(m_instance);
210              }
211              
212              inline Instance& Instance::operator=(const Instance& x)
213              {
214                 CopyRef(x);
215                 return *this;
216              }
217              
218              template<>
219              inline const ArrayTraits* GetArrayTraits<Instance>() 
220              {
221                  return __traits[MI_INSTANCE];
222              };
223              
224              typedef Array<Instance> InstanceA;
225              
226 mike     1.1 MICXX_LINKAGE
227              bool __IsA(const MI_ClassDecl* classDecl, const Instance* instance);
228              
229              template<class CLASS>
230              bool IsA(const Instance& instance)
231              {
232                  return __IsA(((CLASS*)0)->GetClassDecl(), &instance);
233              }
234              
235              MI_END_NAMESPACE
236              
237              #endif /* _micxx_instance_h */

ViewCVS 0.9.2