diff --git a/src/apps/debugger/user_interface/cli/CliContext.cpp b/src/apps/debugger/user_interface/cli/CliContext.cpp index 7b430dc19df..7654b3ec62c 100644 --- a/src/apps/debugger/user_interface/cli/CliContext.cpp +++ b/src/apps/debugger/user_interface/cli/CliContext.cpp @@ -118,6 +118,7 @@ CliContext::Init(Team* team, UserInterfaceListener* listener) fNodeManager = new(std::nothrow) ValueNodeManager(); if (fNodeManager == NULL) return B_NO_MEMORY; + fNodeManager->AddListener(this); return B_OK; } @@ -316,6 +317,25 @@ CliContext::WaitForThreadOrUser() } +void +CliContext::WaitForEvents(int32 eventMask) +{ + for (;;) { + _PrepareToWaitForEvents(eventMask | EVENT_USER_INTERRUPT); + uint32 events = fEventsOccurred; + if ((events & eventMask) == 0) { + events = _WaitForEvents(); + } + + if ((events & EVENT_QUIT) != 0 || (events & eventMask) != 0) { + _SignalInputLoop(eventMask); + ProcessPendingEvents(); + return; + } + } +} + + void CliContext::ProcessPendingEvents() { @@ -404,6 +424,35 @@ CliContext::ThreadStackTraceChanged(const Team::ThreadEvent& threadEvent) } +void +CliContext::ValueNodeChanged(ValueNodeChild* nodeChild, ValueNode* oldNode, + ValueNode* newNode) +{ + _SignalInputLoop(EVENT_VALUE_NODE_CHANGED); +} + + +void +CliContext::ValueNodeChildrenCreated(ValueNode* node) +{ + _SignalInputLoop(EVENT_VALUE_NODE_CHANGED); +} + + +void +CliContext::ValueNodeChildrenDeleted(ValueNode* node) +{ + _SignalInputLoop(EVENT_VALUE_NODE_CHANGED); +} + + +void +CliContext::ValueNodeValueChanged(ValueNode* oldNode) +{ + _SignalInputLoop(EVENT_VALUE_NODE_CHANGED); +} + + void CliContext::_QueueEvent(Event* event) { diff --git a/src/apps/debugger/user_interface/cli/CliContext.h b/src/apps/debugger/user_interface/cli/CliContext.h index faf6bfa3ae2..09d79d87f74 100644 --- a/src/apps/debugger/user_interface/cli/CliContext.h +++ b/src/apps/debugger/user_interface/cli/CliContext.h @@ -13,6 +13,7 @@ #include #include "Team.h" +#include "ValueNodeContainer.h" class StackFrame; @@ -22,7 +23,8 @@ class UserInterfaceListener; class ValueNodeManager; -class CliContext : private Team::Listener { +class CliContext : private Team::Listener, + private ValueNodeContainer::Listener { public: enum { EVENT_QUIT = 0x01, @@ -30,7 +32,8 @@ class CliContext : private Team::Listener { EVENT_THREAD_ADDED = 0x04, EVENT_THREAD_REMOVED = 0x08, EVENT_THREAD_STOPPED = 0x10, - EVENT_THREAD_STACK_TRACE_CHANGED = 0x20 + EVENT_THREAD_STACK_TRACE_CHANGED = 0x20, + EVENT_VALUE_NODE_CHANGED = 0x40 }; public: @@ -70,6 +73,7 @@ class CliContext : private Team::Listener { void QuitSession(bool killTeam); void WaitForThreadOrUser(); + void WaitForEvents(int32 eventMask); void ProcessPendingEvents(); private: @@ -87,6 +91,13 @@ class CliContext : private Team::Listener { virtual void ThreadStackTraceChanged( const Team::ThreadEvent& event); + // ValueNodeContainer::Listener + virtual void ValueNodeChanged(ValueNodeChild* nodeChild, + ValueNode* oldNode, ValueNode* newNode); + virtual void ValueNodeChildrenCreated(ValueNode* node); + virtual void ValueNodeChildrenDeleted(ValueNode* node); + virtual void ValueNodeValueChanged(ValueNode* node); + private: void _QueueEvent(Event* event); diff --git a/src/apps/debugger/user_interface/cli/CliPrintVariableCommand.cpp b/src/apps/debugger/user_interface/cli/CliPrintVariableCommand.cpp index 2bb2eb1328a..2c984fe7e73 100644 --- a/src/apps/debugger/user_interface/cli/CliPrintVariableCommand.cpp +++ b/src/apps/debugger/user_interface/cli/CliPrintVariableCommand.cpp @@ -116,16 +116,14 @@ CliPrintVariableCommand::_ResolveValueIfNeeded(ValueNode* node, context.GetUserInterfaceListener()->ValueNodeValueRequested( context.CurrentThread()->GetCpuState(), container, node); - // TODO: implement proper waiting - while (!context.IsTerminating()) { - context.ProcessPendingEvents(); - if (node->LocationAndValueResolutionState() - != VALUE_NODE_UNRESOLVED) { - break; - } + + while (node->LocationAndValueResolutionState() + == VALUE_NODE_UNRESOLVED) { containerLocker.Unlock(); - snooze(20000); + context.WaitForEvents(CliContext::EVENT_VALUE_NODE_CHANGED); containerLocker.Lock(); + if (context.IsTerminating()) + return B_ERROR; } } diff --git a/src/apps/debugger/user_interface/cli/CliStackTraceCommand.cpp b/src/apps/debugger/user_interface/cli/CliStackTraceCommand.cpp index 9e7f0330a68..37885e26407 100644 --- a/src/apps/debugger/user_interface/cli/CliStackTraceCommand.cpp +++ b/src/apps/debugger/user_interface/cli/CliStackTraceCommand.cpp @@ -45,11 +45,11 @@ CliStackTraceCommand::Execute(int argc, const char* const* argv, // get its stack trace StackTrace* stackTrace = thread->GetStackTrace(); - if (stackTrace == NULL) { - // TODO: Wait for stack trace! - printf("Current thread doesn't have a stack trace. Waiting not " - "implemented yet\n"); - return; + while (stackTrace == NULL) { + context.WaitForEvents(CliContext::EVENT_THREAD_STACK_TRACE_CHANGED); + if (context.IsTerminating()) + return; + stackTrace = thread->GetStackTrace(); } BReference stackTraceReference(stackTrace); // hold a reference until we're done