Skip to content

Commit

Permalink
Fix using wrong token to process a PostAction
Browse files Browse the repository at this point in the history
  • Loading branch information
elinorbgr committed Sep 25, 2023
1 parent 6a67e67 commit 3b0f8de
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 3 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

- Fix an issue where the `Generic` event source would try to unregister its contents from the event loop
after a failed registration.
- Fix an issue where the `EventLoop` would panic when processing a `PostAction::Remove` from an event source
with subsources.

## 0.12.1 -- 2023-09-19

Expand Down
79 changes: 76 additions & 3 deletions src/loop_logic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ impl<'l, Data> EventLoop<'l, Data> {
.inner
.sources_with_additional_lifecycle_events
.borrow_mut(),
&mut TokenFactory::new(event.token.key),
&mut TokenFactory::new(registroken_token),
)?;
}
PostAction::Disable => {
Expand Down Expand Up @@ -477,7 +477,7 @@ impl<'l, Data> EventLoop<'l, Data> {
.inner
.sources
.borrow_mut()
.remove(event.token.key);
.remove(registroken_token);
}
PostAction::Continue => {}
}
Expand Down Expand Up @@ -509,7 +509,7 @@ impl<'l, Data> EventLoop<'l, Data> {
} else {
log::warn!(
"[calloop] Received an event for non-existence source: {:?}",
event.token.key
registroken_token
);
}
}
Expand Down Expand Up @@ -1457,6 +1457,79 @@ mod tests {
assert_eq!(data, 22);
}

#[test]
fn drop_of_subsource() {
struct WithSubSource {
token: Option<Token>,
}

impl crate::EventSource for WithSubSource {
type Event = ();
type Metadata = ();
type Ret = ();
type Error = crate::Error;
const NEEDS_EXTRA_LIFECYCLE_EVENTS: bool = true;

fn process_events<F>(
&mut self,
_: Readiness,
_: Token,
mut callback: F,
) -> Result<PostAction, Self::Error>
where
F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
{
callback((), &mut ());
// Drop the source
Ok(PostAction::Remove)
}

fn register(&mut self, _: &mut Poll, fact: &mut TokenFactory) -> crate::Result<()> {
// produce a few tokens to emulate a subsource
fact.token();
fact.token();
self.token = Some(fact.token());
Ok(())
}

fn reregister(&mut self, _: &mut Poll, _: &mut TokenFactory) -> crate::Result<()> {
Ok(())
}

fn unregister(&mut self, _: &mut Poll) -> crate::Result<()> {
Ok(())
}

// emulate a readiness
fn before_sleep(&mut self) -> crate::Result<Option<(Readiness, Token)>> {
Ok(self.token.map(|token| {
(
Readiness {
readable: true,
writable: false,
error: false,
},
token,
)
}))
}
}

// Now the actual test
let mut evl = EventLoop::<bool>::try_new().unwrap();
evl.handle()
.insert_source(WithSubSource { token: None }, |_, _, ran| {
*ran = true;
})
.unwrap();

let mut ran = false;

evl.dispatch(Some(Duration::ZERO), &mut ran).unwrap();

assert!(ran);
}

// A dummy EventSource to test insertion and removal of sources
struct DummySource;

Expand Down

0 comments on commit 3b0f8de

Please sign in to comment.