releases-comm-central/third_party/rust/runloop
Rob Lemley 94f8f9398c Bug 1860654 - Add vendored Rust deps. rs=me
This is a reproducible commit. Running mach tb-rust vendor again
with mozilla-central and comm-central on the same head revs will
produce the same output.

https://hg.mozilla.org/mozilla-central/rev/55cd203304b8d5343dd941d772085dc25fd278c4
https://hg.mozilla.org/comm-central/rev/8a0750b85f6d85fbf5c2e17a29fbc8112112c374
2023-12-12 14:05:09 -05:00
..
src Bug 1860654 - Add vendored Rust deps. rs=me 2023-12-12 14:05:09 -05:00
.cargo-checksum.json Bug 1860654 - Add vendored Rust deps. rs=me 2023-12-12 14:05:09 -05:00
Cargo.toml Bug 1860654 - Add vendored Rust deps. rs=me 2023-12-12 14:05:09 -05:00
LICENSE Bug 1860654 - Add vendored Rust deps. rs=me 2023-12-12 14:05:09 -05:00
README.md Bug 1860654 - Add vendored Rust deps. rs=me 2023-12-12 14:05:09 -05:00
rustfmt.toml Bug 1860654 - Add vendored Rust deps. rs=me 2023-12-12 14:05:09 -05:00

README.md

runloop Crates.io Build Status License

This crate provides a cancelable RunLoop to simplify writing non-blocking polling threads.

Usage

The closure passed to RunLoop::new() or RunLoop::new_with_timeout() will be called once and is executed in the newly spawned thread. It should periodically check, via the given callback argument named alive in the below examples, whether the runloop was requested to terminate.

RunLoop::alive() allows the owning thread to check whether the runloop is still alive. This can be useful for debugging (e.g. assertions) or early returns on failure in the passed closure.

RunLoop::cancel() will request the runloop to terminate. If the runloop is still active it will join the thread and block. If the runloop already terminated on its own this will be a no-op.

Example: An endless runloop

A runloop does not have to terminate on its own, it can wait until the cancel() method is called.

// This runloop runs until we stop it.
let rloop = RunLoop::new(|alive| {
    while alive() { /* endless loop */ }
})?;

// Loop a few times.
thread::sleep_ms(500);
assert!(rloop.alive());

// This will cause `alive()` to return false
// and block until the thread was joined.
rloop.cancel();

Example: A runloop with a timeout

Creating a runloop via new_with_timeout() ensures that alive() returns false after the given duration.

// This runloop will time out after 10ms.
let rloop = RunLoop::new_with_timeout(|alive| {
    while alive() { /* endless loop */ }
}, 10)?;

// Wait for the timeout.
while rloop.alive() { /* loop */ }

// This won't block anymore, it's a no-op.
// The runloop has already terminated.
rloop.cancel();

Example: A runloop with channels

As a runloop will run the given closure in a newly spawned thread it requires channels and similar utilities to communicate back to the owning thread.

let (tx, rx) = channel();

// This runloop will send a lot of numbers.
let rloop = RunLoop::new(move |alive| {
    let mut counter = 0u64;
    while alive() {
        tx.send(counter).unwrap();
        counter += 1;
    }
})?;

// Wait until we receive a specific number.
while rx.recv().unwrap() < 50 { /* loop */ }

// We've seen enough.
rloop.cancel();

License

runloop is distributed under the terms of the Mozilla Public License, v. 2.0.

See LICENSE for details.