Skip to content

fix: dont wake up calloop if no messages were read#9

Draft
druskus20 wants to merge 1 commit into
Smithay:mainfrom
druskus20:fix-spurious-dispatch
Draft

fix: dont wake up calloop if no messages were read#9
druskus20 wants to merge 1 commit into
Smithay:mainfrom
druskus20:fix-spurious-dispatch

Conversation

@druskus20
Copy link
Copy Markdown

I found that my event loop was being woken up twice back to back by WaylandSource. Turns out the socket's read() call can return Ok(0) for some reason. My guess is that the socket becomes readable but no complete events are found on it.

In such case, maybe it's best to skip dispatching, thus not waking up the event loop into which this source is inserted.

It is entirely possible that the extra check is not worth the effort. Maybe there are better ways to solve this. Maybe this is just not an issue.

I have no strong opinions or deep knowledge in this regard, so feel free to close this PR or modify it however you see fit if it's not applicable.

Comment thread src/lib.rs
Comment on lines -208 to -216
if let Some(Err(WaylandError::Io(err))) = guard.map(ReadEventsGuard::read) {
// If some other thread read events before us, concurrently, that's an expected
// case, so this error isn't an issue. Other error kinds do need to be returned,
// however
if err.kind() != io::ErrorKind::WouldBlock {
match guard.map(ReadEventsGuard::read) {
Some(Ok(n)) => {
self.messages_read = n;
},
Some(Err(WaylandError::Io(err))) => {
// If some other thread read events before us, concurrently, that's an expected
// case, so this error isn't an issue. Other error kinds do need to be returned,
// however
if err.kind() != io::ErrorKind::WouldBlock {
// before_handle_events doesn't allow returning errors
// For now, cache it in self until process_events is called
self.stored_error = Err(err);
}
},
Some(Err(WaylandError::Protocol(err))) => {
log_error!("Protocol error received on display: {}", err);
// before_handle_events doesn't allow returning errors
// For now, cache it in self until process_events is called
self.stored_error = Err(err);
}
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I found that this if let is not exhaustive. I can split this into a separate commit if you prefer. Or we can discard it completely if it does not make sense

Copy link
Copy Markdown
Member

@kchibisov kchibisov left a comment

Choose a reason for hiding this comment

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

Have you read this big comment?

// If some other thread read events before us, concurrently, that's an expected
// case, so this error isn't an issue. Other error kinds do need to be returned,
// however

You clearly broke the dispatch logic, because if some other thread enqueued events there won't be any events for us to read, thus Read(0) but we can have some enqueued by other thread in MT environment (read as using any graphics driver).

I'm not sure we can how many events are there in our queue though, maybe if we can check that there're none in our queue we can avoid dispatch logic.

@druskus20
Copy link
Copy Markdown
Author

Have you read this big comment?

// If some other thread read events before us, concurrently, that's an expected
// case, so this error isn't an issue. Other error kinds do need to be returned,
// however

You clearly broke the dispatch logic, because if some other thread enqueued events there won't be any events for us to read, thus Read(0) but we can have some enqueued by other thread in MT environment (read as using any graphics driver).

I'm not sure we can how many events are there in our queue though, maybe if we can check that there're none in our queue we can avoid dispatch logic.

You are right, thanks. My bad, I had not thought through that.
Let me mark it as draft.

@druskus20 druskus20 marked this pull request as draft May 7, 2026 12:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants