bool Update(thread_id threadID) { if (fTeam == NULL) { for (int32 i = 0; Thread* thread = fThreads.ItemAt(i); i++) thread->ReleaseReference(); fThreads.MakeEmpty(); return true; } AutoLocker<Team> locker(fTeam); ThreadList::ConstIterator it = fTeam->Threads().GetIterator(); Thread* newThread = it.Next(); int32 index = 0; // remove no longer existing threads while (Thread* oldThread = fThreads.ItemAt(index)) { if (oldThread == newThread) { if (threadID >= 0 && oldThread->ID() == threadID) NotifyRowsChanged(index, 1); index++; newThread = it.Next(); } else { // TODO: Not particularly efficient! fThreads.RemoveItemAt(index); oldThread->ReleaseReference(); NotifyRowsRemoved(index, 1); } } // add new threads int32 countBefore = fThreads.CountItems(); while (newThread != NULL) { if (!fThreads.AddItem(newThread)) return false; newThread->AcquireReference(); newThread = it.Next(); } int32 count = fThreads.CountItems(); if (count > countBefore) NotifyRowsAdded(countBefore, count - countBefore); return true; }
Thread* Team::ThreadByID(thread_id threadID) const { for (ThreadList::ConstIterator it = fThreads.GetIterator(); Thread* thread = it.Next();) { if (thread->ID() == threadID) return thread; } return NULL; }
status_t DebugReportGenerator::_DumpRunningThreads(BFile& _output) { AutoLocker< ::Team> locker(fTeam); BString data("\nActive Threads:\n"); WRITE_AND_CHECK(_output, data); BObjectList< ::Thread> threads; ::Thread* thread; for (ThreadList::ConstIterator it = fTeam->Threads().GetIterator(); (thread = it.Next());) { threads.AddItem(thread); } threads.SortItems(&_CompareThreads); for (int32 i = 0; (thread = threads.ItemAt(i)) != NULL; i++) { try { data.SetToFormat("\tthread %" B_PRId32 ": %s %s\n", thread->ID(), thread->Name(), thread->IsMainThread() ? "(main)" : ""); WRITE_AND_CHECK(_output, data); if (thread->State() == THREAD_STATE_STOPPED) { data.SetToFormat("\t\tstate: %s", UiUtils::ThreadStateToString(thread->State(), thread->StoppedReason())); const BString& stoppedInfo = thread->StoppedReasonInfo(); if (stoppedInfo.Length() != 0) data << " (" << stoppedInfo << ")"; data << "\n\n"; WRITE_AND_CHECK(_output, data); // we need to release our lock on the team here // since we might need to block and wait // on the stack trace. BReference< ::Thread> threadRef(thread); locker.Unlock(); status_t error = _DumpDebuggedThreadInfo(_output, thread); if (error != B_OK) return error; locker.Lock(); } } catch (...) { return B_NO_MEMORY; } } return B_OK; }
status_t DebugReportGenerator::_DumpRunningThreads(BString& _output) { AutoLocker< ::Team> locker(fTeam); _output << "\nActive Threads:\n"; BString data; status_t result = B_OK; for (ThreadList::ConstIterator it = fTeam->Threads().GetIterator(); ::Thread* thread = it.Next();) { try { data.SetToFormat("\t%s %s, id: %" B_PRId32", state: %s", thread->Name(), thread->IsMainThread() ? "(main)" : "", thread->ID(), UiUtils::ThreadStateToString(thread->State(), thread->StoppedReason())); if (thread->State() == THREAD_STATE_STOPPED) { const BString& stoppedInfo = thread->StoppedReasonInfo(); if (stoppedInfo.Length() != 0) data << " (" << stoppedInfo << ")"; } _output << data << "\n"; if (thread->State() == THREAD_STATE_STOPPED) { // we need to release our lock on the team here // since we might need to block and wait // on the stack trace. BReference< ::Thread> threadRef(thread); locker.Unlock(); result = _DumpDebuggedThreadInfo(_output, thread); locker.Lock(); } if (result != B_OK) return result; } catch (...) { return B_NO_MEMORY; } } return B_OK; }
void CliContext::WaitForThreadOrUser() { ProcessPendingEvents(); // TODO: Deal with SIGINT as well! for (;;) { _PrepareToWaitForEvents( EVENT_USER_INTERRUPT | EVENT_THREAD_STOPPED); // check whether there are any threads stopped already Thread* stoppedThread = NULL; BReference<Thread> stoppedThreadReference; AutoLocker<Team> teamLocker(fTeam); for (ThreadList::ConstIterator it = fTeam->Threads().GetIterator(); Thread* thread = it.Next();) { if (thread->State() == THREAD_STATE_STOPPED) { stoppedThread = thread; stoppedThreadReference.SetTo(thread); break; } } teamLocker.Unlock(); if (stoppedThread != NULL) { if (fCurrentThread == NULL) SetCurrentThread(stoppedThread); _SignalInputLoop(EVENT_THREAD_STOPPED); } uint32 events = _WaitForEvents(); if ((events & EVENT_QUIT) != 0 || stoppedThread != NULL) { ProcessPendingEvents(); return; } } }