[haiku-commits] haiku: hrev44423 - in src/apps/debugger/user_interface/cli: . src/apps/debugger src/apps/debugger/user_interface

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 29 Jul 2012 00:29:23 +0200 (CEST)

hrev44423 adds 3 changesets to branch 'master'
old head: e51854a127450ed5f1dc33ec350a00f1deaff355
new head: d266c87d174fc714e2c0ecbfe9c18713f3c9215d

----------------------------------------------------------------------------

726d557: Debugger CLI: Wait for TeamDebugger thread to die before exit()

4d8eaa5: Debugger: UserInterface.h: style cleanup

d266c87: Debugger: CliContext: Introduce the notion of events
  
  * The input loop can now wait on abstract events, which other threads
    (or even the input loop thread itself) can signal.
  * Use the new mechanism in QuitSession().
  * Also (with the exception of the SIGINT part) implement
    WaitForThreadOrUser().

                                    [ Ingo Weinhold <ingo_weinhold@xxxxxx> ]

----------------------------------------------------------------------------

4 files changed, 136 insertions(+), 26 deletions(-)
src/apps/debugger/Debugger.cpp                     |   14 +-
src/apps/debugger/user_interface/UserInterface.h   |   10 +-
.../debugger/user_interface/cli/CliContext.cpp     |  116 +++++++++++++---
src/apps/debugger/user_interface/cli/CliContext.h  |   22 ++-

############################################################################

Commit:      726d557c9e2cedcf3145146e3e054c4931c5cb1e
URL:         http://cgit.haiku-os.org/haiku/commit/?id=726d557
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Sat Jul 28 22:18:12 2012 UTC

Debugger CLI: Wait for TeamDebugger thread to die before exit()

----------------------------------------------------------------------------

diff --git a/src/apps/debugger/Debugger.cpp b/src/apps/debugger/Debugger.cpp
index 888db4a..645151d 100644
--- a/src/apps/debugger/Debugger.cpp
+++ b/src/apps/debugger/Debugger.cpp
@@ -594,14 +594,20 @@ CliDebugger::Run(const Options& options)
        if (!get_debugged_program(options, programInfo))
                return false;
 
-       if (start_team_debugger(programInfo.team, &settingsManager, this,
-                       programInfo.thread, programInfo.stopInMain, 
userInterface)
-                       == NULL) {
+       TeamDebugger* teamDebugger = start_team_debugger(programInfo.team,
+               &settingsManager, this, programInfo.thread, 
programInfo.stopInMain,
+               userInterface);
+       if (teamDebugger == NULL)
                return false;
-       }
 
+       thread_id teamDebuggerThread = teamDebugger->Thread();
+
+       // run the input loop
        userInterface->Run();
 
+       // wait for the team debugger thread to terminate
+       wait_for_thread(teamDebuggerThread, NULL);
+
        return true;
 }
 

############################################################################

Commit:      4d8eaa5b11b21e3913b6937e298a7370c3e8c4f8
URL:         http://cgit.haiku-os.org/haiku/commit/?id=4d8eaa5
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Sat Jul 28 22:18:43 2012 UTC

Debugger: UserInterface.h: style cleanup

----------------------------------------------------------------------------

diff --git a/src/apps/debugger/user_interface/UserInterface.h 
b/src/apps/debugger/user_interface/UserInterface.h
index 2f69266..60ae097 100644
--- a/src/apps/debugger/user_interface/UserInterface.h
+++ b/src/apps/debugger/user_interface/UserInterface.h
@@ -68,11 +68,11 @@ public:
 
 class UserInterfaceListener {
 public:
-       enum QuitOption {
-               QUIT_OPTION_ASK_USER,
-               QUIT_OPTION_ASK_KILL_TEAM,
-               QUIT_OPTION_ASK_RESUME_TEAM
-       };
+                       enum QuitOption {
+                               QUIT_OPTION_ASK_USER,
+                               QUIT_OPTION_ASK_KILL_TEAM,
+                               QUIT_OPTION_ASK_RESUME_TEAM
+                       };
 
 public:
        virtual                                         
~UserInterfaceListener();

############################################################################

Revision:    hrev44423
Commit:      d266c87d174fc714e2c0ecbfe9c18713f3c9215d
URL:         http://cgit.haiku-os.org/haiku/commit/?id=d266c87
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Sat Jul 28 22:28:11 2012 UTC

Debugger: CliContext: Introduce the notion of events

* The input loop can now wait on abstract events, which other threads
  (or even the input loop thread itself) can signal.
* Use the new mechanism in QuitSession().
* Also (with the exception of the SIGINT part) implement
  WaitForThreadOrUser().

----------------------------------------------------------------------------

diff --git a/src/apps/debugger/user_interface/cli/CliContext.cpp 
b/src/apps/debugger/user_interface/cli/CliContext.cpp
index ad14f82..68b8e77 100644
--- a/src/apps/debugger/user_interface/cli/CliContext.cpp
+++ b/src/apps/debugger/user_interface/cli/CliContext.cpp
@@ -28,16 +28,22 @@ CliContext::CliContext()
        fHistory(NULL),
        fPrompt(NULL),
        fBlockingSemaphore(-1),
+       fInputLoopWaitingForEvents(0),
+       fEventsOccurred(0),
        fInputLoopWaiting(false),
        fTerminating(false)
 {
        sCurrentContext = this;
 }
 
+
 CliContext::~CliContext()
 {
        Cleanup();
        sCurrentContext = NULL;
+
+       if (fBlockingSemaphore >= 0)
+               delete_sem(fBlockingSemaphore);
 }
 
 
@@ -47,6 +53,8 @@ CliContext::Init(Team* team, UserInterfaceListener* listener)
        fTeam = team;
        fListener = listener;
 
+       fTeam->AddListener(this);
+
        status_t error = fLock.InitCheck();
        if (error != B_OK)
                return error;
@@ -88,6 +96,11 @@ CliContext::Cleanup()
                history_end(fHistory);
                fHistory = NULL;
        }
+
+       if (fTeam != NULL) {
+               fTeam->RemoveListener(this);
+               fTeam = NULL;
+       }
 }
 
 
@@ -97,13 +110,7 @@ CliContext::Terminating()
        AutoLocker<BLocker> locker(fLock);
 
        fTerminating = true;
-
-       if (fBlockingSemaphore >= 0) {
-               delete_sem(fBlockingSemaphore);
-               fBlockingSemaphore = -1;
-       }
-
-       fInputLoopWaiting = false;
+       _SignalInputLoop(EVENT_QUIT);
 
        // TODO: Signal the input loop, should it be in PromptUser()!
 }
@@ -134,27 +141,104 @@ CliContext::AddLineToInputHistory(const char* line)
 void
 CliContext::QuitSession(bool killTeam)
 {
-       AutoLocker<BLocker> locker(fLock);
-
-       sem_id blockingSemaphore = fBlockingSemaphore;
-       fInputLoopWaiting = true;
-
-       locker.Unlock();
+       _PrepareToWaitForEvents(EVENT_QUIT);
 
        fListener->UserInterfaceQuitRequested(
                killTeam
                        ? UserInterfaceListener::QUIT_OPTION_ASK_KILL_TEAM
                        : UserInterfaceListener::QUIT_OPTION_ASK_RESUME_TEAM);
 
-       while (acquire_sem(blockingSemaphore) == B_INTERRUPTED) {
-       }
+       _WaitForEvents();
 }
 
 
 void
 CliContext::WaitForThreadOrUser()
 {
-       // TODO:...
+// TODO: Deal with SIGINT as well!
+       for (;;) {
+               _PrepareToWaitForEvents(
+                       EVENT_USER_INTERRUPT | EVENT_THREAD_STATE_CHANGED);
+
+               // check whether there are any threads stopped already
+               thread_id stoppedThread = -1;
+               AutoLocker<Team> teamLocker(fTeam);
+
+               for (ThreadList::ConstIterator it = 
fTeam->Threads().GetIterator();
+                               Thread* thread = it.Next();) {
+                       if (thread->State() == THREAD_STATE_STOPPED) {
+                               stoppedThread = thread->ID();
+                               break;
+                       }
+               }
+
+               teamLocker.Unlock();
+
+               if (stoppedThread >= 0)
+                       _SignalInputLoop(EVENT_THREAD_STATE_CHANGED);
+
+               uint32 events = _WaitForEvents();
+               if ((events & EVENT_QUIT) != 0 || stoppedThread >= 0)
+                       return;
+       }
+}
+
+
+void
+CliContext::ThreadStateChanged(const Team::ThreadEvent& event)
+{
+       _SignalInputLoop(EVENT_THREAD_STATE_CHANGED);
+}
+
+
+void
+CliContext::_PrepareToWaitForEvents(uint32 eventMask)
+{
+       // Set the events we're going to wait for -- always wait for "quit".
+       AutoLocker<BLocker> locker(fLock);
+       fInputLoopWaitingForEvents = eventMask | EVENT_QUIT;
+       fEventsOccurred = fTerminating ? EVENT_QUIT : 0;
+}
+
+
+uint32
+CliContext::_WaitForEvents()
+{
+       AutoLocker<BLocker> 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<BLocker> locker(fLock);
+
+       if ((fInputLoopWaitingForEvents & events) == 0)
+               return;
+
+       fEventsOccurred = fInputLoopWaitingForEvents & events;
+       fInputLoopWaitingForEvents = 0;
+
+       if (fInputLoopWaiting) {
+               fInputLoopWaiting = false;
+               release_sem(fBlockingSemaphore);
+       }
 }
 
 
diff --git a/src/apps/debugger/user_interface/cli/CliContext.h 
b/src/apps/debugger/user_interface/cli/CliContext.h
index e3617fe..0d5771e 100644
--- a/src/apps/debugger/user_interface/cli/CliContext.h
+++ b/src/apps/debugger/user_interface/cli/CliContext.h
@@ -12,12 +12,21 @@
 
 #include <Locker.h>
 
+#include "Team.h"
+
 
 class Team;
 class UserInterfaceListener;
 
 
-class CliContext {
+class CliContext : private Team::Listener {
+public:
+                       enum {
+                               EVENT_QUIT                                      
= 0x01,
+                               EVENT_USER_INTERRUPT            = 0x02,
+                               EVENT_THREAD_STATE_CHANGED      = 0x04,
+                       };
+
 public:
                                                                CliContext();
                                                                ~CliContext();
@@ -40,6 +49,15 @@ public:
                        void                            WaitForThreadOrUser();
 
 private:
+       // Team::Listener
+       virtual void                            ThreadStateChanged(
+                                                                       const 
Team::ThreadEvent& event);
+
+private:
+                       void                            
_PrepareToWaitForEvents(uint32 eventMask);
+                       uint32                          _WaitForEvents();
+                       void                            _SignalInputLoop(uint32 
events);
+
        static  const char*                     _GetPrompt(EditLine* editLine);
 
 private:
@@ -50,6 +68,8 @@ private:
                        History*                        fHistory;
                        const char*                     fPrompt;
                        sem_id                          fBlockingSemaphore;
+                       uint32                          
fInputLoopWaitingForEvents;
+                       uint32                          fEventsOccurred;
                        bool                            fInputLoopWaiting;
        volatile bool                           fTerminating;
 };


Other related posts:

  • » [haiku-commits] haiku: hrev44423 - in src/apps/debugger/user_interface/cli: . src/apps/debugger src/apps/debugger/user_interface - ingo_weinhold