bool MachThread::RestoreSuspendCount() { DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )", __FUNCTION__); DNBError err; if (ThreadIDIsValid(m_tid) == false) return false; else if (m_suspendCount > m_basicInfo.suspend_count) { while (m_suspendCount > m_basicInfo.suspend_count) { err = ::thread_resume (m_tid); if (err.Success()) --m_suspendCount; if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail()) err.LogThreaded("::thread_resume (%4.4x)", m_tid); } } else if (m_suspendCount < m_basicInfo.suspend_count) { while (m_suspendCount < m_basicInfo.suspend_count) { err = ::thread_suspend (m_tid); if (err.Success()) --m_suspendCount; if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail()) err.LogThreaded("::thread_suspend (%4.4x)", m_tid); } } return m_suspendCount == m_basicInfo.suspend_count; }
void MachThread::Resume(bool others_stopped) { DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )", __FUNCTION__); if (ThreadIDIsValid(m_tid)) { SetSuspendCountBeforeResume(others_stopped); } }
uint32_t MachThread::Resume() { DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )", __FUNCTION__); if (ThreadIDIsValid(m_tid)) { RestoreSuspendCount(); } return SuspendCount(); }
bool MachThread::GetBasicInfo(thread_t thread, struct thread_basic_info *basicInfoPtr) { if (ThreadIDIsValid(thread)) { unsigned int info_count = THREAD_BASIC_INFO_COUNT; kern_return_t err = ::thread_info (thread, THREAD_BASIC_INFO, (thread_info_t) basicInfoPtr, &info_count); if (err == KERN_SUCCESS) return true; } ::memset (basicInfoPtr, 0, sizeof (struct thread_basic_info)); return false; }
void MachThread::Suspend() { DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )", __FUNCTION__); if (ThreadIDIsValid(m_tid)) { DNBError err(::thread_suspend (m_tid), DNBError::MachKernel); if (err.Success()) m_suspend_count++; if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail()) err.LogThreaded("::thread_suspend (%4.4x)", m_tid); } }
bool MachThread::SetSuspendCountBeforeResume(bool others_stopped) { DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )", __FUNCTION__); DNBError err; if (ThreadIDIsValid(m_tid) == false) return false; size_t times_to_resume; if (others_stopped) { if (GetBasicInfo()) { times_to_resume = m_basic_info.suspend_count; m_suspend_count = - (times_to_resume - m_suspend_count); } else times_to_resume = 0; } else { times_to_resume = m_suspend_count; m_suspend_count = 0; } if (times_to_resume > 0) { while (times_to_resume > 0) { err = ::thread_resume (m_tid); if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail()) err.LogThreaded("::thread_resume (%4.4x)", m_tid); if (err.Success()) --times_to_resume; else { if (GetBasicInfo()) times_to_resume = m_basic_info.suspend_count; else times_to_resume = 0; } } } return true; }
uint32_t MachThread::Resume() { DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )", __FUNCTION__); if (ThreadIDIsValid(m_tid)) { while (m_suspendCount > 0) { DNBError err(::thread_resume (m_tid), DNBError::MachKernel); if (err.Success()) m_suspendCount--; if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail()) err.LogThreaded("::thread_resume (%4.4x)", m_tid); } } return SuspendCount(); }
bool MachThread::RestoreSuspendCountAfterStop () { DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )", __FUNCTION__); DNBError err; if (ThreadIDIsValid(m_tid) == false) return false; if (m_suspend_count > 0) { while (m_suspend_count > 0) { err = ::thread_resume (m_tid); if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail()) err.LogThreaded("::thread_resume (%4.4x)", m_tid); if (err.Success()) --m_suspend_count; else { if (GetBasicInfo()) m_suspend_count = m_basic_info.suspend_count; else m_suspend_count = 0; return false; // ??? } } } else if (m_suspend_count < 0) { while (m_suspend_count < 0) { err = ::thread_suspend (m_tid); if (err.Success()) ++m_suspend_count; if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail()) { err.LogThreaded("::thread_suspend (%4.4x)", m_tid); return false; } } } return true; }
bool MachThread::RestoreSuspendCount() { DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )", __FUNCTION__); DNBError err; if (ThreadIDIsValid(m_tid) == false) return false; if (m_suspendCount > 0) { while (m_suspendCount > 0) { err = ::thread_resume (m_tid); if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail()) err.LogThreaded("::thread_resume (%4.4x)", m_tid); if (err.Success()) --m_suspendCount; else { if (GetBasicInfo()) m_suspendCount = m_basicInfo.suspend_count; else m_suspendCount = 0; return false; // ??? } } } // We don't currently really support resuming a thread that was externally // suspended. If/when we do, we will need to make the code below work and // m_suspendCount will need to become signed instead of unsigned. // else if (m_suspendCount < 0) // { // while (m_suspendCount < 0) // { // err = ::thread_suspend (m_tid); // if (err.Success()) // ++m_suspendCount; // if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail()) // err.LogThreaded("::thread_suspend (%4.4x)", m_tid); // } // } return true; }