Mio: How to cancel different event loop?


#1

I’m writing a client of our home made protocol. My client has to send request and wait response. I don’t want to wait indefinitely so I want to wait a specific time or I want to be able to cancel the request if needed to unblock my client (if I want to close the application for example).

To do that, I’m using mio to be able to have events. Here is a small example of what it looks like. The problem comes with mio::Registration, you can’t register the same object to two differents poll, even if the previous poll doesn’t exist anymore. Even if I use poll.deregister(…). I found this : https://github.com/carllerche/mio/issues/506 Maybe it makes sense for channel/socket, but does it here ? The following example crashs on

poll.register(registration, Token(1), Ready::readable(), PollOpt::edge()).unwrap();

for the second call to wait_response. The error is : error: StringError(“registration handle associated with another Poll instance”)

I don’t want to create a different Registration/SetReadiness for each call. So how can I cancel different loop with the same registration object ?

Here is the code example :

extern crate mio;
extern crate mio_extras;
use std::time::Duration;
use mio::{Ready, Events, Registration, Poll, PollOpt, Token, SetReadiness};
use mio_extras::timer::Timer;

fn main() {
let (registration, set_readiness) = Registration::new2();
let client = Client{};
client.send_req1(Duration::from_secs(2), &registration).unwrap();
client.send_req2(Duration::from_secs(2), &registration).unwrap();
}

struct Client;

impl Client {
pub fn send_req1(&self, timeout: Duration, registration: &Registration) -> Result<(), ()> {
//Send req
self.wait_response(timeout, registration)?;
Ok(())
}

pub fn send_req2(&self, timeout: Duration, registration: &Registration) -> Result<(), ()> {
    //Send req2
    self.wait_response(timeout, registration)?;
    Ok(())
}

fn wait_response(&self, timeout: Duration, registration: &Registration) -> Result<(), ()> {
    let poll = Poll::new().unwrap();

    let mut timer = Timer::<()>::default();
    timer.set_timeout(timeout, ());

    poll.register(&timer, Token(0), Ready::readable(), PollOpt::edge()).unwrap();
    poll.register(registration, Token(1), Ready::readable(), PollOpt::edge()).unwrap();

    // Create storage for events
    let mut events = Events::with_capacity(1024);

    loop {
        poll.poll(&mut events, None).unwrap();

        for event in events.iter() {
            match event.token() {
                Token(0) => {
                    println!("TIMEOUT");
                    return Ok(());
                },
                Token(1) => {
                    println!("CANCEL");
                    return Ok(());
                },
                _ => {unreachable!()}
            }
        }
    }
}

}