11
11
#include " lldb/Core/Debugger.h"
12
12
#include " lldb/Utility/StreamString.h"
13
13
14
+ #include < cstdint>
14
15
#include < mutex>
15
16
#include < optional>
16
17
@@ -22,38 +23,46 @@ std::atomic<uint64_t> Progress::g_id(0);
22
23
Progress::Progress (std::string title, std::string details,
23
24
std::optional<uint64_t > total,
24
25
lldb_private::Debugger *debugger)
25
- : m_title(title), m_details(details), m_id(++g_id), m_completed(0 ),
26
- m_total(Progress::kNonDeterministicTotal ) {
26
+ : m_progress_data{title,
27
+ details,
28
+ ++g_id,
29
+ /* m_progress_data.completed=*/ 0 ,
30
+ Progress::kNonDeterministicTotal ,
31
+ /* m_progress_data.debugger_id=*/ std::nullopt} {
27
32
if (total)
28
- m_total = *total;
33
+ m_progress_data. total = *total;
29
34
30
35
if (debugger)
31
- m_debugger_id = debugger->GetID ();
36
+ m_progress_data.debugger_id = debugger->GetID ();
37
+
32
38
std::lock_guard<std::mutex> guard (m_mutex);
33
39
ReportProgress ();
40
+ ProgressManager::Instance ().Increment (m_progress_data);
34
41
}
35
42
36
43
Progress::~Progress () {
37
44
// Make sure to always report progress completed when this object is
38
45
// destructed so it indicates the progress dialog/activity should go away.
39
46
std::lock_guard<std::mutex> guard (m_mutex);
40
- if (!m_completed )
41
- m_completed = m_total ;
47
+ if (!m_progress_data. completed )
48
+ m_progress_data. completed = m_progress_data. total ;
42
49
ReportProgress ();
50
+ ProgressManager::Instance ().Decrement (m_progress_data);
43
51
}
44
52
45
53
void Progress::Increment (uint64_t amount,
46
54
std::optional<std::string> updated_detail) {
47
55
if (amount > 0 ) {
48
56
std::lock_guard<std::mutex> guard (m_mutex);
49
57
if (updated_detail)
50
- m_details = std::move (updated_detail.value ());
58
+ m_progress_data. details = std::move (updated_detail.value ());
51
59
// Watch out for unsigned overflow and make sure we don't increment too
52
- // much and exceed m_total.
53
- if (m_total && (amount > (m_total - m_completed)))
54
- m_completed = m_total;
60
+ // much and exceed the total.
61
+ if (m_progress_data.total &&
62
+ (amount > (m_progress_data.total - m_progress_data.completed )))
63
+ m_progress_data.completed = m_progress_data.total ;
55
64
else
56
- m_completed += amount;
65
+ m_progress_data. completed += amount;
57
66
ReportProgress ();
58
67
}
59
68
}
@@ -62,9 +71,11 @@ void Progress::ReportProgress() {
62
71
if (!m_complete) {
63
72
// Make sure we only send one notification that indicates the progress is
64
73
// complete
65
- m_complete = m_completed == m_total;
66
- Debugger::ReportProgress (m_id, m_title, m_details, m_completed, m_total,
67
- m_debugger_id);
74
+ m_complete = m_progress_data.completed == m_progress_data.total ;
75
+ Debugger::ReportProgress (m_progress_data.progress_id , m_progress_data.title ,
76
+ m_progress_data.details , m_progress_data.completed ,
77
+ m_progress_data.total ,
78
+ m_progress_data.debugger_id );
68
79
}
69
80
}
70
81
@@ -82,20 +93,42 @@ ProgressManager &ProgressManager::Instance() {
82
93
return *g_progress_manager;
83
94
}
84
95
85
- void ProgressManager::Increment (std::string title ) {
96
+ void ProgressManager::Increment (const Progress::ProgressData &progress_data ) {
86
97
std::lock_guard<std::mutex> lock (m_progress_map_mutex);
87
- m_progress_category_map[title]++;
98
+ // If the current category exists in the map then it is not an initial report,
99
+ // therefore don't broadcast to the category bit. Also, store the current
100
+ // progress data in the map so that we have a note of the ID used for the
101
+ // initial progress report.
102
+ if (!m_progress_category_map.contains (progress_data.title )) {
103
+ m_progress_category_map[progress_data.title ].second = progress_data;
104
+ ReportProgress (progress_data);
105
+ }
106
+ m_progress_category_map[progress_data.title ].first ++;
88
107
}
89
108
90
- void ProgressManager::Decrement (std::string title ) {
109
+ void ProgressManager::Decrement (const Progress::ProgressData &progress_data ) {
91
110
std::lock_guard<std::mutex> lock (m_progress_map_mutex);
92
- auto pos = m_progress_category_map.find (title);
111
+ auto pos = m_progress_category_map.find (progress_data. title );
93
112
94
113
if (pos == m_progress_category_map.end ())
95
114
return ;
96
115
97
- if (pos->second <= 1 )
98
- m_progress_category_map.erase (title);
99
- else
100
- --pos->second ;
116
+ if (pos->second .first <= 1 ) {
117
+ ReportProgress (progress_data);
118
+ m_progress_category_map.erase (progress_data.title );
119
+ } else {
120
+ --pos->second .first ;
121
+ }
122
+ }
123
+
124
+ void ProgressManager::ReportProgress (Progress::ProgressData progress_data) {
125
+ // The category bit only keeps track of when progress report categories have
126
+ // started and ended, so clear the details and other fields when broadcasting
127
+ // to it since that bit doesn't need that information.
128
+
129
+ Debugger::ReportProgress (
130
+ m_progress_category_map[progress_data.title ].second .progress_id ,
131
+ progress_data.title , " " , Progress::kNonDeterministicTotal ,
132
+ Progress::kNonDeterministicTotal , progress_data.debugger_id ,
133
+ Debugger::eBroadcastBitProgressCategory);
101
134
}
0 commit comments