Skip to content

Conversation

@Paraworker
Copy link
Contributor

This PR fixes a rare issue when running Scheduler::clear().

Currently, Scheduler::clear() is to first drain active_tasks and wake their Wakers, and then drop all futures. However, a future might spawn a new task during its drop. In that case, a new Waker gets inserted into active_tasks, but its index might still be used by another task due to active_tasks having been drained and the index being reused.

As a result, the drop hook of the original task could remove a Waker that does not belong to it, which is not the behavior we expect.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR refactors the scheduler's task cleanup mechanism to improve efficiency and correctness. Instead of draining and consuming wakers during cleanup, the code now uses non-consuming iterations and relies on drop hooks to properly clean up waker references.

  • Changed the clear() method to use wake_by_ref() with iteration instead of wake() with drain
  • Replaced try_remove() with remove() in the drop hook
  • Improved documentation comments for clarity

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Berrysoft
Copy link
Member

Look familiar? Things like this (TOCTOU) are happening all over the galaxy (really), right now!

@Berrysoft
Copy link
Member

Could you add a test for this fix?

@Paraworker
Copy link
Contributor Author

Could you add a test for this fix?

tbh, I don’t know how to write this test case, because the previous situation did not cause a memory leak or a panic, It was just a sudden realization that the logic wasn’t entirely correct.

Berrysoft
Berrysoft previously approved these changes Nov 5, 2025
@Berrysoft
Copy link
Member

Almost LGTM. @George-Miao to review it too.

@Berrysoft
Copy link
Member

I don’t know how to write this test case

How about this: add two tasks to the runtime, and the second one panics after being woke. If there's a bug, the second one might be removed and never panics.

@Paraworker
Copy link
Contributor Author

How about this: add two tasks to the runtime, and the second one panics after being woke. If there's a bug, the second one might be removed and never panics.

Not fully understand, in Scheduler::clear() the futures are not polled, only dropped. waking a Waker only pushes it to the queue, so it should never panic.

@Berrysoft
Copy link
Member

You're right. Let's wait for another reviewer:)

@George-Miao
Copy link
Member

Exact problem with slab I described in the first PR lol

@Berrysoft Berrysoft self-requested a review November 5, 2025 14:50
@Berrysoft
Copy link
Member

Could you bump the version so that I can publish a fix release?

@Paraworker
Copy link
Contributor Author

Could you bump the version so that I can publish a fix release?

Done, version bumped.

@George-Miao George-Miao added bug Something isn't working package: runtime Related to compio-runtime labels Nov 5, 2025
Copy link
Member

@Berrysoft Berrysoft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Berrysoft Berrysoft merged commit 0bc590d into compio-rs:master Nov 7, 2025
50 checks passed
@Paraworker Paraworker deleted the fix/no-drain branch November 8, 2025 19:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working package: runtime Related to compio-runtime

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants