m_trappingRuntimeThreads = TRUE;
// Take the thread store lock.
- bool alreadyHeldThreadStoreLock = ThreadStore::HoldingThreadStore();
- if (!alreadyHeldThreadStoreLock)
- {
- STRESS_LOG0(LF_CORDB, LL_INFO1000, "About to lock thread Store\n");
- ThreadSuspend::LockThreadStore(ThreadSuspend::SUSPEND_FOR_DEBUGGER);
- STRESS_LOG0(LF_CORDB, LL_INFO1000, "Locked thread store\n");
- }
+ assert(ThreadStore::HoldingThreadStore());
// We start the suspension here, and let the helper thread finish it.
// If there's no helper thread, then we need to do helper duty.
// We will have released the TSL after the call to continue.
}
- else
- {
- // We have a live and active helper thread which will handle events
- // from the RS now that we're stopped.
- // We need to release the TSL which we acquired above. (The helper will
- // likely take this lock while doing stuff).
- if (!alreadyHeldThreadStoreLock)
- {
- STRESS_LOG0(LF_CORDB, LL_INFO1000, "About to unlock thread store!\n");
- ThreadSuspend::UnlockThreadStore(FALSE, ThreadSuspend::SUSPEND_FOR_DEBUGGER);
- STRESS_LOG0(LF_CORDB, LL_INFO1000, "TART: Unlocked thread store!\n");
- }
- }
_ASSERTE(ThreadHoldsLock()); // still hold the lock. (though it may have been toggled)
}
}
// be sent as part of attach if debugger was launched by managed app.
//
DebuggerLockHolder dbgLockHolder(this, FALSE);
+ bool lockedThreadStore = false;
if ((pEvent->type & DB_IPCE_TYPE_MASK) == DB_IPCE_ASYNC_BREAK ||
(pEvent->type & DB_IPCE_TYPE_MASK) == DB_IPCE_ATTACHING ||
this->m_isBlockedOnGarbageCollectionEvent)
{
+ lockedThreadStore = true;
+ ThreadSuspend::LockThreadStore(ThreadSuspend::SUSPEND_FOR_DEBUGGER);
dbgLockHolder.Acquire();
}
else
STRESS_LOG0(LF_CORDB, LL_INFO10000, "D::HIPCE: finished handling event\n");
+ if (lockedThreadStore)
+ {
+ ThreadSuspend::UnlockThreadStore(FALSE, ThreadSuspend::SUSPEND_FOR_DEBUGGER);
+ }
// dbgLockHolder goes out of scope - implicit Release
return fContinue;
}
#include "common.h"
#include "winwrap.h"
#include "threads.h"
+#include "threadsuspend.h"
#include "frames.h"
#include "appdomain.hpp"
#endif
private:
HANDLE GetGarbageCollectionBlockerEvent() { return GetLazyData()->m_garbageCollectionBlockerEvent; }
-
+
};
LPCWSTR lpName
);
-#define SENDIPCEVENT_RAW_BEGIN_EX(pDbgLockHolder, gcxStmt) \
- { \
- ThreadStore::LockThreadStore(); \
- Debugger::DebuggerLockHolder *__pDbgLockHolder = pDbgLockHolder; \
- gcxStmt; \
+#define SENDIPCEVENT_RAW_BEGIN_EX(pDbgLockHolder, gcxStmt) \
+ { \
+ ThreadSuspend::LockThreadStore(ThreadSuspend::SUSPEND_FOR_DEBUGGER); \
+ Debugger::DebuggerLockHolder *__pDbgLockHolder = pDbgLockHolder; \
+ gcxStmt; \
g_pDebugger->LockForEventSending(__pDbgLockHolder);
-#define SENDIPCEVENT_RAW_END_EX \
- g_pDebugger->UnlockFromEventSending(__pDbgLockHolder); \
- ThreadStore::UnlockThreadStore(); \
+#define SENDIPCEVENT_RAW_END_EX \
+ g_pDebugger->UnlockFromEventSending(__pDbgLockHolder); \
+ ThreadStore::UnlockThreadStore(); \
}
#define SENDIPCEVENT_RAW_BEGIN(pDbgLockHolder) \
Debugger::DebuggerLockHolder __dbgLockHolder(pDebugger, FALSE); \
Debugger::DebuggerLockHolder *__pDbgLockHolder = &__dbgLockHolder; \
gcxStmt; \
- ThreadStore::LockThreadStore(); \
+ ThreadSuspend::LockThreadStore(ThreadSuspend::SUSPEND_FOR_DEBUGGER); \
g_pDebugger->LockForEventSending(__pDbgLockHolder); \
/* Check if the thread has been suspended by the debugger via SetDebugState(). */ \
if (thread != NULL && thread->HasThreadStateNC(Thread::TSNC_DebuggerUserSuspend)) \