Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ ThreadInfo::unwind_tasks()
std::unordered_set<PyObject*> parent_tasks;
std::unordered_map<PyObject*, TaskInfo::Ref> waitee_map; // Indexed by task origin
std::unordered_map<PyObject*, TaskInfo::Ref> origin_map; // Indexed by task origin
static std::unordered_set<PyObject*> previous_task_objects;

auto maybe_all_tasks = get_all_tasks(reinterpret_cast<PyObject*>(asyncio_loop));
if (!maybe_all_tasks) {
Expand All @@ -232,14 +233,25 @@ ThreadInfo::unwind_tasks()
if (all_task_origins.find(kv.first) == all_task_origins.end())
to_remove.push_back(kv.first);
}
for (auto key : to_remove)
task_link_map.erase(key);
for (auto key : to_remove) {
// Only remove the link if the Child Task previously existed; otherwise it's a Task that
// has just been created and that wasn't in all_tasks when we took the snapshot.
if (previous_task_objects.find(key) != previous_task_objects.end()) {
task_link_map.erase(key);
}
}

// Determine the parent tasks from the gather links.
std::transform(task_link_map.cbegin(),
task_link_map.cend(),
std::inserter(parent_tasks, parent_tasks.begin()),
[](const std::pair<PyObject*, PyObject*>& kv) { return kv.second; });

// Copy all Task object pointers into previous_task_objects
previous_task_objects.clear();
for (const auto& task : all_tasks) {
previous_task_objects.insert(task->origin);
}
}

for (auto& task : all_tasks) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fixes:
- |
profiling: This fix resolves a race condition leading to incorrect stacks being reported
for asyncio parent/child Tasks (e.g. when using ``asyncio.gather``).
Loading