diff --git a/src/apps/debugger/user_interface/cli/CliContext.cpp b/src/apps/debugger/user_interface/cli/CliContext.cpp index cb915fbf18..bc2cd1fd5b 100644 --- a/src/apps/debugger/user_interface/cli/CliContext.cpp +++ b/src/apps/debugger/user_interface/cli/CliContext.cpp @@ -100,6 +100,7 @@ CliContext::CliContext() fEventsOccurred(0), fInputLoopWaiting(false), fTerminating(false), + fStoppedThread(NULL), fCurrentThread(NULL), fCurrentStackTrace(NULL), fCurrentStackFrameIndex(-1), @@ -381,43 +382,24 @@ CliContext::QuitSession(bool killTeam) void CliContext::WaitForThreadOrUser() { - ProcessPendingEvents(); - // TODO: Deal with SIGINT as well! - for (;;) { + + // if no thread has been stopped, wait till one is + while (fStoppedThread == NULL) { _PrepareToWaitForEvents( - EVENT_USER_INTERRUPT | EVENT_THREAD_STOPPED); - - // check whether there are any threads stopped already - Thread* stoppedThread = NULL; - BReference stoppedThreadReference; - - AutoLocker 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); - } - + EVENT_USER_INTERRUPT | EVENT_THREAD_STATE_CHANGED); uint32 events = _WaitForEvents(); - if ((events & EVENT_QUIT) != 0 || stoppedThread != NULL) { - ProcessPendingEvents(); + + ProcessPendingEvents(); + // updates fStoppedThread if any thread has been stopped + + if ((events & EVENT_QUIT) != 0) { return; } } + + if (fCurrentThread == NULL) + SetCurrentThread(fStoppedThread); } @@ -470,9 +452,14 @@ CliContext::ProcessPendingEvents() printf("[thread terminated: %" B_PRId32 " \"%s\"]\n", thread->ID(), thread->Name()); break; - case EVENT_THREAD_STOPPED: - printf("[thread stopped: %" B_PRId32 " \"%s\"]\n", - thread->ID(), thread->Name()); + case EVENT_THREAD_STATE_CHANGED: + if (thread->State() == THREAD_STATE_STOPPED) { + printf("[thread stopped: %" B_PRId32 " \"%s\"]\n", + thread->ID(), thread->Name()); + fStoppedThread.SetTo(thread); + } else { + fStoppedThread = NULL; + } break; case EVENT_THREAD_STACK_TRACE_CHANGED: if (thread == fCurrentThread) { @@ -524,12 +511,9 @@ CliContext::ThreadRemoved(const Team::ThreadEvent& threadEvent) void CliContext::ThreadStateChanged(const Team::ThreadEvent& threadEvent) { - if (threadEvent.GetThread()->State() != THREAD_STATE_STOPPED) - return; - _QueueEvent( - new(std::nothrow) Event(EVENT_THREAD_STOPPED, threadEvent.GetThread())); - _SignalInputLoop(EVENT_THREAD_STOPPED); + new(std::nothrow) Event(EVENT_THREAD_STATE_CHANGED, threadEvent.GetThread())); + _SignalInputLoop(EVENT_THREAD_STATE_CHANGED); } diff --git a/src/apps/debugger/user_interface/cli/CliContext.h b/src/apps/debugger/user_interface/cli/CliContext.h index 77f1bfb6fd..775522342a 100644 --- a/src/apps/debugger/user_interface/cli/CliContext.h +++ b/src/apps/debugger/user_interface/cli/CliContext.h @@ -38,7 +38,7 @@ public: EVENT_USER_INTERRUPT = 0x02, EVENT_THREAD_ADDED = 0x04, EVENT_THREAD_REMOVED = 0x08, - EVENT_THREAD_STOPPED = 0x10, + EVENT_THREAD_STATE_CHANGED = 0x10, EVENT_THREAD_STACK_TRACE_CHANGED = 0x20, EVENT_VALUE_NODE_CHANGED = 0x40, EVENT_TEAM_MEMORY_BLOCK_RETRIEVED = 0x80, @@ -151,6 +151,7 @@ private: bool fInputLoopWaiting; volatile bool fTerminating; + BReference fStoppedThread; Thread* fCurrentThread; StackTrace* fCurrentStackTrace; int32 fCurrentStackFrameIndex; diff --git a/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp b/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp index 371eb3f9c9..7a35671191 100644 --- a/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp +++ b/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp @@ -248,6 +248,8 @@ CommandLineUserInterface::_InputLoop() thread_id currentThread = -1; while (!fTerminating) { + fContext.ProcessPendingEvents(); + // Wait for a thread or Ctrl-C. fContext.WaitForThreadOrUser(); if (fContext.IsTerminating())