-
Notifications
You must be signed in to change notification settings - Fork 347
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support blocking for epoll #3804
Conversation
This should be EDIT: Ah, you don't. And it is indeed impossible, this approach is a dead end. Just using an owned |
☔ The latest upstream changes (presumably #3712) made this pull request unmergeable. Please resolve the merge conflicts. |
This works, thanks! |
☔ The latest upstream changes (presumably #3809) made this pull request unmergeable. Please resolve the merge conflicts. |
I wonder if it would make sense to implement #3665 first, as that's a much easier case of blocking? That might be a good way to learn how Miri deals with blocking. |
That's what I said, too, in our last meeting, and we realized it is not easier, as you need to refactor all read/write methods instead of just focussing on this one |
(If those are done first, I'd like to have a PR that passes |
Oh wait, so that does not have to happen for this one? Ah right, the blocking is in epoll_wait, not in read/write... makes sense. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please bless and fix the tokio sleep test
src/shims/unix/linux/epoll.rs
Outdated
// Collect all thread id of blocked threads that received notification. | ||
let thread_id = epoll_event_interest.thread_id; | ||
if this.has_blocked_on_epoll(thread_id) { | ||
waiters.push(thread_id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could also just wake here and record in a hashset whether the thread id was already woken
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the new change in 9cb087d, I was trying to avoid using this.unblock_thread
inside
if let Some(epoll_interests) = this.machine.epoll_interests.get_epoll_interest(id) { }
because it will trigger this error:
error[E0502]: cannot borrow `*this` as mutable because it is also borrowed as immutable
--> src/shims/unix/linux/epoll.rs:594:29
|
568 | if let Some(epoll_interests) = this.machine.epoll_interests.get_epoll_interest(id) {
| ---------------------------- immutable borrow occurs here
...
573 | for weak_epoll_interest in epoll_interests {
| --------------- immutable borrow later used here
...
594 | this.unblock_thread(thread_id, BlockReason::Epoll)?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
So instead I just store the ThreadIds that I want to unblock into a Vec then unblock them altogether outside of the block.
This is how it currently works: struct Epoll {
/// A map of EpollEventInterests registered under this epoll instance.
/// Each entry is differentiated using FdId and file descriptor value.
interest_list: RefCell<BTreeMap<(FdId, i32), Rc<RefCell<EpollEventInterest>>>>,
/// A map of EpollEventInstance that will be returned when `epoll_wait` is called.
/// Similar to interest_list, the entry is also differentiated using FdId
/// and file descriptor value.
// This is an Rc because EpollInterest need to hold a reference to update
// it.
ready_list: Rc<RefCell<BTreeMap<(FdId, i32), EpollEventInstance>>>,
/// A list of thread ids blocked on this epoll instance.
thread_id: RefCell<Vec<ThreadId>>, // < this is newly added
} Later in |
@rustbot ready |
The PR's main message is a bit outdated |
Do we want another test for triggering a notification after the |
There should be such a test in your libc-epoll-blocking test file.
But doesn't `test_epoll_block_without_notification` do that?
|
No, that test only epoll_wait, then timeout without notification. A notification need to be sent after timeout to trigger the bug. Also there is an error on the comment for that test, sorry for the confusion. |
Okay, just make sure the test has a comment explaining the exact scenario. :) |
@bors r+ |
☀️ Test successful - checks-actions |
Add tokio io test After #3804 landed, these tests passed.
This PR enabled epoll to have blocking operation.
The changes introduced by this PR are:
epoll_wait
toblocking_epoll_callback
thread_ids
inEpoll
for blocked thread idsBlockReason::Epoll