Skip to content

Commit 22d2f7f

Browse files
authored
[lldb] Emit a progress event from the source manager (#165802)
Reading a source file might take a while, for example because it's located on a virtual file system that's fetching the data on demand. This PR emits a progress event to convey this to the user when reading the file exceeds a certain threshold (500ms). Although it doesn't speed up the operation, it still greatly improves the user experience by helping them understand what's going on. rdar://163750392
1 parent 6bac76b commit 22d2f7f

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

lldb/include/lldb/Core/SourceManager.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ class SourceManager {
109109
private:
110110
void CommonInitializer(lldb::SupportFileSP support_file_sp,
111111
lldb::TargetSP target_sp);
112+
void CommonInitializerImpl(lldb::SupportFileSP support_file_sp,
113+
lldb::TargetSP target_sp);
112114
};
113115

114116
typedef std::shared_ptr<File> FileSP;

lldb/source/Core/SourceManager.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434

3535
#include "llvm/ADT/Twine.h"
3636

37+
#include <future>
3738
#include <memory>
3839
#include <optional>
3940
#include <utility>
@@ -54,8 +55,7 @@ using namespace lldb_private;
5455
static inline bool is_newline_char(char ch) { return ch == '\n' || ch == '\r'; }
5556

5657
static void resolve_tilde(FileSpec &file_spec) {
57-
if (!FileSystem::Instance().Exists(file_spec) &&
58-
file_spec.GetDirectory() &&
58+
if (!FileSystem::Instance().Exists(file_spec) && file_spec.GetDirectory() &&
5959
file_spec.GetDirectory().GetCString()[0] == '~') {
6060
FileSystem::Instance().Resolve(file_spec);
6161
}
@@ -477,6 +477,28 @@ SourceManager::File::File(SupportFileSP support_file_sp, TargetSP target_sp)
477477

478478
void SourceManager::File::CommonInitializer(SupportFileSP support_file_sp,
479479
TargetSP target_sp) {
480+
// It might take a while to read a source file, for example because it's
481+
// coming from a virtual file system that's fetching the data on demand. When
482+
// reading the data exceeds a certain threshold, show a progress event to let
483+
// the user know what's going on.
484+
static constexpr auto g_progress_delay = std::chrono::milliseconds(500);
485+
486+
std::future<void> future = std::async(std::launch::async, [=]() {
487+
CommonInitializerImpl(support_file_sp, target_sp);
488+
});
489+
490+
std::optional<Progress> progress;
491+
if (future.wait_for(g_progress_delay) == std::future_status::timeout) {
492+
Debugger *debugger = target_sp ? &target_sp->GetDebugger() : nullptr;
493+
progress.emplace("Loading source file",
494+
support_file_sp->GetSpecOnly().GetFilename().GetString(),
495+
1, debugger);
496+
}
497+
future.wait();
498+
}
499+
500+
void SourceManager::File::CommonInitializerImpl(SupportFileSP support_file_sp,
501+
TargetSP target_sp) {
480502
// Set the file and update the modification time.
481503
SetSupportFile(support_file_sp);
482504

0 commit comments

Comments
 (0)