EventLoop

Struct EventLoop 

Source
pub struct EventLoop { /* private fields */ }
Expand description

The main event loop structure for registering I/O sources and handling events.

EventLoop is the primary interface for Mill-IO, providing a simple API for:

  • Registering I/O sources (sockets, files, etc.) with event handlers
  • Starting and stopping the event loop
  • Managing the underlying reactor and thread pool

The event loop uses a reactor pattern internally, where I/O events are detected by the polling mechanism and dispatched to registered handlers via a thread pool.

§Examples

Basic usage with default configuration:

use mill_io::{EventLoop, EventHandler};
use mio::{net::TcpListener, Interest, Token};
use std::net::SocketAddr;

struct MyHandler;
impl EventHandler for MyHandler {
    fn handle_event(&self, event: &mio::event::Event) {
        println!("Event received: {:?}", event);
    }
}

let event_loop = EventLoop::default();
let addr: SocketAddr = "127.0.0.1:0".parse()?;
let mut listener = TcpListener::bind(addr)?;
 
event_loop.register(&mut listener, Token(0), Interest::READABLE, MyHandler)?;
event_loop.run()?; // Blocks until stopped

Custom configuration:

use mill_io::EventLoop;

let event_loop = EventLoop::new(
    4,      // 4 worker threads
    512,    // Buffer for 512 events per poll
    50      // 50ms poll timeout
)?;

Implementations§

Source§

impl EventLoop

Source

pub fn new( workers: usize, events_capacity: usize, poll_timeout_ms: u64, ) -> Result<Self>

Creates a new EventLoop with custom configuration.

§Arguments
  • workers - Number of worker threads in the thread pool (recommended: num_cpus)
  • events_capacity - Maximum number of events to poll per iteration (typical: 512-4096)
  • poll_timeout_ms - Poll timeout in milliseconds (balance between latency and CPU usage)
§Errors

Returns an error if:

  • The reactor cannot be initialized
  • The thread pool cannot be created
  • The polling mechanism fails to initialize
§Examples
use mill_io::EventLoop;

// High-throughput configuration
let event_loop = EventLoop::new(8, 2048, 50)?;

// Low-latency configuration
let event_loop = EventLoop::new(2, 256, 10)?;
Source

pub fn register<H, S>( &self, source: &mut S, token: Token, interests: Interest, handler: H, ) -> Result<()>
where H: EventHandler + Send + Sync + 'static, S: Source + ?Sized,

Registers an I/O source with the event loop and associates it with a handler.

This method registers an I/O source (such as a TCP listener or socket) with the event loop. When events occur on the source, the provided handler will be invoked on a worker thread.

§Arguments
§Errors

Returns an error if:

  • The token is already in use
  • The source cannot be registered with the underlying poll mechanism
  • The handler registry is full
§Examples
use mill_io::{EventLoop, EventHandler};
use mio::{net::TcpListener, Interest, Token};
use std::net::SocketAddr;

struct ConnectionHandler;
impl EventHandler for ConnectionHandler {
    fn handle_event(&self, event: &mio::event::Event) {
        // Handle new connections
    }
}

let event_loop = EventLoop::default();
let addr: SocketAddr = "0.0.0.0:8080".parse()?;
let mut listener = TcpListener::bind(addr)?;

event_loop.register(
    &mut listener,
    Token(0),
    Interest::READABLE,
    ConnectionHandler
)?;
Source

pub fn deregister<S>(&self, source: &mut S, token: Token) -> Result<()>
where S: Source + ?Sized,

Deregisters an I/O source from the event loop.

Removes the source from the polling mechanism and clears its associated handler. After deregistration, no more events will be delivered for this source.

§Arguments
  • source - The I/O source to deregister
  • token - Token associated with the source during registration
§Errors

Returns an error if:

  • The source is not currently registered
  • The deregistration fails at the OS level
  • The token is invalid
§Examples
use mill_io::{EventLoop, EventHandler};
use mio::{net::TcpListener, Interest, Token};
use std::net::SocketAddr;

struct Handler;
impl EventHandler for Handler {
    fn handle_event(&self, _: &mio::event::Event) {}
}

let event_loop = EventLoop::default();
let addr: SocketAddr = "127.0.0.1:0".parse()?;
let mut listener = TcpListener::bind(addr)?;
let token = Token(0);

// Register
event_loop.register(&mut listener, token, Interest::READABLE, Handler)?;

// Later, deregister
event_loop.deregister(&mut listener, token)?;
Source

pub fn run(&self) -> Result<()>

Runs the event loop, blocking the current thread and dispatching events.

This method starts the reactor’s main loop, which will:

  1. Poll for I/O events using the configured timeout
  2. Dispatch events to registered handlers via the thread pool
  3. Continue until stop() is called or an error occurs

The method blocks the calling thread and will only return when the event loop is stopped or encounters a fatal error.

§Errors

Returns an error if:

  • The polling mechanism fails
  • The thread pool encounters a fatal error
  • System resources are exhausted
§Ok::<(), Box>(())
Source

pub fn stop(&self)

Signals the event loop to stop gracefully.

This method initiates a graceful shutdown of the event loop. It sends a shutdown signal to the reactor, which will cause the main loop to exit after finishing the current polling cycle.

This method is non-blocking and returns immediately. The actual shutdown happens asynchronously, and run() will return once the shutdown is complete.

§Thread Safety

This method is thread-safe and can be called from any thread, making it suitable for use in signal handlers or from other threads.

§Examples
use mill_io::EventLoop;
use std::thread;
use std::sync::Arc;

let event_loop = Arc::new(EventLoop::default());
let event_loop_clone = Arc::clone(&event_loop);

// Start event loop in background thread
let handle = thread::spawn(move || {
    // In a real application, you would handle the result properly
    let _ = event_loop_clone.run();
});

// Stop after some time
thread::sleep(std::time::Duration::from_secs(1));
event_loop.stop();

// Wait for shutdown
let _ = handle.join();

Trait Implementations§

Source§

impl Default for EventLoop

Source§

fn default() -> Self

Creates a new EventLoop with default configuration.

The default configuration uses:

§Panics

Panics if the reactor cannot be initialized with default settings.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.