diff --git a/src/apps/debugger/user_interface/cli/CliContext.cpp b/src/apps/debugger/user_interface/cli/CliContext.cpp index bc2cd1fd5b..86682fbb8d 100644 --- a/src/apps/debugger/user_interface/cli/CliContext.cpp +++ b/src/apps/debugger/user_interface/cli/CliContext.cpp @@ -29,7 +29,7 @@ static CliContext* sCurrentContext; struct CliContext::Event : DoublyLinkedListLinkImpl { - Event(int type, Thread* thread = NULL, TeamMemoryBlock* block = NULL, + Event(int type, ::Thread* thread = NULL, TeamMemoryBlock* block = NULL, ExpressionInfo* info = NULL, status_t expressionResult = B_OK, ExpressionResult* expressionValue = NULL) : @@ -47,7 +47,7 @@ struct CliContext::Event : DoublyLinkedListLinkImpl { return fType; } - Thread* GetThread() const + ::Thread* GetThread() const { return fThreadReference.Get(); } @@ -75,7 +75,7 @@ struct CliContext::Event : DoublyLinkedListLinkImpl { private: int fType; - BReference fThreadReference; + BReference< ::Thread> fThreadReference; BReference fMemoryBlockReference; BReference fExpressionInfo; status_t fExpressionResult; @@ -88,6 +88,7 @@ private: CliContext::CliContext() : + BLooper("CliContext"), fLock("CliContext"), fTeam(NULL), fListener(NULL), @@ -95,10 +96,8 @@ CliContext::CliContext() fEditLine(NULL), fHistory(NULL), fPrompt(NULL), - fBlockingSemaphore(-1), - fInputLoopWaitingForEvents(0), - fEventsOccurred(0), - fInputLoopWaiting(false), + fWaitForEventSemaphore(-1), + fEventOccurred(0), fTerminating(false), fStoppedThread(NULL), fCurrentThread(NULL), @@ -118,14 +117,16 @@ CliContext::~CliContext() Cleanup(); sCurrentContext = NULL; - if (fBlockingSemaphore >= 0) - delete_sem(fBlockingSemaphore); + if (fWaitForEventSemaphore >= 0) + delete_sem(fWaitForEventSemaphore); } status_t -CliContext::Init(Team* team, UserInterfaceListener* listener) +CliContext::Init(::Team* team, UserInterfaceListener* listener) { + AutoLocker locker(fLock); + fTeam = team; fListener = listener; @@ -135,9 +136,9 @@ CliContext::Init(Team* team, UserInterfaceListener* listener) if (error != B_OK) return error; - fBlockingSemaphore = create_sem(0, "CliContext block"); - if (fBlockingSemaphore < 0) - return fBlockingSemaphore; + fWaitForEventSemaphore = create_sem(0, "CliContext wait for event"); + if (fWaitForEventSemaphore < 0) + return fWaitForEventSemaphore; fEditLine = el_init("Debugger", stdin, stdout, stderr); if (fEditLine == NULL) @@ -171,11 +172,9 @@ CliContext::Init(Team* team, UserInterfaceListener* listener) void CliContext::Cleanup() { + AutoLocker locker(fLock); Terminating(); - while (Event* event = fPendingEvents.RemoveHead()) - delete event; - if (fEditLine != NULL) { el_end(fEditLine); fEditLine = NULL; @@ -208,13 +207,16 @@ CliContext::Cleanup() } +// TODO: Use the lifecycle methods of BLooper instead void CliContext::Terminating() { AutoLocker locker(fLock); fTerminating = true; - _SignalInputLoop(EVENT_QUIT); + + BMessage message(MSG_QUIT); + PostMessage(&message); // TODO: Signal the input loop, should it be in PromptUser()! } @@ -223,12 +225,13 @@ CliContext::Terminating() thread_id CliContext::CurrentThreadID() const { + AutoLocker locker(fLock); return fCurrentThread != NULL ? fCurrentThread->ID() : -1; } void -CliContext::SetCurrentThread(Thread* thread) +CliContext::SetCurrentThread(::Thread* thread) { AutoLocker locker(fLock); @@ -262,7 +265,8 @@ CliContext::SetCurrentThread(Thread* thread) void CliContext::PrintCurrentThread() { - AutoLocker teamLocker(fTeam); + AutoLocker< ::Team> teamLocker(fTeam); + AutoLocker locker(fLock); if (fCurrentThread != NULL) { printf("current thread: %" B_PRId32 " \"%s\"\n", fCurrentThread->ID(), @@ -294,11 +298,12 @@ status_t CliContext::EvaluateExpression(const char* expression, SourceLanguage* language, target_addr_t& address) { + AutoLocker locker(fLock); fExpressionInfo->SetTo(expression); fListener->ExpressionEvaluationRequested( language, fExpressionInfo); - WaitForEvents(CliContext::EVENT_EXPRESSION_EVALUATED); + _WaitForEvent(MSG_EXPRESSION_EVALUATED); if (fTerminating) return B_INTERRUPTED; @@ -329,9 +334,10 @@ CliContext::EvaluateExpression(const char* expression, status_t CliContext::GetMemoryBlock(target_addr_t address, TeamMemoryBlock*& block) { + AutoLocker locker(fLock); if (fCurrentBlock == NULL || !fCurrentBlock->Contains(address)) { GetUserInterfaceListener()->InspectRequested(address, this); - WaitForEvents(CliContext::EVENT_TEAM_MEMORY_BLOCK_RETRIEVED); + _WaitForEvent(MSG_TEAM_MEMORY_BLOCK_RETRIEVED); if (fTerminating) return B_INTERRUPTED; } @@ -351,8 +357,6 @@ CliContext::PromptUser(const char* prompt) fPrompt = NULL; - ProcessPendingEvents(); - return line; } @@ -368,14 +372,12 @@ CliContext::AddLineToInputHistory(const char* line) void CliContext::QuitSession(bool killTeam) { - _PrepareToWaitForEvents(EVENT_QUIT); - fListener->UserInterfaceQuitRequested( killTeam ? UserInterfaceListener::QUIT_OPTION_ASK_KILL_TEAM : UserInterfaceListener::QUIT_OPTION_ASK_RESUME_TEAM); - _WaitForEvents(); + WaitForEvent(MSG_QUIT); } @@ -384,19 +386,10 @@ CliContext::WaitForThreadOrUser() { // TODO: Deal with SIGINT as well! - // if no thread has been stopped, wait till one is - while (fStoppedThread == NULL) { - _PrepareToWaitForEvents( - EVENT_USER_INTERRUPT | EVENT_THREAD_STATE_CHANGED); - uint32 events = _WaitForEvents(); + AutoLocker locker(fLock); - ProcessPendingEvents(); - // updates fStoppedThread if any thread has been stopped - - if ((events & EVENT_QUIT) != 0) { - return; - } - } + while (fStoppedThread == NULL) + _WaitForEvent(MSG_THREAD_STATE_CHANGED); if (fCurrentThread == NULL) SetCurrentThread(fStoppedThread); @@ -404,116 +397,138 @@ 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; - } - } +CliContext::WaitForEvent(uint32 event) { + AutoLocker locker(fLock); + _WaitForEvent(event); } void -CliContext::ProcessPendingEvents() +CliContext::MessageReceived(BMessage* message) { - AutoLocker teamLocker(fTeam); + fLock.Lock(); - for (;;) { - // get the next event - AutoLocker locker(fLock); - Event* event = fPendingEvents.RemoveHead(); - locker.Unlock(); - if (event == NULL) + int32 threadID; + message->FindInt32("thread", &threadID); + + const char* threadName; + message->FindString("threadName", &threadName); + + switch (message->what) { + case MSG_THREAD_ADDED: + printf("[new thread: %" B_PRId32 " \"%s\"]\n", threadID, + threadName); break; - ObjectDeleter eventDeleter(event); + case MSG_THREAD_REMOVED: + printf("[thread terminated: %" B_PRId32 " \"%s\"]\n", + threadID, threadName); + break; + case MSG_THREAD_STATE_CHANGED: + { + AutoLocker< ::Team> locker(fTeam); + ::Thread* thread = fTeam->ThreadByID(threadID); - // process the event - Thread* thread = event->GetThread(); - - switch (event->Type()) { - case EVENT_QUIT: - case EVENT_DEBUG_REPORT_CHANGED: - case EVENT_USER_INTERRUPT: - break; - case EVENT_THREAD_ADDED: - printf("[new thread: %" B_PRId32 " \"%s\"]\n", thread->ID(), - thread->Name()); - break; - case EVENT_THREAD_REMOVED: - printf("[thread terminated: %" B_PRId32 " \"%s\"]\n", - thread->ID(), thread->Name()); - break; - 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) { - fCurrentStackTrace = thread->GetStackTrace(); - fCurrentStackTrace->AcquireReference(); - SetCurrentStackFrameIndex(0); - } - break; - case EVENT_TEAM_MEMORY_BLOCK_RETRIEVED: - if (fCurrentBlock != NULL) { - fCurrentBlock->ReleaseReference(); - fCurrentBlock = NULL; - } - fCurrentBlock = event->GetMemoryBlock(); - break; - case EVENT_EXPRESSION_EVALUATED: - fExpressionResult = event->GetExpressionResult(); - if (fExpressionValue != NULL) { - fExpressionValue->ReleaseReference(); - fExpressionValue = NULL; - } - fExpressionValue = event->GetExpressionValue(); - if (fExpressionValue != NULL) - fExpressionValue->AcquireReference(); - break; + if (thread->State() == THREAD_STATE_STOPPED) { + printf("[thread stopped: %" B_PRId32 " \"%s\"]\n", + threadID, threadName); + fStoppedThread.SetTo(thread); + } else { + fStoppedThread = NULL; + } + break; } + case MSG_THREAD_STACK_TRACE_CHANGED: + if (threadID == fCurrentThread->ID()) { + AutoLocker< ::Team> locker(fTeam); + ::Thread* thread = fTeam->ThreadByID(threadID); + + fCurrentStackTrace = thread->GetStackTrace(); + fCurrentStackTrace->AcquireReference(); + SetCurrentStackFrameIndex(0); + } + break; + case MSG_TEAM_MEMORY_BLOCK_RETRIEVED: + { + TeamMemoryBlock* block = NULL; + if (message->FindPointer("block", + reinterpret_cast(&block)) != B_OK) { + break; + } + + if (fCurrentBlock != NULL) { + fCurrentBlock->ReleaseReference(); + } + + // reference acquired in MemoryBlockRetrieved + fCurrentBlock = block; + break; + } + case MSG_EXPRESSION_EVALUATED: + { + status_t result; + if (message->FindInt32("result", &result) != B_OK) { + break; + } + + fExpressionResult = result; + + ExpressionResult* value = NULL; + message->FindPointer("value", reinterpret_cast(&value)); + + if (fExpressionValue != NULL) { + fExpressionValue->ReleaseReference(); + } + + // reference acquired in ExpressionEvaluated + fExpressionValue = value; + break; + } + default: + BLooper::MessageReceived(message); + break; } + + fEventOccurred = message->what; + + fLock.Unlock(); + + release_sem(fWaitForEventSemaphore); + // all of the code that was waiting on the semaphore runs + acquire_sem(fWaitForEventSemaphore); + + fLock.Lock(); + fEventOccurred = 0; + fLock.Unlock(); } void CliContext::ThreadAdded(const Team::ThreadEvent& threadEvent) { - _QueueEvent( - new(std::nothrow) Event(EVENT_THREAD_ADDED, threadEvent.GetThread())); - _SignalInputLoop(EVENT_THREAD_ADDED); + BMessage message(MSG_THREAD_ADDED); + message.AddInt32("thread", threadEvent.GetThread()->ID()); + message.AddString("threadName", threadEvent.GetThread()->Name()); + PostMessage(&message); } void CliContext::ThreadRemoved(const Team::ThreadEvent& threadEvent) { - _QueueEvent( - new(std::nothrow) Event(EVENT_THREAD_REMOVED, threadEvent.GetThread())); - _SignalInputLoop(EVENT_THREAD_REMOVED); + BMessage message(MSG_THREAD_REMOVED); + message.AddInt32("thread", threadEvent.GetThread()->ID()); + message.AddString("threadName", threadEvent.GetThread()->Name()); + PostMessage(&message); } void CliContext::ThreadStateChanged(const Team::ThreadEvent& threadEvent) { - _QueueEvent( - new(std::nothrow) Event(EVENT_THREAD_STATE_CHANGED, threadEvent.GetThread())); - _SignalInputLoop(EVENT_THREAD_STATE_CHANGED); + BMessage message(MSG_THREAD_STATE_CHANGED); + message.AddInt32("thread", threadEvent.GetThread()->ID()); + message.AddString("threadName", threadEvent.GetThread()->Name()); + PostMessage(&message); } @@ -523,10 +538,10 @@ CliContext::ThreadStackTraceChanged(const Team::ThreadEvent& threadEvent) if (threadEvent.GetThread()->State() != THREAD_STATE_STOPPED) return; - _QueueEvent( - new(std::nothrow) Event(EVENT_THREAD_STACK_TRACE_CHANGED, - threadEvent.GetThread())); - _SignalInputLoop(EVENT_THREAD_STACK_TRACE_CHANGED); + BMessage message(MSG_THREAD_STACK_TRACE_CHANGED); + message.AddInt32("thread", threadEvent.GetThread()->ID()); + message.AddString("threadName", threadEvent.GetThread()->Name()); + PostMessage(&message); } @@ -534,10 +549,15 @@ void CliContext::ExpressionEvaluated(ExpressionInfo* info, status_t result, ExpressionResult* value) { - _QueueEvent( - new(std::nothrow) Event(EVENT_EXPRESSION_EVALUATED, - NULL, NULL, info, result, value)); - _SignalInputLoop(EVENT_EXPRESSION_EVALUATED); + BMessage message(MSG_EXPRESSION_EVALUATED); + message.AddInt32("result", result); + + if (value != NULL) { + value->AcquireReference(); + message.AddPointer("value", value); + } + + PostMessage(&message); } @@ -551,9 +571,6 @@ CliContext::DebugReportChanged(const Team::DebugReportEvent& event) fprintf(stderr, "Failed to write debug report: %s\n", strerror( event.GetFinalStatus())); } - - _QueueEvent(new(std::nothrow) Event(EVENT_DEBUG_REPORT_CHANGED)); - _SignalInputLoop(EVENT_DEBUG_REPORT_CHANGED); } @@ -562,19 +579,18 @@ CliContext::CoreFileChanged(const Team::CoreFileChangedEvent& event) { printf("Successfully saved core file to %s\n", event.GetTargetPath()); - - _QueueEvent(new(std::nothrow) Event(EVENT_CORE_FILE_CHANGED)); - _SignalInputLoop(EVENT_CORE_FILE_CHANGED); } void CliContext::MemoryBlockRetrieved(TeamMemoryBlock* block) { - _QueueEvent( - new(std::nothrow) Event(EVENT_TEAM_MEMORY_BLOCK_RETRIEVED, - NULL, block)); - _SignalInputLoop(EVENT_TEAM_MEMORY_BLOCK_RETRIEVED); + if (block != NULL) + block->AcquireReference(); + + BMessage message(MSG_TEAM_MEMORY_BLOCK_RETRIEVED); + message.AddPointer("block", block); + PostMessage(&message); } @@ -582,92 +598,32 @@ void CliContext::ValueNodeChanged(ValueNodeChild* nodeChild, ValueNode* oldNode, ValueNode* newNode) { - _SignalInputLoop(EVENT_VALUE_NODE_CHANGED); + BMessage message(MSG_VALUE_NODE_CHANGED); + PostMessage(&message); } void CliContext::ValueNodeChildrenCreated(ValueNode* node) { - _SignalInputLoop(EVENT_VALUE_NODE_CHANGED); + BMessage message(MSG_VALUE_NODE_CHANGED); + PostMessage(&message); } void CliContext::ValueNodeChildrenDeleted(ValueNode* node) { - _SignalInputLoop(EVENT_VALUE_NODE_CHANGED); + BMessage message(MSG_VALUE_NODE_CHANGED); + PostMessage(&message); } void CliContext::ValueNodeValueChanged(ValueNode* oldNode) { - _SignalInputLoop(EVENT_VALUE_NODE_CHANGED); -} - - -void -CliContext::_QueueEvent(Event* event) -{ - if (event == NULL) { - // no memory -- can't do anything about it - return; - } - - AutoLocker locker(fLock); - fPendingEvents.Add(event); -} - - -void -CliContext::_PrepareToWaitForEvents(uint32 eventMask) -{ - // Set the events we're going to wait for -- always wait for "quit". - AutoLocker locker(fLock); - fInputLoopWaitingForEvents = eventMask | EVENT_QUIT; - fEventsOccurred = fTerminating ? EVENT_QUIT : 0; -} - - -uint32 -CliContext::_WaitForEvents() -{ - AutoLocker locker(fLock); - - if (fEventsOccurred == 0) { - sem_id blockingSemaphore = fBlockingSemaphore; - fInputLoopWaiting = true; - - locker.Unlock(); - - while (acquire_sem(blockingSemaphore) == B_INTERRUPTED) { - } - - locker.Lock(); - } - - uint32 events = fEventsOccurred; - fEventsOccurred = 0; - return events; -} - - -void -CliContext::_SignalInputLoop(uint32 events) -{ - AutoLocker locker(fLock); - - if ((fInputLoopWaitingForEvents & events) == 0) - return; - - fEventsOccurred = fInputLoopWaitingForEvents & events; - fInputLoopWaitingForEvents = 0; - - if (fInputLoopWaiting) { - fInputLoopWaiting = false; - release_sem(fBlockingSemaphore); - } + BMessage message(MSG_VALUE_NODE_CHANGED); + PostMessage(&message); } @@ -676,3 +632,19 @@ CliContext::_GetPrompt(EditLine* editLine) { return sCurrentContext != NULL ? sCurrentContext->fPrompt : NULL; } + + +void +CliContext::_WaitForEvent(uint32 event) { + if (fTerminating) + return; + + do { + fLock.Unlock(); + while (acquire_sem(fWaitForEventSemaphore) == B_INTERRUPTED) { + } + fLock.Lock(); + release_sem(fWaitForEventSemaphore); + } while (fEventOccurred != event && !fTerminating); +} + diff --git a/src/apps/debugger/user_interface/cli/CliContext.h b/src/apps/debugger/user_interface/cli/CliContext.h index 775522342a..0b6c698a15 100644 --- a/src/apps/debugger/user_interface/cli/CliContext.h +++ b/src/apps/debugger/user_interface/cli/CliContext.h @@ -12,6 +12,7 @@ #include #include +#include #include "ExpressionInfo.h" #include "Team.h" @@ -31,27 +32,28 @@ class ValueNodeManager; class CliContext : private Team::Listener, public TeamMemoryBlock::Listener, public ExpressionInfo::Listener, - private ValueNodeContainer::Listener { + private ValueNodeContainer::Listener, + public BLooper { public: enum { - EVENT_QUIT = 0x01, - EVENT_USER_INTERRUPT = 0x02, - EVENT_THREAD_ADDED = 0x04, - EVENT_THREAD_REMOVED = 0x08, - EVENT_THREAD_STATE_CHANGED = 0x10, - EVENT_THREAD_STACK_TRACE_CHANGED = 0x20, - EVENT_VALUE_NODE_CHANGED = 0x40, - EVENT_TEAM_MEMORY_BLOCK_RETRIEVED = 0x80, - EVENT_EXPRESSION_EVALUATED = 0x100, - EVENT_DEBUG_REPORT_CHANGED = 0x200, - EVENT_CORE_FILE_CHANGED = 0x400 + MSG_QUIT = 'quit', + MSG_USER_INTERRUPT = 'uint', + MSG_THREAD_ADDED = 'thad', + MSG_THREAD_REMOVED = 'thar', + MSG_THREAD_STATE_CHANGED = 'tsch', + MSG_THREAD_STACK_TRACE_CHANGED = 'tstc', + MSG_VALUE_NODE_CHANGED = 'vnch', + MSG_TEAM_MEMORY_BLOCK_RETRIEVED = 'tmbr', + MSG_EXPRESSION_EVALUATED = 'exev', + MSG_DEBUG_REPORT_CHANGED = 'drch', + MSG_CORE_FILE_CHANGED = 'cfch' }; public: CliContext(); ~CliContext(); - status_t Init(Team* team, + status_t Init(::Team* team, UserInterfaceListener* listener); void Cleanup(); @@ -59,9 +61,11 @@ public: bool IsTerminating() const { return fTerminating; } + virtual void MessageReceived(BMessage* message); + // service methods for the input loop thread follow - Team* GetTeam() const { return fTeam; } + ::Team* GetTeam() const { return fTeam; } UserInterfaceListener* GetUserInterfaceListener() const { return fListener; } ValueNodeManager* GetValueNodeManager() const @@ -69,9 +73,9 @@ public: StackTrace* GetStackTrace() const { return fCurrentStackTrace; } - Thread* CurrentThread() const { return fCurrentThread; } + ::Thread* CurrentThread() const { return fCurrentThread; } thread_id CurrentThreadID() const; - void SetCurrentThread(Thread* thread); + void SetCurrentThread(::Thread* thread); void PrintCurrentThread(); int32 CurrentStackFrameIndex() const @@ -90,8 +94,7 @@ public: void QuitSession(bool killTeam); void WaitForThreadOrUser(); - void WaitForEvents(int32 eventMask); - void ProcessPendingEvents(); + void WaitForEvent(uint32 event); private: struct Event; @@ -129,30 +132,23 @@ private: virtual void ValueNodeValueChanged(ValueNode* node); private: - void _QueueEvent(Event* event); - - void _PrepareToWaitForEvents(uint32 eventMask); - uint32 _WaitForEvents(); - void _SignalInputLoop(uint32 events); - static const char* _GetPrompt(EditLine* editLine); + void _WaitForEvent(uint32 event); private: - BLocker fLock; - Team* fTeam; + mutable BLocker fLock; + ::Team* fTeam; UserInterfaceListener* fListener; ValueNodeManager* fNodeManager; EditLine* fEditLine; History* fHistory; const char* fPrompt; - sem_id fBlockingSemaphore; - uint32 fInputLoopWaitingForEvents; - uint32 fEventsOccurred; - bool fInputLoopWaiting; + sem_id fWaitForEventSemaphore; + uint32 fEventOccurred; volatile bool fTerminating; - BReference fStoppedThread; - Thread* fCurrentThread; + BReference< ::Thread> fStoppedThread; + ::Thread* fCurrentThread; StackTrace* fCurrentStackTrace; int32 fCurrentStackFrameIndex; TeamMemoryBlock* fCurrentBlock; @@ -160,8 +156,6 @@ private: ExpressionInfo* fExpressionInfo; status_t fExpressionResult; ExpressionResult* fExpressionValue; - - EventList fPendingEvents; }; diff --git a/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp b/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp index 7a35671191..ed5dacb51a 100644 --- a/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp +++ b/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp @@ -97,6 +97,7 @@ private: CommandLineUserInterface::CommandLineUserInterface() : + fContext(new CliContext()), fCommands(20, true), fShowSemaphore(-1), fShown(false), @@ -122,7 +123,7 @@ CommandLineUserInterface::ID() const status_t CommandLineUserInterface::Init(Team* team, UserInterfaceListener* listener) { - status_t error = fContext.Init(team, listener); + status_t error = fContext->Init(team, listener); if (error != B_OK) return error; @@ -152,7 +153,7 @@ CommandLineUserInterface::Terminate() fTerminating = true; if (fShown) { - fContext.Terminating(); + fContext->Terminating(); // Wait for input loop to finish. while (acquire_sem(fShowSemaphore) == B_INTERRUPTED) { @@ -163,7 +164,10 @@ CommandLineUserInterface::Terminate() fShowSemaphore = -1; } - fContext.Cleanup(); + fContext->Cleanup(); + + BMessage message(B_QUIT_REQUESTED); + fContext->PostMessage(&message); } @@ -236,6 +240,7 @@ CommandLineUserInterface::Run() if (error != B_OK) return; + fContext->Run(); _InputLoop(); // Release the Show() semaphore to signal Terminate(). release_sem(fShowSemaphore); @@ -248,21 +253,19 @@ CommandLineUserInterface::_InputLoop() thread_id currentThread = -1; while (!fTerminating) { - fContext.ProcessPendingEvents(); - // Wait for a thread or Ctrl-C. - fContext.WaitForThreadOrUser(); - if (fContext.IsTerminating()) + fContext->WaitForThreadOrUser(); + if (fContext->IsTerminating()) break; // Print the active thread, if it changed. - if (fContext.CurrentThreadID() != currentThread) { - fContext.PrintCurrentThread(); - currentThread = fContext.CurrentThreadID(); + if (fContext->CurrentThreadID() != currentThread) { + fContext->PrintCurrentThread(); + currentThread = fContext->CurrentThreadID(); } // read a command line - const char* line = fContext.PromptUser(kDebuggerPrompt); + const char* line = fContext->PromptUser(kDebuggerPrompt); if (line == NULL) break; @@ -288,7 +291,7 @@ CommandLineUserInterface::_InputLoop() continue; // add line to history - fContext.AddLineToInputHistory(line); + fContext->AddLineToInputHistory(line); // execute command _ExecuteCommand(args.ArgumentCount(), args.Arguments()); @@ -369,7 +372,7 @@ CommandLineUserInterface::_ExecuteCommand(int argc, const char* const* argv) { CommandEntry* commandEntry = _FindCommand(argv[0]); if (commandEntry != NULL) - commandEntry->Command()->Execute(argc, argv, fContext); + commandEntry->Command()->Execute(argc, argv, *fContext); } diff --git a/src/apps/debugger/user_interface/cli/CommandLineUserInterface.h b/src/apps/debugger/user_interface/cli/CommandLineUserInterface.h index 7fbfd214ae..0605c146eb 100644 --- a/src/apps/debugger/user_interface/cli/CommandLineUserInterface.h +++ b/src/apps/debugger/user_interface/cli/CommandLineUserInterface.h @@ -77,7 +77,7 @@ private: const CommandEntry* command2); private: - CliContext fContext; + CliContext* fContext; CommandList fCommands; sem_id fShowSemaphore; bool fShown; diff --git a/src/apps/debugger/user_interface/cli/commands/CliPrintVariableCommand.cpp b/src/apps/debugger/user_interface/cli/commands/CliPrintVariableCommand.cpp index 5613457112..0f35220ad8 100644 --- a/src/apps/debugger/user_interface/cli/commands/CliPrintVariableCommand.cpp +++ b/src/apps/debugger/user_interface/cli/commands/CliPrintVariableCommand.cpp @@ -119,7 +119,7 @@ CliPrintVariableCommand::_ResolveValueIfNeeded(ValueNode* node, while (node->LocationAndValueResolutionState() == VALUE_NODE_UNRESOLVED) { containerLocker.Unlock(); - context.WaitForEvents(CliContext::EVENT_VALUE_NODE_CHANGED); + context.WaitForEvent(CliContext::MSG_VALUE_NODE_CHANGED); containerLocker.Lock(); if (context.IsTerminating()) return B_ERROR; diff --git a/src/apps/debugger/user_interface/cli/commands/CliStackTraceCommand.cpp b/src/apps/debugger/user_interface/cli/commands/CliStackTraceCommand.cpp index 37885e2640..ea93d349fb 100644 --- a/src/apps/debugger/user_interface/cli/commands/CliStackTraceCommand.cpp +++ b/src/apps/debugger/user_interface/cli/commands/CliStackTraceCommand.cpp @@ -46,7 +46,7 @@ CliStackTraceCommand::Execute(int argc, const char* const* argv, // get its stack trace StackTrace* stackTrace = thread->GetStackTrace(); while (stackTrace == NULL) { - context.WaitForEvents(CliContext::EVENT_THREAD_STACK_TRACE_CHANGED); + context.WaitForEvent(CliContext::MSG_THREAD_STACK_TRACE_CHANGED); if (context.IsTerminating()) return; stackTrace = thread->GetStackTrace();