1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4
5/*++
6
7
8
9Module Name:
10
11 palobjbase.cpp
12
13Abstract:
14 PAL object base class
15
16
17
18--*/
19
20#include "palobjbase.hpp"
21#include "pal/malloc.hpp"
22#include "pal/dbgmsg.h"
23
24SET_DEFAULT_DEBUG_CHANNEL(PAL);
25
26using namespace CorUnix;
27
28CObjectType* CObjectType::s_rgotIdMapping[ObjectTypeIdCount];
29
30/*++
31Function:
32 CPalObjectBase::Initialize
33
34 Performs possibly-failing initialization for a newly-constructed
35 object
36
37Parameters:
38 pthr -- thread data for calling thread
39 poa -- the object attributes (e.g., name) for the object
40--*/
41
42PAL_ERROR
43CPalObjectBase::Initialize(
44 CPalThread *pthr,
45 CObjectAttributes *poa
46 )
47{
48 PAL_ERROR palError = NO_ERROR;
49
50 _ASSERTE(NULL != pthr);
51 _ASSERTE(NULL != poa);
52
53 ENTRY("CPalObjectBase::Initialize"
54 "(this = %p, pthr = %p, poa = %p)\n",
55 this,
56 pthr,
57 poa
58 );
59
60 if (0 != m_pot->GetImmutableDataSize())
61 {
62 m_pvImmutableData = InternalMalloc(m_pot->GetImmutableDataSize());
63 if (NULL != m_pvImmutableData)
64 {
65 ZeroMemory(m_pvImmutableData, m_pot->GetImmutableDataSize());
66 }
67 else
68 {
69 ERROR("Unable to allocate immutable data\n");
70 palError = ERROR_OUTOFMEMORY;
71 goto IntializeExit;
72 }
73 }
74
75 if (0 != m_pot->GetProcessLocalDataSize())
76 {
77 palError = m_sdlLocalData.Initialize();
78 if (NO_ERROR != palError)
79 {
80 ERROR("Unable to initialize local data lock!\n");
81 goto IntializeExit;
82 }
83
84 m_pvLocalData = InternalMalloc(m_pot->GetProcessLocalDataSize());
85 if (NULL != m_pvLocalData)
86 {
87 ZeroMemory(m_pvLocalData, m_pot->GetProcessLocalDataSize());
88 }
89 else
90 {
91 ERROR("Unable to allocate local data\n");
92 palError = ERROR_OUTOFMEMORY;
93 goto IntializeExit;
94 }
95 }
96
97 if (0 != poa->sObjectName.GetStringLength())
98 {
99 palError = m_oa.sObjectName.CopyString(&poa->sObjectName);
100 }
101
102IntializeExit:
103
104 LOGEXIT("CPalObjectBase::Initialize returns %d\n", palError);
105
106 return palError;
107}
108
109/*++
110Function:
111 CPalObjectBase::GetObjectType
112
113 Returns the type of the object
114--*/
115
116CObjectType *
117CPalObjectBase::GetObjectType(
118 VOID
119 )
120{
121 ENTRY("CPalObjectBase::GetObjectType(this = %p)\n", this);
122 LOGEXIT("CPalObjectBase::GetObjectType returns %p\n", m_pot);
123
124 return m_pot;
125}
126
127/*++
128Function:
129 CPalObjectBase::GetObjectAttributes
130
131 Returns the attributes of the object
132--*/
133
134CObjectAttributes *
135CPalObjectBase::GetObjectAttributes(
136 VOID
137 )
138{
139 ENTRY("CPalObjectBase::GetObjectAttributes(this = %p)\n", this);
140 LOGEXIT("CPalObjectBase::GetObjectAttributes returns %p\n", &m_oa);
141
142 return &m_oa;
143}
144
145/*++
146Function:
147 CPalObjectBase::GetImmutableData
148
149 Provides the caller access to the object's immutable data (if any)
150
151Parameters:
152 ppvImmutableData -- on success, receives a pointer to the object's
153 immutable data
154--*/
155
156PAL_ERROR
157CPalObjectBase::GetImmutableData(
158 void **ppvImmutableData // OUT
159 )
160{
161 _ASSERTE(NULL != ppvImmutableData);
162
163 ENTRY("CPalObjectBase::GetImmutableData"
164 "(this = %p, ppvImmutableData = %p)\n",
165 this,
166 ppvImmutableData
167 );
168
169 _ASSERTE(0 < m_pot->GetImmutableDataSize());
170
171 *ppvImmutableData = m_pvImmutableData;
172
173 LOGEXIT("CPalObjectBase::GetImmutableData returns %d\n", NO_ERROR);
174
175 return NO_ERROR;
176}
177
178/*++
179Function:
180 CPalObjectBase::GetProcessLocalData
181
182 Provides the caller access to the object's local data (if any)
183
184Parameters:
185 pthr -- thread data for calling thread
186 eLockRequest -- specifies if the caller desires a read lock or a
187 write lock on the data (currently ignored)
188 ppDataLock -- on success, receives a pointer to the data lock instance
189 for the local data
190 ppvProcssLocalData -- on success, receives a pointer to the local data
191--*/
192
193PAL_ERROR
194CPalObjectBase::GetProcessLocalData(
195 CPalThread *pthr,
196 LockType eLockRequest,
197 IDataLock **ppDataLock, // OUT
198 void **ppvProcessLocalData // OUT
199 )
200{
201 _ASSERTE(NULL != pthr);
202 _ASSERTE(ReadLock == eLockRequest || WriteLock == eLockRequest);
203 _ASSERTE(NULL != ppDataLock);
204 _ASSERTE(NULL != ppvProcessLocalData);
205
206 ENTRY("CPalObjectBase::GetProcessLocalData"
207 "(this = %p, pthr = %p, eLockRequest = %d, ppDataLock = %p,"
208 " ppvProcessLocalData = %p)\n",
209 this,
210 pthr,
211 eLockRequest,
212 ppDataLock,
213 ppvProcessLocalData
214 );
215
216 _ASSERTE(0 < m_pot->GetProcessLocalDataSize());
217
218 m_sdlLocalData.AcquireLock(pthr, ppDataLock);
219 *ppvProcessLocalData = m_pvLocalData;
220
221 LOGEXIT("CPalObjectBase::GetProcessLocalData returns %d\n", NO_ERROR);
222
223 return NO_ERROR;
224}
225
226/*++
227Function:
228 CPalObjectBase::AddReference
229
230 Increments the object's reference count. The updated count is returned
231 for diagnostic purposes only
232--*/
233
234DWORD
235CPalObjectBase::AddReference(
236 void
237 )
238{
239 LONG lRefCount;
240
241 ENTRY("CPalObjectBase::AddReference(this = %p)\n", this);
242
243 _ASSERTE(m_lRefCount > 0);
244 lRefCount = InterlockedIncrement(&m_lRefCount);
245
246 LOGEXIT("CPalObjectBase::AddReference returns %d\n", lRefCount);
247
248 return lRefCount;
249}
250
251/*++
252Function:
253 CPalObjectBase::ReleaseReference
254
255 Decrements the object's reference count. The updated count is returned
256 for diagnostic purposes only
257
258Parameters:
259 pthr -- thread data for calling thread
260--*/
261
262DWORD
263CPalObjectBase::ReleaseReference(
264 CPalThread *pthr
265 )
266{
267 LONG lRefCount;
268
269 _ASSERTE(NULL != pthr);
270
271 ENTRY("CPalObjectBase::ReleaseReference"
272 "(this = %p, pthr = %p)\n",
273 this,
274 pthr
275 );
276
277 AcquireObjectDestructionLock(pthr);
278
279 _ASSERTE(m_lRefCount > 0);
280
281 //
282 // Even though object destruction takes place under a lock
283 // we still need to use an interlocked decrement, as AddRef
284 // operates lock free
285 //
286
287 lRefCount = InterlockedDecrement(&m_lRefCount);
288
289 if (0 == lRefCount)
290 {
291 bool fCleanupSharedState = ReleaseObjectDestructionLock(pthr, TRUE);
292
293 //
294 // We need to do two things with the calling thread data here:
295 // 1) store it in m_pthrCleanup so it is available to the destructors
296 // 2) Add a reference to it before starting any cleanup, and release
297 // that reference afterwords.
298 //
299 // Step 2 is necessary when we're cleaning up the thread object that
300 // represents the calling thread -- it ensures that the thread data
301 // is available throughout the entire cleanup process.
302 //
303
304 m_pthrCleanup = pthr;
305 pthr->AddThreadReference();
306
307 if (NULL != m_pot->GetObjectCleanupRoutine())
308 {
309 (*m_pot->GetObjectCleanupRoutine())(
310 pthr,
311 static_cast<IPalObject*>(this),
312 FALSE,
313 fCleanupSharedState
314 );
315 }
316
317 if (NULL != m_pot->GetImmutableDataCleanupRoutine())
318 {
319 (*m_pot->GetImmutableDataCleanupRoutine())(m_pvImmutableData);
320 }
321
322 if (NULL != m_pot->GetProcessLocalDataCleanupRoutine())
323 {
324 (*m_pot->GetProcessLocalDataCleanupRoutine())(pthr, static_cast<IPalObject*>(this));
325 }
326
327 InternalDelete(this);
328
329 pthr->ReleaseThreadReference();
330 }
331 else
332 {
333 ReleaseObjectDestructionLock(pthr, FALSE);
334 }
335
336 LOGEXIT("CPalObjectBase::ReleaseReference returns %d\n", lRefCount);
337
338 return lRefCount;
339}
340
341/*++
342Function:
343 CPalObjectBase::~CPalObjectBase
344
345 Object destructor
346--*/
347
348CPalObjectBase::~CPalObjectBase()
349{
350 ENTRY("CPalObjectBase::~CPalObjectBase(this = %p)\n", this);
351
352 if (NULL != m_pvImmutableData)
353 {
354 free(m_pvImmutableData);
355 }
356
357 if (NULL != m_pvLocalData)
358 {
359 free(m_pvLocalData);
360 }
361
362 if (NULL != m_oa.sObjectName.GetString())
363 {
364 m_oa.sObjectName.FreeBuffer();
365 }
366
367 LOGEXIT("CPalObjectBase::~CPalObjectBase\n");
368}
369
370