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.
9 /*============================================================
11 ** Header: Threads.inl
13 ** Purpose: Implements Thread inline functions
16 ===========================================================*/
21 #include "appdomain.hpp"
24 #ifndef DACCESS_COMPILE
27 EXTERN_C __declspec(thread) ThreadLocalInfo gCurrentThreadInfo;
29 EXTERN_C __thread ThreadLocalInfo gCurrentThreadInfo;
32 EXTERN_C inline Thread* STDCALL GetThread()
34 return gCurrentThreadInfo.m_pThread;
37 EXTERN_C inline AppDomain* STDCALL GetAppDomain()
39 return AppDomain::GetCurrentDomain();
42 #endif // !DACCESS_COMPILE
44 inline void Thread::IncLockCount()
46 LIMITED_METHOD_CONTRACT;
47 _ASSERTE(GetThread() == this);
49 _ASSERTE(m_dwLockCount != 0 || HasThreadStateNC(TSNC_UnbalancedLocks));
52 inline void Thread::DecLockCount()
54 LIMITED_METHOD_CONTRACT;
55 _ASSERTE(GetThread() == this);
56 _ASSERTE(m_dwLockCount > 0 || HasThreadStateNC(TSNC_UnbalancedLocks));
61 Frame* Thread::FindFrame(SIZE_T StackPointer)
63 Frame* pFrame = GetFrame();
65 while ((SIZE_T)pFrame < StackPointer)
67 pFrame = pFrame->Next();
73 inline void Thread::SetThrowable(OBJECTREF pThrowable DEBUG_ARG(ThreadExceptionState::SetThrowableErrorChecking stecFlags))
77 m_ExceptionState.SetThrowable(pThrowable DEBUG_ARG(stecFlags));
80 // get the current notification (if any) from this thread
81 inline OBJECTHANDLE Thread::GetThreadCurrNotification()
91 return m_hCurrNotification;
94 // set the current notification (if any) from this thread
95 inline void Thread::SetThreadCurrNotification(OBJECTHANDLE handle)
104 m_hCurrNotification = handle;
107 // clear the current notification (if any) from this thread
108 inline void Thread::ClearThreadCurrNotification()
117 m_hCurrNotification = NULL;
121 inline OBJECTREF Thread::GetExposedObjectRaw()
130 return ObjectFromHandle(m_ExposedObject);
133 inline void Thread::FinishSOWork()
136 _ASSERTE(!HasThreadStateNC(TSNC_SOWorkNeeded));
139 #ifdef FEATURE_COMINTEROP
140 inline void Thread::RevokeApartmentSpy()
142 LIMITED_METHOD_CONTRACT;
144 if (m_fInitializeSpyRegistered)
146 VERIFY(SUCCEEDED(CoRevokeInitializeSpy(m_uliInitializeSpyCookie)));
147 m_fInitializeSpyRegistered = false;
151 inline LPVOID Thread::GetLastSTACtxCookie(BOOL *pfNAContext)
153 LIMITED_METHOD_CONTRACT;
154 *pfNAContext = ((UINT_PTR)m_pLastSTACtxCookie & 1);
155 return (LPVOID)((UINT_PTR)m_pLastSTACtxCookie & ~1);
158 inline void Thread::SetLastSTACtxCookie(LPVOID pCtxCookie, BOOL fNAContext)
160 LIMITED_METHOD_CONTRACT;
163 // The ctx cookie is an interface pointer so we can steal the lowest bit
164 // to mark whether the context is known to be Neutral Apartment or not.
165 m_pLastSTACtxCookie = (LPVOID)((UINT_PTR)pCtxCookie | 1);
169 m_pLastSTACtxCookie = pCtxCookie;
172 #endif // FEATURE_COMINTEROP
174 inline bool Thread::IsGCSpecial()
176 LIMITED_METHOD_CONTRACT;
180 inline void Thread::SetGCSpecial(bool fGCSpecial)
182 LIMITED_METHOD_CONTRACT;
183 m_fGCSpecial = fGCSpecial;
186 #if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
188 inline Thread::CurrentPrepareCodeConfigHolder::CurrentPrepareCodeConfigHolder(Thread *thread, PrepareCodeConfig *config)
194 LIMITED_METHOD_CONTRACT;
195 _ASSERTE(thread != nullptr);
196 _ASSERTE(thread == GetThread());
197 _ASSERTE(config != nullptr);
199 PrepareCodeConfig *previousConfig = thread->m_currentPrepareCodeConfig;
200 if (previousConfig != nullptr)
202 config->SetNextInSameThread(previousConfig);
204 thread->m_currentPrepareCodeConfig = config;
207 inline Thread::CurrentPrepareCodeConfigHolder::~CurrentPrepareCodeConfigHolder()
209 LIMITED_METHOD_CONTRACT;
211 PrepareCodeConfig *config = m_thread->m_currentPrepareCodeConfig;
212 _ASSERTE(config == m_config);
213 m_thread->m_currentPrepareCodeConfig = config->GetNextInSameThread();
214 config->SetNextInSameThread(nullptr);
217 #endif // !DACCESS_COMPILE && !CROSSGEN_COMPILE