Struct esp_idf_svc::eventloop::EspEventLoop
source · pub struct EspEventLoop<T>(/* private fields */)
where
T: EspEventLoopType;
Implementations§
source§impl<T> EspEventLoop<T>where
T: EspEventLoopType,
impl<T> EspEventLoop<T>where
T: EspEventLoopType,
pub fn subscribe_async<D>(&self) -> Result<EspAsyncSubscription<D, T>, EspError>where
D: EspEventDeserializer,
pub fn subscribe<D, F>(
&self,
callback: F,
) -> Result<EspSubscription<'static, T>, EspError>where
D: EspEventDeserializer,
F: for<'a> FnMut(D::Data<'a>) + Send + 'static,
sourcepub unsafe fn subscribe_nonstatic<'a, D, F>(
&self,
callback: F,
) -> Result<EspSubscription<'a, T>, EspError>where
D: EspEventDeserializer,
F: for<'d> FnMut(D::Data<'d>) + Send + 'a,
pub unsafe fn subscribe_nonstatic<'a, D, F>(
&self,
callback: F,
) -> Result<EspSubscription<'a, T>, EspError>where
D: EspEventDeserializer,
F: for<'d> FnMut(D::Data<'d>) + Send + 'a,
§Safety
This method - in contrast to method subscribe
- allows the user to pass
a non-static callback/closure. This enables users to borrow
- in the closure - variables that live on the stack - or more generally - in the same scope where the service is created.
HOWEVER: care should be taken NOT to call core::mem::forget()
on the service,
as that would immediately lead to an UB (crash).
Also note that forgetting the service might happen with Rc
and Arc
when circular references are introduced: https://github.com/rust-lang/rust/issues/24456
The reason is that the closure is actually sent to a hidden ESP IDF thread. This means that if the service is forgotten, Rust is free to e.g. unwind the stack and the closure now owned by this other thread will end up with references to variables that no longer exist.
The destructor of the service takes care - prior to the service being dropped and e.g. the stack being unwind - to remove the closure from the hidden thread and destroy it. Unfortunately, when the service is forgotten, the un-subscription does not happen and invalid references are left dangling.
This “local borrowing” will only be possible to express in a safe way once/if !Leak
types
are introduced to Rust (i.e. the impossibility to “forget” a type and thus not call its destructor).
pub async fn post_async<S>(&self, payload: &S::Data<'_>) -> Result<(), EspError>where
S: EspEventSerializer,
pub fn post<S>(
&self,
payload: &S::Data<'_>,
timeout: TickType_t,
) -> Result<bool, EspError>where
S: EspEventSerializer,
source§impl<T> EspEventLoop<User<T>>
impl<T> EspEventLoop<User<T>>
pub fn spin(&mut self, timeout: TickType_t) -> Result<(), EspError>
source§impl EspEventLoop<User<Background>>
impl EspEventLoop<User<Background>>
pub fn new(conf: &BackgroundLoopConfiguration<'_>) -> Result<Self, EspError>
source§impl EspEventLoop<User<Explicit>>
impl EspEventLoop<User<Explicit>>
pub fn new(conf: &ExplicitLoopConfiguration) -> Result<Self, EspError>
Trait Implementations§
source§impl<T> Clone for EspEventLoop<T>where
T: EspEventLoopType,
impl<T> Clone for EspEventLoop<T>where
T: EspEventLoopType,
source§impl<T> Debug for EspEventLoop<T>where
T: EspEventLoopType + Debug,
impl<T> Debug for EspEventLoop<T>where
T: EspEventLoopType + Debug,
source§impl<T> RawHandle for EspEventLoop<User<T>>
impl<T> RawHandle for EspEventLoop<User<T>>
impl<T> Send for EspEventLoop<T>where
T: EspEventLoopType + Send,
impl<T> Sync for EspEventLoop<T>where
T: EspEventLoopType + Sync,
Auto Trait Implementations§
impl<T> Freeze for EspEventLoop<T>
impl<T> RefUnwindSafe for EspEventLoop<T>where
T: RefUnwindSafe,
impl<T> Unpin for EspEventLoop<T>
impl<T> UnwindSafe for EspEventLoop<T>where
T: RefUnwindSafe,
Blanket Implementations§
§impl<T> Any for Twhere
T: 'static + ?Sized,
impl<T> Any for Twhere
T: 'static + ?Sized,
§impl<T> Borrow<T> for Twhere
T: ?Sized,
impl<T> Borrow<T> for Twhere
T: ?Sized,
§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§default unsafe fn clone_to_uninit(&self, dst: *mut T)
default unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)