From 45e0c33d4fdc8926a82c5800b7f7953f61f46afa Mon Sep 17 00:00:00 2001 From: Zardshard <0azrune6@zard.anonaddy.com> Date: Mon, 1 May 2023 10:28:52 -0400 Subject: [PATCH] Debugger: Make CliContext use BLooper for message passing This commit replaces the custom implementation of message passing with BLooper. This commit does not fully transition the code to the BLooper paradigm. WaitForEvent still exists, when, ideally, message passing should be used to notify the waiting class that the results are ready. Change-Id: Id223b9fc0ac1aa9a5a5aeb4af63da04f2cc7574b Reviewed-on: https://review.haiku-os.org/c/haiku/+/6400 Reviewed-by: John Scipione Reviewed-by: Rene Gollent --- .../user_interface/cli/CliContext.cpp | 384 ++++++++---------- .../debugger/user_interface/cli/CliContext.h | 62 ++- .../cli/CommandLineUserInterface.cpp | 29 +- .../cli/CommandLineUserInterface.h | 2 +- .../cli/commands/CliPrintVariableCommand.cpp | 2 +- .../cli/commands/CliStackTraceCommand.cpp | 2 +- 6 files changed, 225 insertions(+), 256 deletions(-) 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();