summaryrefslogtreecommitdiff
path: root/lldb/source/Host/common/Alarm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Host/common/Alarm.cpp')
-rw-r--r--lldb/source/Host/common/Alarm.cpp84
1 files changed, 45 insertions, 39 deletions
diff --git a/lldb/source/Host/common/Alarm.cpp b/lldb/source/Host/common/Alarm.cpp
index 245cdc7ae5c2..afc770d20d7b 100644
--- a/lldb/source/Host/common/Alarm.cpp
+++ b/lldb/source/Host/common/Alarm.cpp
@@ -154,54 +154,60 @@ lldb::thread_result_t Alarm::AlarmThread() {
//
// Below we only deal with the timeout expiring and fall through for dealing
// with the rest.
- std::unique_lock<std::mutex> alarm_lock(m_alarm_mutex);
- if (next_alarm) {
- if (!m_alarm_cv.wait_until(alarm_lock, *next_alarm, predicate)) {
- // The timeout for the next alarm expired.
-
- // Clear the next timeout to signal that we need to recompute the next
- // timeout.
- next_alarm.reset();
-
- // Iterate over all the callbacks. Call the ones that have expired
- // and remove them from the list.
- const TimePoint now = std::chrono::system_clock::now();
- auto it = m_entries.begin();
- while (it != m_entries.end()) {
- if (it->expiration <= now) {
- it->callback();
- it = m_entries.erase(it);
- } else {
- it++;
+ llvm::SmallVector<Callback, 1> callbacks;
+ {
+ std::unique_lock<std::mutex> alarm_lock(m_alarm_mutex);
+ if (next_alarm) {
+ if (!m_alarm_cv.wait_until(alarm_lock, *next_alarm, predicate)) {
+ // The timeout for the next alarm expired.
+
+ // Clear the next timeout to signal that we need to recompute the next
+ // timeout.
+ next_alarm.reset();
+
+ // Iterate over all the callbacks. Call the ones that have expired
+ // and remove them from the list.
+ const TimePoint now = std::chrono::system_clock::now();
+ auto it = m_entries.begin();
+ while (it != m_entries.end()) {
+ if (it->expiration <= now) {
+ callbacks.emplace_back(std::move(it->callback));
+ it = m_entries.erase(it);
+ } else {
+ it++;
+ }
}
}
+ } else {
+ m_alarm_cv.wait(alarm_lock, predicate);
}
- } else {
- m_alarm_cv.wait(alarm_lock, predicate);
- }
- // Fall through after waiting on the condition variable. At this point
- // either the predicate is true or we woke up because an alarm expired.
+ // Fall through after waiting on the condition variable. At this point
+ // either the predicate is true or we woke up because an alarm expired.
- // The alarm thread is shutting down.
- if (m_exit) {
- exit = true;
- if (m_run_callbacks_on_exit) {
- for (Entry &entry : m_entries)
- entry.callback();
+ // The alarm thread is shutting down.
+ if (m_exit) {
+ exit = true;
+ if (m_run_callbacks_on_exit) {
+ for (Entry &entry : m_entries)
+ callbacks.emplace_back(std::move(entry.callback));
+ }
}
- continue;
- }
- // A new alarm was added or an alarm expired. Either way we need to
- // recompute when this thread should wake up for the next alarm.
- if (m_recompute_next_alarm || !next_alarm) {
- for (Entry &entry : m_entries) {
- if (!next_alarm || entry.expiration < *next_alarm)
- next_alarm = entry.expiration;
+ // A new alarm was added or an alarm expired. Either way we need to
+ // recompute when this thread should wake up for the next alarm.
+ if (m_recompute_next_alarm || !next_alarm) {
+ for (Entry &entry : m_entries) {
+ if (!next_alarm || entry.expiration < *next_alarm)
+ next_alarm = entry.expiration;
+ }
+ m_recompute_next_alarm = false;
}
- m_recompute_next_alarm = false;
}
+
+ // Outside the lock, call the callbacks.
+ for (Callback &callback : callbacks)
+ callback();
}
return {};
}