Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Non-blocking polling of events #44

Open
svenvdvoort opened this issue Nov 15, 2020 · 2 comments
Open

Non-blocking polling of events #44

svenvdvoort opened this issue Nov 15, 2020 · 2 comments

Comments

@svenvdvoort
Copy link

Hello,

Thank you for providing us with this wonderful library!
A missing feature of this library to me is the ability to do a non-blocking poll on the LineEventHandle struct.
Currently every method (.get_event(), .next() and .read_event()) is blocking.
Ideally we would have a sort of .has_event() -> bool function available to check whether there is an event available to process. This way we would take maximum advantage of the queue-like architecture of the new GPIO character device ABI.

Please let me know what you think of this suggestion.

Cheers,
Sven.

@ryankurte
Copy link

hmm is this for async or sync use? in the async case would .poll_next() per the standard stream implementation work?

in the blocking case this seems like it could be useful, perhaps a .try_get_event() -> Option<bool> or similar?

@MarceloAlm
Copy link

Hi,
I do not know how @svenvdvoort plans to use, but I am searching to someway impletent a timeout for the .read_event():
a process starts a request for a GPIO interaction from the user and, if there is no input for a Duration, the code continues with a timeout.
I tried this with select!, but the result was very unstable.

pub async fn confirma_giro(&self, timeout: Duration) -> LeitorResult<()> {
    let _handle_confirm = match self.gpio_confirm.events(
        gpio_cdev::LineRequestFlags::INPUT,
        gpio_cdev::EventRequestFlags::FALLING_EDGE,
        &(self.sentido.to_string() + "_GPIO_CONFIRM"),
    ) {
        Ok(value) => value,
        Err(e) => return Err(LeitorError::GPIO { kind: e }),
    };

    let timeout = async {
        thread::sleep(timeout);
    };

    let giro = Box::pin(async {
        // *** Aguarda o sinal chegar ao estado desligado
        match _handle_confirm.get_value() {
            Ok(sinal) => {
                if sinal != SIGNAL_OFF {
                    return Err(LeitorError::ConfirmaGiroIncorreto);
                }
            }
            Err(e) => return Err(LeitorError::GPIO { kind: e }),
        };

        if let Ok(_e) = _handle_confirm.get_event() {
            thread::sleep(Duration::from_millis(100));

            if let Ok(sinal) = _handle_confirm.get_value() {
                if sinal == SIGNAL_ON {
                    return Ok(());
                }
            }
            return Err(LeitorError::SinalInstavel);
        }
        Err(LeitorError::ConfirmaGiroIncorreto)
    });

    select! {
        resp = giro.fuse() => resp,
        _out = timeout.fuse() => Err(LeitorError::TimeOut),
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants