NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
crates.io · #1151 most downloaded on crates.io
A callback-based event loop
Last release 6 days ago
01 Oct 2026
Ships fairly regularly
a new release about every 3 months
Most releases are documented
notes for 41 of 47 stable releases
2 versions withdrawn
withdrawn after publishing
8 years old
49 releases · first in 2018
Unregister source when Async is dropped.
Async is dropped.pin-utils dependency with std::pin::pin!.Add StreamSource to adapt an async Stream to an EventSource .
StreamSource to adapt an async Stream to an EventSource. (#228)One column per quarter.
Add WeakLoopHandle .
WeakLoopHandle. (#216)Simplify the way timeouts are calculated for Poll .
Use the tracing crate for logging instead of the log crate.
Improve the MSRV policy. Now, changes to the MSRV are no longer considered breaking changes, improving stability.
nix from the public API. This replaces Signal with a home-grownSignal enum and siginfo with a structure that provides most of its fields. (#182)thiserror usage with manual implementations. This may cause the API to be slightly different in some cases, but should mostly be identical. (#186)nix to v0.29. (#188)Bump nix to v0.28 . As nix is exposed in the public API, this is a breaking change.
calloop is now supported for Windows.
Token and RegistrationToken are now invalidated when the event source they represent is removed from the event loop.
Token and RegistrationToken are now invalidated when the event source they represent is removed from the event loop.AsRawFd and AsFd for EventLoop<'l, Data>Fix an issue where the Generic event source would try to unregister its contents from the event loop after a failed registration.
Generic event source would try to unregister its contents from the event loop
after a failed registration.EventLoop would panic when processing a PostAction::Remove from an event source
with subsources.Fix EventSource::before_handle_events() being erroneously give an iterator over synthetic events instead of real events
EventSource::before_handle_events() being erroneously give an iterator over synthetic events instead of real eventsMake signals an optional feature under the signals features.
signals features.nix crate with standard library I/O errors and the rustix crate.pre_run and post_run on EventSource have been replaced with before_sleep and before_handle_events, respectively.
These are now opt-in through the NEEDS_EXTRA_LIFECYCLE_EVENTS associated constant, and occur at slightly different times to
the methods they are replacing. This allows greater compatibility with Wayland based event sources.Fixed a crash due to double borrow when handling pre/post run hooks
Durations are passed to Timer::from_duration.sys module with the polling crate.block_on feature enabled, the EventLoop method now has a block_on method that runs a future to completion on the event loop.TransientSource is now an opaque type. It provides API methods for removing or
replacing the wrapped source. This mitigates a potential leak of registration data if the
TransientSource is replaced by direct assignment in a parent source.Timer::current_deadline returns Option<Instant>, so that it can return None
in the event of an overflow.AsFd instead of AsRawFd/RawFd.Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
The return value of LoopHandle::insert_idle no longer borrows the LoopHandle.
LoopHandle::insert_idle no longer borrows the LoopHandle.The Channel now has proxy methods for Receiver::recv and Receiver::try_recv
Channel now has proxy methods for Receiver::recv and Receiver::try_recvtarget_os = "android"Breaking: Calloop's internal storage is now backed by a slotmap. As a result the RegistrationToken is now Copy+Clone, and the low-level registration A
slotmap. As a result the
RegistrationToken is now Copy+Clone, and the low-level registration API of Poll is
altered in a breaking way. MSRV is bumped to 1.49.generic::Fd adapter is removed, as since that rust version RawFd implements
AsRawFd, allowing it to be used directly in Generic.EventSource trait has a new associated type Error. This determines the type
of the error variant returned by EventSource::process_events(). It must be convertible into
Box<dyn std::error::Error + Sync + Send>.Error type on the EventSource trait.calloop::Error) instead of
std::io::Error as the error variants of their returned results.Timer event source has been completely reworked and is now directly driven by
calloop polling mechanism instead of a background thread. Timer multiplexing is now handled by
creating multiple Timers, and self-repeating timers is handled by the return value of the
associated event callback.EventLoop::try_new_high_precision() for sub-millisecond accuracy in the event loopPingSource event source now uses an eventfd instead of a pipe on Linux.Nothing published for this version
Introduce the methods pre_run() and post_run() to EventSource, allowing event sources to do preparations before entering a run/dispatch session, and c
pre_run() and post_run() to EventSource, allowing event sources
to do preparations before entering a run/dispatch session, and cleanup afterwards. They have default
implementations doing nothing.- Update nix dependency to 0.22
nix dependency to 0.22The futures module now has a proper error type for Scheduler::schedule()
futures module now has a proper error type for Scheduler::schedule()EventSource::process_events() is now io::Result<PostAction> allowing
the sources to directly request the event loop to reregister/disable/destroy them.Token creation mechanism is now driven by a TokenFactory, that
dynamically generates new unique token for sub-sources. Following for this
if you create a new event source that is not built by composing the ones
provided by calloop, you need to check if the Token provided to
process_events is the same as the one you created when (re)registering
your source. If you delegate process_events to a sub-source, you no longer
need to check the sub_id before, instead the source you are delegating to
is responsible to to this check.The Dispatcher type no longer has the closure type within its type parameters, but instead now has an explicit lifetime parameter, as well as the sour
Dispatcher type no longer has the closure type within its type parameters,
but instead now has an explicit lifetime parameter, as well as the source type S
and the event loop Data type. This allows the type to be explicitly named and
stored into an other struct.Token now has a method with_sub_id() that returns a copy of the token
but with the given sub_id.EventLoop::run() now accepts Into >, like EventLoop::dispatch()
EventLoop::run() now accepts Into<Option<Duration>>, like EventLoop::dispatch()Ping event source now automatically disables itself when its sending end is
dropped, preventing to always be considered readable (which caused a busy-loop).
This also fixes a similar behavior of Executor and Channel, which use Ping
internally.Nothing published for this version
The return type for LoopHandle::insert_source was renamed as RegistrationToken and can be used in {enable,disable,update,remove,kill} just like before
LoopHandle::insert_source was renamed as
RegistrationToken and can be used in {enable,disable,update,remove,kill}
just like before.'static event sources and callbacks, so they can hold references
to other values.
LoopHandle::with_source was removed. To achieve the same behaviour, use a
Dispatcher and register it via the LoopHandle::register_dispatcher. The
EventSource will be available using Dispatcher::as_source_{ref,mut}.LoopHandle::remove doesn't return the event source any more. To achieve
the same behaviour, use a Dispatcher and register it via the
LoopHandle::register_dispatcher. After removing the EventSource with
LoopHandle::remove, you will be able to call
Dispatcher::into_source_inner to get ownership of the EventSource.LoopHandle::register_dispatcher can be used in place of
LoopHandle::insert_source when the source needs to be accessed after
its insertion in the loop.Interest is changed into a struct to allow empty interest queriesexecutor cargo
feature.LoopHandle::adapt_io method for creating Async<F> adapters to
adapt IO objects for async use, powered by the event loop.Channel now signals readinnes after the event has actually been sent, fixing a race condition where the event loop would try to read the message befor
Fix double borrow during dispatch when some event source is getting removed
Add support for openbsd, netbsd, and dragonfly.
openbsd, netbsd, and dragonfly.InsertError<E> now implements std::error::Error.'static dispatch Data. Data is passed as an argument to the
callbacks while dispatching. This change allows defining Data types which
can hold references to other values.dispatch now will retry on EINTR.Update the README and keywords for crates.io
Introduce LoopHandle::kill to allow dropping a source from within its callback
LoopHandle::kill to allow dropping a source from within its callbackBreaking Change: Significantly rework the calloop API, notably:
mio dependencycalloop API, notably:
EventLoopPing event sourcechannel::Channel is now Send, allowing you to create a channel in one thread and sending its receiving end to an other thread for event loop insertion
channel::Channel is now Send, allowing you to create a channel in one thread and sending
its receiving end to an other thread for event loop insertion.- Update mio to 0.7
mio to 0.7Breaking Update mio dependency to 0.7.0-alpha.1. The API of calloop for custom event sources significantly changed, and the channel and timer event so
nix dependency to 0.17mio dependency to 0.7.0-alpha.1. The API of calloop for custom
event sources significantly changed, and the channel and timer event sources are now
implemented in calloop rather than pulled from mio-extras.- Update nix dependency to 0.14
nix dependency to 0.14- Update mio dependency - Update nix dependency
mio dependencynix dependencyImplement Debug for InsertError.
Debug for InsertError.Disable the sources::signal module on FreeBSD so that the library can be built on this platform.
sources::signal module on FreeBSD so that the library can be built on this
platform.Breaking Use mio-extras instead of mio-more which is not maintained.
mio-extras instead of mio-more which is not maintained.mio rather than selectively re-exporting some of its types.Generic to retrive the inner Rc and construct it from an RcLoopHandle::insert_source now allows to retrieve the source on error.Fix the contents of EventedRawFd which was erroneously not public.
EventedRawFd which was erroneously not public.introduce EventedRawFd as a special case for the Generic event source, for when you really have to manipulate raw fds
EventedRawFd as a special case for the Generic event source, for when
you really have to manipulate raw fdsFixed a bug where inserting an event source from within a callback caused a panic.
Data type parameter from Source and Idle, for
improved ergonomics.Introduce an EventLoop::run method, as well as the LoopSignal handle allowing to wakeup or stop the event loop from anywhere.
EventLoop::run method, as well as the LoopSignal handle allowing to
wakeup or stop the event loop from anywhere.[breaking] Add a &mut shared_data argument to EventLoop::dispatch(..) to share data between callbacks.
&mut shared_data argument to EventLoop::dispatch(..) to share data
between callbacks.Generic event source for wrapping arbitrary Evented types
Generic event source for wrapping arbitrary Evented typesInitial release
Initial release
Your coding agent can read these notes before it upgrades. Set up the MCP server →