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 */
|