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
|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// ===========================================================================
// File: ListLock.cpp
//
//
// ===========================================================================
// This file decribes the list lock and deadlock aware list lock.
// ===========================================================================
#include "common.h"
#include "listlock.h"
#include "listlock.inl"
ListLockEntry::ListLockEntry(ListLock *pList, void *pData, const char *description)
: m_deadlock(description),
m_pList(pList),
m_pData(pData),
m_Crst(CrstListLock,
(CrstFlags)(CRST_REENTRANCY | (pList->IsHostBreakable()?CRST_HOST_BREAKABLE:0))),
m_pszDescription(description),
m_pNext(NULL),
m_dwRefCount(1),
m_hrResultCode(S_FALSE),
m_hInitException(NULL),
m_pLoaderAllocator(NULL)
#ifdef FEATURE_CORRUPTING_EXCEPTIONS
,
m_CorruptionSeverity(NotCorrupting)
#endif // FEATURE_CORRUPTING_EXCEPTIONS
{
WRAPPER_NO_CONTRACT;
}
ListLockEntry *ListLockEntry::Find(ListLock* pLock, LPVOID pPointer, const char *description)
{
CONTRACTL
{
THROWS;
GC_NOTRIGGER;
MODE_ANY;
}
CONTRACTL_END;
_ASSERTE(pLock->HasLock());
ListLockEntry *pEntry = pLock->Find(pPointer);
if (pEntry==NULL)
{
pEntry = new ListLockEntry(pLock, pPointer, description);
pLock->AddElement(pEntry);
}
else
pEntry->AddRef();
return pEntry;
};
void ListLockEntry::AddRef()
{
CONTRACTL
{
NOTHROW;
GC_NOTRIGGER;
MODE_ANY;
PRECONDITION(CheckPointer(this));
}
CONTRACTL_END;
FastInterlockIncrement((LONG*)&m_dwRefCount);
}
void ListLockEntry::Release()
{
CONTRACTL
{
NOTHROW;
GC_TRIGGERS;
MODE_ANY;
PRECONDITION(CheckPointer(this));
}
CONTRACTL_END;
ListLockHolder lock(m_pList);
if (FastInterlockDecrement((LONG*)&m_dwRefCount) == 0)
{
// Remove from list
m_pList->Unlink(this);
delete this;
}
};
|