On 12/14/10, Ingo Weinhold <ingo_weinhold@xxxxxx> wrote: > No, I was thinking of having that in DebuggerInterface. Either there would > be > a separate thread or GetNextDebugEvent() would do that from time to time. > The > interface wouldn't change, save for the additional event(s) you already > added. In that case it seems to make more sense to implement the polling portion of it in TeamDebugger ; DebuggerInterface currently doesn't keep any information about the active thread list so it'd have to maintain a duplicate copy of the thread information TeamDebugger's already keeping in its fTeam member in order to be able to do the comparisons needed to see if anything's changed, which seems unnecessary. A thread off TeamDebugger would easily be able to access that information safely and just poll using DebuggerInterface's GetThreadInfos() call. Proof of concept patch attached for review. Regards, Rene
Index: src/apps/debugger/TeamDebugger.h =================================================================== --- src/apps/debugger/TeamDebugger.h (revision 39852) +++ src/apps/debugger/TeamDebugger.h (working copy) @@ -125,6 +125,8 @@ void _NotifyUser(const char* title, const char* text,...); + static status_t _ThreadStateWatcher(void* teamDebugger); + private: Listener* fListener; SettingsManager* fSettingsManager; @@ -142,6 +144,7 @@ UserInterface* fUserInterface; volatile bool fTerminating; bool fKillTeamOnQuit; + thread_id fThreadStateWatcher; }; Index: src/apps/debugger/TeamDebugger.cpp =================================================================== --- src/apps/debugger/TeamDebugger.cpp (revision 39852) +++ src/apps/debugger/TeamDebugger.cpp (working copy) @@ -142,7 +142,8 @@ fDebugEventListener(-1), fUserInterface(userInterface), fTerminating(false), - fKillTeamOnQuit(false) + fKillTeamOnQuit(false), + fThreadStateWatcher(-1) { fUserInterface->AcquireReference(); } @@ -168,6 +169,9 @@ if (fDebugEventListener >= 0) wait_for_thread(fDebugEventListener, NULL); + if (fThreadStateWatcher >= 0) + wait_for_thread(fThreadStateWatcher, NULL); + // terminate UI fUserInterface->Terminate(); fUserInterface->ReleaseReference(); @@ -325,6 +329,13 @@ } } + fThreadStateWatcher = spawn_thread(_ThreadStateWatcher, "ThreadStateWatcher", + B_NORMAL_PRIORITY, this); + if (fThreadStateWatcher < 0) + return fThreadStateWatcher; + + resume_thread(fThreadStateWatcher); + Image* appImage = NULL; { BObjectList<ImageInfo> imageInfos(20, true); @@ -1315,6 +1326,44 @@ } +status_t +TeamDebugger::_ThreadStateWatcher(void* teamDebugger) +{ + TeamDebugger* debugger = (TeamDebugger*)teamDebugger; + + bigtime_t fLastCheckTime = system_time(); + while (!debugger->fTerminating) { + if (system_time() - fLastCheckTime < 500000L) { + // stagger the sleep interval so we can quickly respond + // to shutdown requests + snooze(20000); + continue; + } + + fLastCheckTime = system_time(); + { + BObjectList<ThreadInfo> threadInfos(20, true); + status_t error = debugger->fDebuggerInterface + ->GetThreadInfos(threadInfos); + if (error == B_OK) { + AutoLocker< ::Team> locker(debugger->fTeam); + for (int32 i = 0; i < threadInfos.CountItems(); i++) { + ThreadInfo* info = threadInfos.ItemAt(i); + ::Thread* thread = debugger->fTeam->ThreadByID( + info->ThreadID()); + if (thread != NULL && strcmp(thread->Name(), + info->Name()) != 0) { + thread->SetName(info->Name()); + } + } + + } + } + } + + return B_OK; +} + // #pragma mark - Listener