From 04463bf78cf86d6e7a9236e911de00db9096372b Mon Sep 17 00:00:00 2001 From: Elinor Berger Date: Fri, 6 Oct 2023 00:09:51 +0200 Subject: [PATCH] Implement `AsRawFd`/`AsFd` for `EventLoop<'l, Data>` This should allow inserting one `EventLoop` into another. --- CHANGELOG.md | 1 + src/loop_logic.rs | 31 ++++++++++++++++++++++++++++++- src/sys.rs | 2 +- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f11f1f19..27919f92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ #### Additions - `Token` and `RegistrationToken` are now invalidated when the event source they represent is removed from the event loop. +- Implement `AsRawFd` and `AsFd` for `EventLoop<'l, Data>` #### Bugfixes diff --git a/src/loop_logic.rs b/src/loop_logic.rs index 1db8a534..58bf4071 100644 --- a/src/loop_logic.rs +++ b/src/loop_logic.rs @@ -1,6 +1,6 @@ use std::cell::{Cell, RefCell}; use std::fmt::Debug; -use std::os::unix::io::AsFd; +use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, RawFd}; use std::rc::Rc; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; @@ -11,6 +11,7 @@ use std::{io, slice}; use std::future::Future; use log::trace; +use polling::Poller; use crate::list::{SourceEntry, SourceList}; use crate::sources::{Dispatcher, EventSource, Idle, IdleDispatcher}; @@ -286,6 +287,7 @@ impl<'l, Data> LoopHandle<'l, Data> { /// /// This loop can host several event sources, that can be dynamically added or removed. pub struct EventLoop<'l, Data> { + poller: Arc, handle: LoopHandle<'l, Data>, signals: Arc, // A caching vector for synthetic poll events @@ -315,6 +317,7 @@ impl<'l, Data> EventLoop<'l, Data> { /// Fails if the initialization of the polling system failed. pub fn try_new() -> crate::Result { let poll = Poll::new()?; + let poller = poll.poller.clone(); let handle = LoopHandle { inner: Rc::new(LoopInner { poll: RefCell::new(poll), @@ -332,6 +335,7 @@ impl<'l, Data> EventLoop<'l, Data> { #[cfg(feature = "block_on")] future_ready: AtomicBool::new(false), }), + poller, synthetic_events: vec![], }) } @@ -660,6 +664,31 @@ impl<'l, Data> EventLoop<'l, Data> { } } +impl<'l, Data> AsRawFd for EventLoop<'l, Data> { + /// Get the underlying raw-fd of the poller. + /// + /// This could be used to create [`Generic`] source out of the current loop + /// and inserting into some other [`EventLoop`]. It's recommended to clone `fd` + /// before doing so. + /// + /// [`Generic`]: crate::generic::Generic + fn as_raw_fd(&self) -> RawFd { + self.poller.as_raw_fd() + } +} + +impl<'l, Data> AsFd for EventLoop<'l, Data> { + /// Get the underlying fd of the poller. + /// + /// This could be used to create [`Generic`] source out of the current loop + /// and inserting into some other [`EventLoop`]. + /// + /// [`Generic`]: crate::generic::Generic + fn as_fd(&self) -> BorrowedFd<'_> { + self.poller.as_fd() + } +} + #[derive(Clone, Debug)] /// The EventIterator is an `Iterator` over the events relevant to a particular source /// This type is used in the [`EventSource::before_handle_events`] methods for diff --git a/src/sys.rs b/src/sys.rs index d7a473c3..2efe6ab1 100644 --- a/src/sys.rs +++ b/src/sys.rs @@ -167,7 +167,7 @@ pub struct Token { /// source and delegate the implementations to it. pub struct Poll { /// The handle to wepoll/epoll/kqueue/... used to poll for events. - poller: Arc, + pub(crate) poller: Arc, /// The buffer of events returned by the poller. events: RefCell,