refactor(libkernel): let an equeue filter name the descriptor its waits block on

WaitForDescriptors always handed the knote's own descriptor to the host wait. A filter that tracks readiness through a descriptor of its own, such as an edge watch, needs the wait to block on that descriptor instead, or a descriptor that stays ready keeps waking the wait. KernelFilter gets a waitDescriptor, and the filter's owner is held for the length of the wait so the descriptor cannot be closed under it.
This commit is contained in:
Alexej Szpevák authored and Adrià Franch committed 2026-10-19 15:05:10 +02:00
1 parent 3bb15be094
commit 5cbc46029b
2 files changed
+9 -1

No files matched your search

+8 -1
View File
@@ -98,8 +98,15 @@ void KernelEqueuePrivate::WakePollers() {
void KernelEqueuePrivate::WaitForDescriptors(std::unique_lock<std::mutex>& lock, std::uint64_t deadlineNanos) {
std::vector<GuestSockets::Interest> interests;
std::vector<std::shared_ptr<void>> held;
for (const auto& e : m_events) {
if (e.enabled && e.filter.pollFunc != nullptr) {
if (!e.enabled || e.filter.pollFunc == nullptr) {
continue;
}
if (e.filter.waitDescriptor >= 0) {
interests.push_back({e.filter.waitDescriptor, false});
held.push_back(e.filter.owner);
} else {
interests.push_back({static_cast<int>(e.event.ident), e.event.filter == EVFILT_WRITE});
}
}
@@ -55,6 +55,7 @@ struct KernelFilter {
EqueueResetFunc resetFunc = nullptr;
EqueueDeleteFunc deleteEventFunc = nullptr;
EqueuePollFunc pollFunc = nullptr;
int waitDescriptor = -1;
};
struct KernelEqueueEvent {