• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

llnl / dftracer-utils / 28521653886

01 Jul 2026 01:36PM UTC coverage: 50.92% (-1.4%) from 52.278%
28521653886

Pull #83

github

web-flow
Merge 9bdedb1e9 into 2efed6649
Pull Request #83: refactor and improve code QoL

31893 of 80049 branches covered (39.84%)

Branch coverage included in aggregate %.

789 of 1613 new or added lines in 87 files covered. (48.92%)

5007 existing lines in 181 files now uncovered.

32812 of 47024 relevant lines covered (69.78%)

9905.42 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

50.59
/src/dftracer/utils/core/tasks/task_result.cpp
1
#include <dftracer/utils/core/common/error.h>
2
#include <dftracer/utils/core/tasks/task_result.h>
3

4
#include <cassert>
5

6
namespace dftracer::utils {
7

8
void TaskResult::set_value(std::any value) {
763✔
9
    value_ = std::move(value);
763✔
10
    publish(State::value);
763✔
11
}
763✔
12

13
void TaskResult::set_exception(std::exception_ptr ex) {
17✔
14
    exception_ = ex;
17✔
15
    publish(State::exception);
17✔
16
}
17✔
17

18
void TaskResult::set_cancelled() { publish(State::cancelled); }
×
19

20
void TaskResult::mark_running() {
776✔
21
    auto expected = static_cast<std::uint8_t>(State::pending);
776✔
22
    state_.compare_exchange_strong(
776✔
23
        expected, static_cast<std::uint8_t>(State::running),
24
        std::memory_order_release, std::memory_order_relaxed);
25
}
776✔
26

27
void TaskResult::add_reader() {
561✔
28
    pending_readers_.fetch_add(1, std::memory_order_relaxed);
561✔
29
}
561✔
30

31
void TaskResult::release_reader() {
527✔
32
    int prev = pending_readers_.fetch_sub(1, std::memory_order_acq_rel);
527✔
33
    if (prev == 1) {
527✔
34
        // Last reader released -- free value memory
35
        std::lock_guard<std::mutex> lock(mutex_);
326✔
36
        value_ = std::any{};
326✔
37
    }
326✔
38
}
527✔
39

40
void TaskResult::publish(State s) {
780✔
41
    std::vector<std::coroutine_handle<>> to_resume;
780✔
42
    {
43
        std::lock_guard<std::mutex> lock(mutex_);
780✔
44
        state_.store(static_cast<std::uint8_t>(s), std::memory_order_release);
779✔
45
        to_resume.swap(continuations_);
779✔
46
    }
779✔
47
    cv_.notify_all();
779✔
48
    // Resume coroutine continuations OUTSIDE the lock.
49
    for (auto h : to_resume) {
779✔
50
        if (h && !h.done()) {
1!
51
            h.resume();
×
UNCOV
52
        }
×
53
    }
54
}
780✔
55

56
bool TaskResult::wait(std::chrono::milliseconds timeout) const {
426✔
57
    auto ready = [this] {
852✔
58
        auto s = static_cast<State>(state_.load(std::memory_order_acquire));
426✔
59
        return s == State::value || s == State::exception ||
426!
UNCOV
60
               s == State::cancelled;
×
61
    };
62
    if (ready()) return true;
426!
63

64
    std::unique_lock<std::mutex> lock(mutex_);
×
65
    if (timeout.count() == 0) {
×
66
        cv_.wait(lock, ready);
×
67
        return true;
×
68
    }
69
    return cv_.wait_for(lock, timeout, ready);
×
70
}
426✔
71

72
std::any TaskResult::get() const {
337✔
73
    wait();
337✔
74
    std::lock_guard<std::mutex> lock(mutex_);
337✔
75
    auto s = static_cast<State>(state_.load(std::memory_order_acquire));
337✔
76
    if (s == State::exception) {
337✔
77
        std::rethrow_exception(exception_);
3!
78
    }
79
    if (s == State::cancelled) {
334!
NEW
80
        throw DFTUtilsException(ErrorCode::PIPELINE, "Task was cancelled");
×
81
    }
82
    return value_;  // returns COPY
334!
83
}
337✔
84

85
std::any TaskResult::get_ready() const {
527✔
86
    std::lock_guard<std::mutex> lock(mutex_);
527✔
87
    auto s = static_cast<State>(state_.load(std::memory_order_acquire));
527✔
88
    assert(s == State::value || s == State::exception || s == State::cancelled);
527!
89
    if (s == State::exception) {
527!
90
        std::rethrow_exception(exception_);
×
91
    }
92
    if (s == State::cancelled) {
527!
NEW
93
        throw DFTUtilsException(ErrorCode::PIPELINE, "Task was cancelled");
×
94
    }
95
    return value_;  // returns COPY
527!
96
}
527✔
97

98
std::exception_ptr TaskResult::get_exception() const { return exception_; }
5✔
99

100
bool TaskResult::is_ready() const {
7✔
101
    auto s = static_cast<State>(state_.load(std::memory_order_acquire));
7✔
102
    return s == State::value || s == State::exception || s == State::cancelled;
7!
103
}
104

105
bool TaskResult::has_exception() const {
781✔
106
    return static_cast<State>(state_.load(std::memory_order_acquire)) ==
781✔
107
           State::exception;
108
}
109

110
bool TaskResult::is_cancelled() const {
×
111
    return static_cast<State>(state_.load(std::memory_order_acquire)) ==
×
112
           State::cancelled;
113
}
114

115
TaskResult::State TaskResult::state() const {
×
116
    return static_cast<State>(state_.load(std::memory_order_acquire));
×
117
}
118

119
// WhenReadyAwaitable
120
bool TaskResult::WhenReadyAwaitable::await_ready() const noexcept {
×
121
    return result.is_ready();
×
122
}
123

124
bool TaskResult::WhenReadyAwaitable::await_suspend(std::coroutine_handle<> h) {
×
125
    std::lock_guard<std::mutex> lock(result.mutex_);
×
126
    // Double-check under lock -- result may have been published
127
    // between await_ready() and await_suspend().
128
    if (result.is_ready()) {
×
129
        return false;  // Don't suspend, resume immediately
×
130
    }
131
    result.continuations_.push_back(h);
×
132
    return true;       // Suspend
×
133
}
×
134

135
void TaskResult::WhenReadyAwaitable::await_resume() {
×
136
    if (result.has_exception()) {
×
137
        std::rethrow_exception(result.exception_);
×
138
    }
139
}
×
140

141
}  // namespace dftracer::utils
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc