More adjustments to CliContext.
- CliContext now listens for value node container events so that commands can request such a wait as well - Implement an event wait mechanism for commands to make use of. Adjust CliStackTrace and CliPrintVariable accordingly.
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <Locker.h>
|
||||
|
||||
#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 @@ public:
|
||||
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 @@ public:
|
||||
void QuitSession(bool killTeam);
|
||||
|
||||
void WaitForThreadOrUser();
|
||||
void WaitForEvents(int32 eventMask);
|
||||
void ProcessPendingEvents();
|
||||
|
||||
private:
|
||||
@@ -87,6 +91,13 @@ private:
|
||||
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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<StackTrace> stackTraceReference(stackTrace);
|
||||
// hold a reference until we're done
|
||||
|
||||
Reference in New Issue
Block a user