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 | // ThreadDebugBlockingInfo.cpp |
5 | // |
6 | |
7 | // |
8 | // |
9 | #include "common.h" |
10 | #include "threaddebugblockinginfo.h" |
11 | |
12 | //Constructor |
13 | ThreadDebugBlockingInfo::ThreadDebugBlockingInfo() |
14 | { |
15 | m_firstBlockingItem = NULL; |
16 | } |
17 | |
18 | //Destructor |
19 | ThreadDebugBlockingInfo::~ThreadDebugBlockingInfo() |
20 | { |
21 | WRAPPER_NO_CONTRACT; |
22 | _ASSERTE(m_firstBlockingItem == NULL); |
23 | } |
24 | |
25 | // Adds a new blocking item at the front of the list |
26 | // The caller is responsible for allocating the memory this points to and keeping it alive until |
27 | // after PopBlockingItem is called |
28 | #ifndef DACCESS_COMPILE |
29 | VOID ThreadDebugBlockingInfo::PushBlockingItem(DebugBlockingItem *pItem) |
30 | { |
31 | LIMITED_METHOD_CONTRACT; |
32 | |
33 | _ASSERTE(pItem != NULL); |
34 | pItem->pNext = m_firstBlockingItem; |
35 | m_firstBlockingItem = pItem; |
36 | } |
37 | #endif //!DACCESS_COMPILE |
38 | |
39 | // Removes the most recently added item (FIFO) |
40 | #ifndef DACCESS_COMPILE |
41 | VOID ThreadDebugBlockingInfo::PopBlockingItem() |
42 | { |
43 | LIMITED_METHOD_CONTRACT; |
44 | |
45 | _ASSERTE(m_firstBlockingItem != NULL); |
46 | m_firstBlockingItem = m_firstBlockingItem->pNext; |
47 | } |
48 | #endif //!DACCESS_COMPILE |
49 | |
50 | // Calls the visitor function on each item in the stack from front to back |
51 | #ifdef DACCESS_COMPILE |
52 | VOID ThreadDebugBlockingInfo::VisitBlockingItems(DebugBlockingItemVisitor visitorFunc, VOID* pUserData) |
53 | { |
54 | CONTRACTL |
55 | { |
56 | NOTHROW; |
57 | GC_NOTRIGGER; |
58 | MODE_ANY; |
59 | } |
60 | CONTRACTL_END; |
61 | |
62 | SUPPORTS_DAC; |
63 | |
64 | PTR_DebugBlockingItem pItem = m_firstBlockingItem; |
65 | while(pItem != NULL) |
66 | { |
67 | visitorFunc(pItem, pUserData); |
68 | pItem = pItem->pNext; |
69 | } |
70 | } |
71 | #endif //DACCESS_COMPILE |
72 | |
73 | // Holder constructor pushes a blocking item on the blocking info stack |
74 | #ifndef DACCESS_COMPILE |
75 | DebugBlockingItemHolder::DebugBlockingItemHolder(Thread *pThread, DebugBlockingItem *pItem) : |
76 | m_pThread(pThread) |
77 | { |
78 | LIMITED_METHOD_CONTRACT; |
79 | pThread->DebugBlockingInfo.PushBlockingItem(pItem); |
80 | } |
81 | #endif //DACCESS_COMPILE |
82 | |
83 | // Holder destructor pops a blocking item off the blocking info stack |
84 | #ifndef DACCESS_COMPILE |
85 | DebugBlockingItemHolder::~DebugBlockingItemHolder() |
86 | { |
87 | LIMITED_METHOD_CONTRACT; |
88 | m_pThread->DebugBlockingInfo.PopBlockingItem(); |
89 | } |
90 | #endif //DACCESS_COMPILE |
91 | |