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

llnl / dftracer-utils / 28693295402

04 Jul 2026 03:17AM UTC coverage: 52.408% (+0.1%) from 52.278%
28693295402

push

github

hariharan-devarajan
feat: silence noisy warnings on aarch64

37318 of 92666 branches covered (40.27%)

Branch coverage included in aggregate %.

33462 of 42389 relevant lines covered (78.94%)

20557.64 hits per line

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

5.26
/src/dftracer/utils/python/task_handle.cpp
1
#define PY_SSIZE_T_CLEAN
2
#include <Python.h>
3
#include <dftracer/utils/python/py_errors.h>
4
#include <dftracer/utils/python/py_runtime_mixin.h>
5
#include <dftracer/utils/python/py_type_helpers.h>
6
#include <dftracer/utils/python/task_handle.h>
7

8
#include <any>
9
#include <chrono>
10
#include <future>
11
#include <string>
12

13
static void TaskHandle_dealloc(TaskHandleObject *self) {
×
14
    self->future.~shared_future();
×
15
    self->typed_future.~shared_future();
×
16
    self->name.~basic_string();
×
17
    Py_TYPE(self)->tp_free((PyObject *)self);
×
18
}
×
19

20
static PyObject *TaskHandle_new(PyTypeObject *type, PyObject * /*args*/,
×
21
                                PyObject * /*kwds*/) {
22
    TaskHandleObject *self = (TaskHandleObject *)type->tp_alloc(type, 0);
×
23
    if (self) {
×
24
        new (&self->future) std::shared_future<void>();
×
25
        new (&self->typed_future) std::shared_future<std::any>();
×
26
        new (&self->name) std::string();
×
27
        self->has_typed_future = false;
×
28
        self->task_id = -1;
×
29
    }
30
    return (PyObject *)self;
×
31
}
32

33
static PyObject *TaskHandle_get(TaskHandleObject *self,
×
34
                                PyObject *Py_UNUSED(ignored)) {
35
    if (!self->future.valid()) {
×
36
        Py_RETURN_NONE;
×
37
    }
38
    if (self->has_typed_future) {
×
39
        std::any result;
×
40
        if (!run_blocking_r([&] { return self->typed_future.get(); }, result))
×
41
            return NULL;
×
42
        if (result.has_value()) {
×
43
            try {
44
                PyObject *obj = std::any_cast<PyObject *>(result);
×
45
                if (obj) {
×
46
                    Py_INCREF(obj);
×
47
                    return obj;
×
48
                }
49
            } catch (const std::bad_any_cast &) {
×
50
                // Not a PyObject* — fall through to None
51
            }
×
52
        }
53
        Py_RETURN_NONE;
×
54
    }
×
55

56
    // Void task: .get() returns void and rethrows stored exceptions.
57
    if (!run_blocking([&] { self->future.get(); })) return NULL;
×
58
    Py_RETURN_NONE;
×
59
}
60

61
static PyObject *TaskHandle_wait(TaskHandleObject *self,
×
62
                                 PyObject *Py_UNUSED(ignored)) {
63
    if (!self->future.valid()) {
×
64
        Py_RETURN_NONE;
×
65
    }
66
    // Use .get() (not .wait()) so stored exceptions are rethrown.
67
    if (!run_blocking([&] { self->future.get(); })) return NULL;
×
68
    Py_RETURN_NONE;
×
69
}
70

71
static PyObject *TaskHandle_done(TaskHandleObject *self,
×
72
                                 PyObject *Py_UNUSED(ignored)) {
73
    if (!self->future.valid()) {
×
74
        Py_RETURN_FALSE;
×
75
    }
76
    bool is_done = self->future.wait_for(std::chrono::seconds(0)) ==
×
77
                   std::future_status::ready;
78
    return PyBool_FromLong(is_done ? 1 : 0);
×
79
}
80

81
static PyObject *TaskHandle_get_name(TaskHandleObject *self, void *) {
×
82
    return PyUnicode_FromStringAndSize(
×
83
        self->name.data(), static_cast<Py_ssize_t>(self->name.size()));
×
84
}
85

86
static PyObject *TaskHandle_get_task_id(TaskHandleObject *self, void *) {
×
87
    return PyLong_FromLongLong(static_cast<long long>(self->task_id));
×
88
}
89

90
static PyMethodDef TaskHandle_methods[] = {
91
    {"get", (PyCFunction)TaskHandle_get, METH_NOARGS,
92
     "Block until task completes and return result.\n"
93
     "Raises RuntimeError if the task failed."},
94
    {"wait", (PyCFunction)TaskHandle_wait, METH_NOARGS,
95
     "Block until task completes.\n"
96
     "Raises RuntimeError if the task failed."},
97
    {"done", (PyCFunction)TaskHandle_done, METH_NOARGS,
98
     "Return True if task has completed."},
99
    {NULL}};
100

101
static PyGetSetDef TaskHandle_getsetters[] = {
102
    {"name", (getter)TaskHandle_get_name, NULL, "Task name", NULL},
103
    {"task_id", (getter)TaskHandle_get_task_id, NULL, "Task identifier", NULL},
104
    {NULL}};
105

106
PyTypeObject TaskHandleType = {
107
    PyVarObject_HEAD_INIT(NULL, 0) "dftracer_utils_ext.TaskHandle",
108
    sizeof(TaskHandleObject),                       /* tp_basicsize */
109
    0,                                              /* tp_itemsize */
110
    (destructor)TaskHandle_dealloc,                 /* tp_dealloc */
111
    0,                                              /* tp_vectorcall_offset */
112
    0,                                              /* tp_getattr */
113
    0,                                              /* tp_setattr */
114
    0,                                              /* tp_as_async */
115
    0,                                              /* tp_repr */
116
    0,                                              /* tp_as_number */
117
    0,                                              /* tp_as_sequence */
118
    0,                                              /* tp_as_mapping */
119
    0,                                              /* tp_hash */
120
    0,                                              /* tp_call */
121
    0,                                              /* tp_str */
122
    0,                                              /* tp_getattro */
123
    0,                                              /* tp_setattro */
124
    0,                                              /* tp_as_buffer */
125
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,       /* tp_flags */
126
    "Handle to an async task submitted to Runtime", /* tp_doc */
127
    0,                                              /* tp_traverse */
128
    0,                                              /* tp_clear */
129
    0,                                              /* tp_richcompare */
130
    0,                                              /* tp_weaklistoffset */
131
    0,                                              /* tp_iter */
132
    0,                                              /* tp_iternext */
133
    TaskHandle_methods,                             /* tp_methods */
134
    0,                                              /* tp_members */
135
    TaskHandle_getsetters,                          /* tp_getset */
136
    0,                                              /* tp_base */
137
    0,                                              /* tp_dict */
138
    0,                                              /* tp_descr_get */
139
    0,                                              /* tp_descr_set */
140
    0,                                              /* tp_dictoffset */
141
    0,                                              /* tp_init */
142
    0,                                              /* tp_alloc */
143
    TaskHandle_new,                                 /* tp_new */
144
};
145

146
PyObject *create_task_handle(dftracer::utils::TaskHandle handle) {
×
147
    TaskHandleObject *obj =
148
        (TaskHandleObject *)TaskHandleType.tp_alloc(&TaskHandleType, 0);
×
149
    if (!obj) return NULL;
×
150
    new (&obj->future) std::shared_future<void>(std::move(handle.future));
×
151
    new (&obj->typed_future) std::shared_future<std::any>();
×
152
    new (&obj->name) std::string(std::move(handle.name));
×
153
    obj->has_typed_future = false;
×
154
    obj->task_id = handle.id;
×
155
    return (PyObject *)obj;
×
156
}
157

158
PyObject *create_typed_task_handle(std::shared_future<void> void_future,
×
159
                                   std::shared_future<std::any> typed_future,
160
                                   dftracer::utils::TaskIndex id,
161
                                   std::string name) {
162
    TaskHandleObject *obj =
163
        (TaskHandleObject *)TaskHandleType.tp_alloc(&TaskHandleType, 0);
×
164
    if (!obj) return NULL;
×
165
    new (&obj->future) std::shared_future<void>(std::move(void_future));
×
166
    new (&obj->typed_future)
×
167
        std::shared_future<std::any>(std::move(typed_future));
×
168
    new (&obj->name) std::string(std::move(name));
×
169
    obj->has_typed_future = true;
×
170
    obj->task_id = id;
×
171
    return (PyObject *)obj;
×
172
}
173

174
int init_task_handle(PyObject *m) {
2✔
175
    if (register_type(m, &TaskHandleType, "TaskHandle") < 0) return -1;
2✔
176
    return 0;
2✔
177
}
1✔
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