Debugger: Improvements to hrev47421.

- Isolate the filesystem query/result list building into a separate
  worker thread in order to prevent blocking the window thread in
  case the query winds up being a bit more time consuming. This
  doesn't yet handle intelligent prefetching (and associated can of
  synchronization worms), but that will come once time permits.
- Also fixes a missing break statement introduced in the aforementioned
  commit, though that one shouldn't have caused any actual harm.
This commit is contained in:
Rene Gollent
2014-06-26 22:13:49 -04:00
parent b43baaba36
commit 3eadb2cc1d
2 changed files with 82 additions and 20 deletions
@@ -67,6 +67,7 @@ enum {
MSG_CHOOSE_DEBUG_REPORT_LOCATION = 'ccrl', MSG_CHOOSE_DEBUG_REPORT_LOCATION = 'ccrl',
MSG_DEBUG_REPORT_SAVED = 'drsa', MSG_DEBUG_REPORT_SAVED = 'drsa',
MSG_LOCATE_SOURCE_IF_NEEDED = 'lsin', MSG_LOCATE_SOURCE_IF_NEEDED = 'lsin',
MSG_SOURCE_ENTRY_QUERY_COMPLETE = 'seqc',
MSG_CLEAR_STACK_TRACE = 'clst' MSG_CLEAR_STACK_TRACE = 'clst'
}; };
@@ -134,7 +135,8 @@ TeamWindow::TeamWindow(::Team* team, UserInterfaceListener* listener)
fConsoleSplitView(NULL), fConsoleSplitView(NULL),
fBreakConditionConfigWindow(NULL), fBreakConditionConfigWindow(NULL),
fInspectorWindow(NULL), fInspectorWindow(NULL),
fFilePanel(NULL) fFilePanel(NULL),
fActiveSourceWorker(-1)
{ {
fTeam->Lock(); fTeam->Lock();
BString name = fTeam->Name(); BString name = fTeam->Name();
@@ -172,6 +174,9 @@ TeamWindow::~TeamWindow()
_SetActiveThread(NULL); _SetActiveThread(NULL);
delete fFilePanel; delete fFilePanel;
if (fActiveSourceWorker > 0)
wait_for_thread(fActiveSourceWorker, NULL);
} }
@@ -383,6 +388,17 @@ TeamWindow::MessageReceived(BMessage* message)
case MSG_LOCATE_SOURCE_IF_NEEDED: case MSG_LOCATE_SOURCE_IF_NEEDED:
{ {
_HandleLocateSourceRequest(); _HandleLocateSourceRequest();
break;
}
case MSG_SOURCE_ENTRY_QUERY_COMPLETE:
{
BStringList* entries;
if (message->FindPointer("entries", (void**)&entries) != B_OK)
break;
ObjectDeleter<BStringList> entryDeleter(entries);
_HandleLocateSourceRequest(entries);
fActiveSourceWorker = -1;
break;
} }
case MSG_THREAD_RUN: case MSG_THREAD_RUN:
case MSG_THREAD_STOP: case MSG_THREAD_STOP:
@@ -1529,6 +1545,44 @@ TeamWindow::_HandleWatchpointChanged(Watchpoint* watchpoint)
} }
status_t
TeamWindow::_RetrieveMatchingSourceWorker(void* arg)
{
TeamWindow* window = (TeamWindow*)arg;
BStringList* entries = new(std::nothrow) BStringList();
if (entries == NULL)
return B_NO_MEMORY;
ObjectDeleter<BStringList> stringListDeleter(entries);
if (!window->Lock())
return B_BAD_VALUE;
BString path;
window->fActiveFunction->GetFunctionDebugInfo()->SourceFile()
->GetPath(path);
window->Unlock();
status_t error = window->_RetrieveMatchingSourceEntries(path, entries);
if (error != B_OK)
return error;
entries->Sort();
BMessenger messenger(window);
if (messenger.IsValid() && messenger.LockTarget()) {
if (window->fActiveSourceWorker == find_thread(NULL)) {
BMessage message(MSG_SOURCE_ENTRY_QUERY_COMPLETE);
message.AddPointer("entries", entries);
if (messenger.SendMessage(&message) == B_OK)
stringListDeleter.Detach();
}
window->Unlock();
}
return B_OK;
}
void void
TeamWindow::_HandleResolveMissingSourceFile(entry_ref& locatedPath) TeamWindow::_HandleResolveMissingSourceFile(entry_ref& locatedPath)
{ {
@@ -1570,7 +1624,7 @@ TeamWindow::_HandleResolveMissingSourceFile(entry_ref& locatedPath)
void void
TeamWindow::_HandleLocateSourceRequest() TeamWindow::_HandleLocateSourceRequest(BStringList* entries)
{ {
if (fActiveFunction == NULL) if (fActiveFunction == NULL)
return; return;
@@ -1585,13 +1639,18 @@ TeamWindow::_HandleLocateSourceRequest()
return; return;
} }
BStringList entries; if (entries == NULL) {
if (_RetrieveMatchingSourceEntries(entries) != B_OK) if (fActiveSourceWorker < 0) {
fActiveSourceWorker = spawn_thread(&_RetrieveMatchingSourceWorker,
"source file query worker", B_NORMAL_PRIORITY, this);
if (fActiveSourceWorker > 0)
resume_thread(fActiveSourceWorker);
}
return; return;
}
int32 count = entries.CountStrings(); int32 count = entries->CountStrings();
if (count > 0) { if (count > 0) {
entries.Sort();
BPopUpMenu* menu = new(std::nothrow) BPopUpMenu(""); BPopUpMenu* menu = new(std::nothrow) BPopUpMenu("");
if (menu == NULL) if (menu == NULL)
return; return;
@@ -1599,7 +1658,7 @@ TeamWindow::_HandleLocateSourceRequest()
BPrivate::ObjectDeleter<BPopUpMenu> menuDeleter(menu); BPrivate::ObjectDeleter<BPopUpMenu> menuDeleter(menu);
BMenuItem* item = NULL; BMenuItem* item = NULL;
for (int32 i = 0; i < count; i++) { for (int32 i = 0; i < count; i++) {
item = new(std::nothrow) BMenuItem(entries.StringAt(i).String(), item = new(std::nothrow) BMenuItem(entries->StringAt(i).String(),
NULL); NULL);
if (item == NULL || !menu->AddItem(item)) { if (item == NULL || !menu->AddItem(item)) {
delete item; delete item;
@@ -1647,22 +1706,20 @@ TeamWindow::_HandleLocateSourceRequest()
status_t status_t
TeamWindow::_RetrieveMatchingSourceEntries(BStringList& _entries) TeamWindow::_RetrieveMatchingSourceEntries(const BString& path,
BStringList* _entries)
{ {
BString data; BPath filePath(path);
fActiveFunction->GetFunctionDebugInfo()->SourceFile()->GetPath(data); status_t error = filePath.InitCheck();
BPath path;
status_t error = path.SetTo(data);
if (error != B_OK) if (error != B_OK)
return error; return error;
_entries.MakeEmpty(); _entries->MakeEmpty();
BQuery query; BQuery query;
BString predicate; BString predicate;
query.PushAttr("name"); query.PushAttr("name");
query.PushString(path.Leaf()); query.PushString(filePath.Leaf());
query.PushOp(B_EQ); query.PushOp(B_EQ);
error = query.GetPredicate(&predicate); error = query.GetPredicate(&predicate);
@@ -1687,8 +1744,8 @@ TeamWindow::_RetrieveMatchingSourceEntries(BStringList& _entries)
entry_ref ref; entry_ref ref;
while (query.GetNextRef(&ref) == B_OK) { while (query.GetNextRef(&ref) == B_OK) {
path.SetTo(&ref); filePath.SetTo(&ref);
_entries.Add(path.Path()); _entries->Add(filePath.Path());
} }
query.Clear(); query.Clear();
@@ -168,11 +168,15 @@ private:
UserBreakpoint* breakpoint); UserBreakpoint* breakpoint);
void _HandleWatchpointChanged( void _HandleWatchpointChanged(
Watchpoint* watchpoint); Watchpoint* watchpoint);
static status_t _RetrieveMatchingSourceWorker(void* arg);
void _HandleResolveMissingSourceFile(entry_ref& void _HandleResolveMissingSourceFile(entry_ref&
locatedPath); locatedPath);
void _HandleLocateSourceRequest(); void _HandleLocateSourceRequest(
status_t _RetrieveMatchingSourceEntries( BStringList* entries = NULL);
BStringList& _entries); static status_t _RetrieveMatchingSourceEntries(
const BString& path,
BStringList* _entries);
status_t _SaveInspectorSettings( status_t _SaveInspectorSettings(
const BMessage* settings); const BMessage* settings);
@@ -214,6 +218,7 @@ private:
InspectorWindow* fInspectorWindow; InspectorWindow* fInspectorWindow;
GuiTeamUiSettings fUiSettings; GuiTeamUiSettings fUiSettings;
BFilePanel* fFilePanel; BFilePanel* fFilePanel;
thread_id fActiveSourceWorker;
}; };