Skip to main content

InterruptEvent

Struct InterruptEvent 

Source
pub struct InterruptEvent { /* private fields */ }
Available on Unix and crate feature interruptible only.
Expand description

Event object for interrupting blocking I/O operations.

InterruptEvent provides a mechanism to cancel blocking read/write operations from another thread. It uses a pipe-based signaling mechanism internally.

§Thread Safety

This type is thread-safe and can be shared across threads using Arc<InterruptEvent>.

§Examples

Basic usage with interruptible read:

use std::sync::Arc;
use std::thread;
use std::time::Duration;
use tun_rs::{DeviceBuilder, InterruptEvent};

let device = DeviceBuilder::new()
    .ipv4("10.0.0.1", 24, None)
    .build_sync()?;

let event = Arc::new(InterruptEvent::new()?);
let event_clone = event.clone();

let reader = thread::spawn(move || {
    let mut buf = vec![0u8; 1500];
    device.recv_intr(&mut buf, &event_clone)
});

// Give the reader time to start blocking
thread::sleep(Duration::from_millis(100));

// Trigger the interrupt
event.trigger()?;

match reader.join().unwrap() {
    Ok(n) => println!("Read {} bytes", n),
    Err(e) if e.kind() == std::io::ErrorKind::Interrupted => {
        println!("Successfully interrupted!");
    }
    Err(e) => eprintln!("Error: {}", e),
}

Using with a timeout:

use std::time::Duration;
use tun_rs::{DeviceBuilder, InterruptEvent};

let device = DeviceBuilder::new()
    .ipv4("10.0.0.1", 24, None)
    .build_sync()?;

let event = InterruptEvent::new()?;
let mut buf = vec![0u8; 1500];

// Will return an error if no data arrives within 5 seconds
match device.recv_intr_timeout(&mut buf, &event, Some(Duration::from_secs(5))) {
    Ok(n) => println!("Read {} bytes", n),
    Err(e) if e.kind() == std::io::ErrorKind::TimedOut => {
        println!("Timed out waiting for data");
    }
    Err(e) if e.kind() == std::io::ErrorKind::Interrupted => {
        println!("Operation was interrupted");
    }
    Err(e) => eprintln!("Error: {}", e),
}

§Implementation Details

  • Uses a Unix pipe for signaling
  • Both read and write ends are set to non-blocking mode
  • State is protected by a mutex to prevent race conditions
  • Once triggered, the event remains triggered until reset

Implementations§

Source§

impl InterruptEvent

Source

pub fn new() -> Result<Self>

Creates a new InterruptEvent.

This allocates a Unix pipe for signaling and sets both ends to non-blocking mode.

§Errors

Returns an error if:

  • The pipe creation fails (e.g., out of file descriptors)
  • Setting non-blocking mode fails
§Example
use tun_rs::InterruptEvent;

let event = InterruptEvent::new()?;
Source

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

Triggers the interrupt event with value 1.

This will cause any blocking I/O operations waiting on this event to return with ErrorKind::Interrupted.

Calling trigger() multiple times before reset() has no additional effect - the event remains triggered.

§Errors

Returns an error if writing to the internal pipe fails, though this is rare in practice (pipe write errors are usually WouldBlock, which is handled).

§Example
use std::sync::Arc;
use std::thread;
use tun_rs::{DeviceBuilder, InterruptEvent};

let event = Arc::new(InterruptEvent::new()?);
let event_clone = event.clone();

thread::spawn(move || {
    // ... blocking I/O with event_clone ...
});

// Interrupt the operation
event.trigger()?;
Source

pub fn trigger_value(&self, val: i32) -> Result<()>

Triggers the interrupt event with a specific value.

Similar to trigger(), but allows specifying a custom value that can be retrieved with value().

§Arguments
  • val - The value to store (must be non-zero)
§Errors
  • Returns ErrorKind::InvalidInput if val is 0
  • Returns an error if writing to the pipe fails
§Example
use tun_rs::InterruptEvent;

let event = InterruptEvent::new()?;

// Trigger with a custom value (e.g., signal number)
event.trigger_value(15)?; // SIGTERM

// Later, check what value was used
assert_eq!(event.value(), 15);
Source

pub fn is_trigger(&self) -> bool

Checks if the event has been triggered.

Returns true if the event is currently in the triggered state (value is non-zero).

§Example
use tun_rs::InterruptEvent;

let event = InterruptEvent::new()?;
assert!(!event.is_trigger());

event.trigger()?;
assert!(event.is_trigger());

event.reset()?;
assert!(!event.is_trigger());
Source

pub fn value(&self) -> i32

Returns the current trigger value.

Returns 0 if the event is not triggered, or the value passed to trigger_value() if triggered.

§Example
use tun_rs::InterruptEvent;

let event = InterruptEvent::new()?;
assert_eq!(event.value(), 0);

event.trigger_value(42)?;
assert_eq!(event.value(), 42);
Source

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

Resets the event to the non-triggered state.

This drains any pending data from the internal pipe and sets the state back to 0. After calling reset(), the event can be triggered again.

§Errors

Returns an error if reading from the pipe fails (other than WouldBlock).

§Example
use tun_rs::InterruptEvent;

let event = InterruptEvent::new()?;

event.trigger()?;
assert!(event.is_trigger());

event.reset()?;
assert!(!event.is_trigger());

// Can trigger again after reset
event.trigger()?;
assert!(event.is_trigger());

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.