diff --git a/Cargo.lock b/Cargo.lock index 0487c2e..26905c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,7 +15,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -32,7 +32,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi", "libc", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -83,9 +83,9 @@ checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" [[package]] name = "bytes" -version = "0.5.6" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" +checksum = "e0dcbc35f504eb6fc275a6d20e4ebcda18cf50d40ba6fabff8c711fa16cb3b16" [[package]] name = "cc" @@ -180,22 +180,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "fuchsia-zircon" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -dependencies = [ - "bitflags", - "fuchsia-zircon-sys", -] - -[[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" - [[package]] name = "glob" version = "0.3.0" @@ -242,30 +226,10 @@ dependencies = [ "bindgen", "cc", "libc", - "mio", "serde", "tokio", ] -[[package]] -name = "iovec" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" -dependencies = [ - "libc", -] - -[[package]] -name = "kernel32-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -dependencies = [ - "winapi 0.2.8", - "winapi-build", -] - [[package]] name = "lazy_static" version = "1.4.0" @@ -291,7 +255,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2443d8f0478b16759158b2f66d525991a05491138bc05814ef52a250148ef4f9" dependencies = [ "cfg-if", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -311,44 +275,25 @@ checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" [[package]] name = "mio" -version = "0.6.22" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430" +checksum = "f8f1c83949125de4a582aa2da15ae6324d91cf6a58a70ea407643941ff98f558" dependencies = [ - "cfg-if", - "fuchsia-zircon", - "fuchsia-zircon-sys", - "iovec", - "kernel32-sys", "libc", "log", "miow", - "net2", - "slab", - "winapi 0.2.8", -] - -[[package]] -name = "mio-uds" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" -dependencies = [ - "iovec", - "libc", - "mio", + "ntapi", + "winapi", ] [[package]] name = "miow" -version = "0.2.1" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" +checksum = "07b88fb9795d4d36d62a012dfbf49a8f5cf12751f36d31a9dbe66d528e58979e" dependencies = [ - "kernel32-sys", - "net2", - "winapi 0.2.8", - "ws2_32-sys", + "socket2", + "winapi", ] [[package]] @@ -361,17 +306,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "net2" -version = "0.2.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ebc3ec692ed7c9a255596c67808dee269f64655d8baf7b4f0638e51ba1d6853" -dependencies = [ - "cfg-if", - "libc", - "winapi 0.3.9", -] - [[package]] name = "nom" version = "5.1.2" @@ -382,6 +316,25 @@ dependencies = [ "version_check", ] +[[package]] +name = "ntapi" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" +dependencies = [ + "winapi", +] + +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + [[package]] name = "peeking_take_while" version = "0.1.2" @@ -442,6 +395,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "redox_syscall" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + [[package]] name = "regex" version = "1.3.9" @@ -522,6 +481,18 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" +[[package]] +name = "socket2" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1fa70dc5c8104ec096f4fe7ede7a221d35ae13dcd19ba1ad9a81d2cab9a1c44" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "winapi", +] + [[package]] name = "strsim" version = "0.8.0" @@ -592,30 +563,29 @@ dependencies = [ [[package]] name = "tokio" -version = "0.2.22" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d34ca54d84bf2b5b4d7d31e901a8464f7b60ac145a284fba25ceb801f2ddccd" +checksum = "71f1b20504fd0aa9dab3ae17e8c4dd9431e5e08fd6921689f9745a4004883a17" dependencies = [ "bytes", "fnv", - "iovec", "lazy_static", "libc", "memchr", "mio", - "mio-uds", + "num_cpus", "pin-project-lite", "signal-hook-registry", "slab", "tokio-macros", - "winapi 0.3.9", + "winapi", ] [[package]] name = "tokio-macros" -version = "0.2.5" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389" +checksum = "21d30fdbb5dc2d8f91049691aa1a9d4d4ae422a21c334ce8936e5886d30c5c45" dependencies = [ "proc-macro2", "quote", @@ -670,12 +640,6 @@ dependencies = [ "libc", ] -[[package]] -name = "winapi" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" - [[package]] name = "winapi" version = "0.3.9" @@ -686,12 +650,6 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu", ] -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" - [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" @@ -704,7 +662,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -712,13 +670,3 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "ws2_32-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -dependencies = [ - "winapi 0.2.8", - "winapi-build", -] diff --git a/client/Cargo.toml b/client/Cargo.toml index 7c3ac42..480c2ca 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -tokio = { version = "0.2.22", features = ["macros", "time", "fs", "tcp", "dns", "signal"] } +tokio = { version = "0.3.2", features = ["macros", "time", "fs", "net", "signal", "rt-multi-thread"] } input = { path = "../input" } net = { path = "../net" } serde = { version = "1.0.117", features = ["derive"] } diff --git a/input/Cargo.toml b/input/Cargo.toml index 61bd9a9..fcbb0f5 100644 --- a/input/Cargo.toml +++ b/input/Cargo.toml @@ -7,8 +7,7 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -tokio = { version = "0.2.22", features = ["fs", "io-util", "io-driver", "sync", "blocking", "uds"] } -mio = "0.6.22" +tokio = { version = "0.3.2", features = ["fs", "io-util", "net", "sync", "rt"] } libc = "0.2.77" serde = { version = "1.0.117", features = ["derive"] } diff --git a/input/src/event_reader.rs b/input/src/event_reader.rs index f79bc90..8dfa9fa 100644 --- a/input/src/event_reader.rs +++ b/input/src/event_reader.rs @@ -1,19 +1,14 @@ use crate::glue::{self, input_event, libevdev}; -use mio::unix::EventedFd; use std::fs::{File, OpenOptions}; -use std::future::Future; -use std::io::Error; +use std::io::{Error, ErrorKind}; use std::mem::MaybeUninit; use std::os::unix::fs::OpenOptionsExt; use std::os::unix::io::AsRawFd; use std::path::Path; -use std::pin::Pin; -use std::task::{Context, Poll}; -use tokio::io::Registration; +use tokio::io::unix::AsyncFd; pub(crate) struct EventReader { - file: File, - registration: Registration, + file: AsyncFd, evdev: *mut libevdev, } @@ -27,8 +22,8 @@ impl EventReader { let file = OpenOptions::new() .read(true) .custom_flags(libc::O_NONBLOCK) - .open(path)?; - let registration = Registration::new(&EventedFd(&file.as_raw_fd()))?; + .open(path) + .and_then(AsyncFd::new)?; let mut evdev = MaybeUninit::uninit(); let ret = unsafe { glue::libevdev_new_from_fd(file.as_raw_fd(), evdev.as_mut_ptr()) }; @@ -46,19 +41,35 @@ impl EventReader { return Err(Error::from_raw_os_error(-ret)); } - Ok(Self { - file, - registration, - evdev, - }) + Ok(Self { file, evdev }) } pub async fn read(&mut self) -> Result { - Read { - reader: self, - polling: false, + loop { + let result = self.file.readable().await?.with_io(|| { + let mut event = MaybeUninit::uninit(); + let ret = unsafe { + glue::libevdev_next_event( + self.evdev, + glue::libevdev_read_flag_LIBEVDEV_READ_FLAG_NORMAL, + event.as_mut_ptr(), + ) + }; + + if ret < 0 { + return Err(Error::from_raw_os_error(-ret)); + } + + let event = unsafe { event.assume_init() }; + Ok(event) + }); + + match result { + Ok(event) => return Ok(event), + Err(ref err) if err.kind() == ErrorKind::WouldBlock => {} + Err(err) => return Err(err), + } } - .await } } @@ -71,43 +82,3 @@ impl Drop for EventReader { } unsafe impl Send for EventReader {} - -struct Read<'a> { - reader: &'a mut EventReader, - polling: bool, -} - -impl Future for Read<'_> { - type Output = Result; - - fn poll(mut self: Pin<&mut Self>, context: &mut Context) -> Poll { - if self.polling { - if let Poll::Pending = self.reader.registration.poll_read_ready(context)? { - return Poll::Pending; - } - } - - let mut event = MaybeUninit::uninit(); - let ret = unsafe { - glue::libevdev_next_event( - self.reader.evdev, - glue::libevdev_read_flag_LIBEVDEV_READ_FLAG_NORMAL, - event.as_mut_ptr(), - ) - }; - - if !self.polling && ret == -libc::EAGAIN { - self.polling = true; - return self.poll(context); - } - - self.polling = false; - - if ret < 0 { - return Poll::Ready(Err(Error::from_raw_os_error(-ret))); - } - - let event = unsafe { event.assume_init() }; - Poll::Ready(Ok(event)) - } -} diff --git a/input/src/event_writer.rs b/input/src/event_writer.rs index cda4b52..a3d35f4 100644 --- a/input/src/event_writer.rs +++ b/input/src/event_writer.rs @@ -1,21 +1,12 @@ use crate::event::Event; use crate::glue::{self, input_event, libevdev, libevdev_uinput}; -use mio::unix::EventedFd; -use std::fs::OpenOptions; -use std::future::Future; use std::io::{Error, ErrorKind}; use std::mem::MaybeUninit; use std::ops::RangeInclusive; -use std::os::unix::fs::OpenOptionsExt; -use std::os::unix::io::AsRawFd; -use std::pin::Pin; -use std::task::{Context, Poll}; -use tokio::io::Registration; pub struct EventWriter { evdev: *mut libevdev, uinput: *mut libevdev_uinput, - registration: Registration, } impl EventWriter { @@ -52,24 +43,7 @@ impl EventWriter { } let uinput = unsafe { uinput.assume_init() }; - let fd = unsafe { glue::libevdev_uinput_get_fd(uinput) }; - let registration = match Registration::new(&EventedFd(&fd)) { - Ok(registration) => registration, - Err(err) => { - unsafe { - glue::libevdev_uinput_destroy(uinput); - glue::libevdev_free(evdev); - }; - - return Err(err); - } - }; - - Ok(Self { - evdev, - uinput, - registration, - }) + Ok(Self { evdev, uinput }) } pub async fn write(&mut self, event: Event) -> Result<(), Error> { @@ -77,12 +51,22 @@ impl EventWriter { } pub(crate) async fn write_raw(&mut self, event: input_event) -> Result<(), Error> { - WriteRaw { - writer: self, - event, - polling: false, + // As far as tokio is concerned, the FD never becomes ready for writing, so just write it normally. + // If an error happens, it will be propagated to caller, so it shouldn't be an issue. + let ret = unsafe { + glue::libevdev_uinput_write_event( + self.uinput as *const _, + event.type_ as _, + event.code as _, + event.value, + ) + }; + + if ret < 0 { + return Err(Error::from_raw_os_error(-ret)); } - .await + + Ok(()) } } @@ -97,46 +81,6 @@ impl Drop for EventWriter { unsafe impl Send for EventWriter {} -struct WriteRaw<'a> { - writer: &'a mut EventWriter, - event: input_event, - polling: bool, -} - -impl Future for WriteRaw<'_> { - type Output = Result<(), Error>; - - fn poll(mut self: Pin<&mut Self>, context: &mut Context) -> Poll { - if self.polling { - if let Poll::Pending = self.writer.registration.poll_write_ready(context)? { - return Poll::Pending; - } - } - - let ret = unsafe { - glue::libevdev_uinput_write_event( - self.writer.uinput as *const _, - self.event.type_ as _, - self.event.code as _, - self.event.value, - ) - }; - - if !self.polling && ret == -libc::EAGAIN { - self.polling = true; - return self.poll(context); - } - - self.polling = false; - - if ret < 0 { - return Poll::Ready(Err(Error::from_raw_os_error(-ret))); - } - - Poll::Ready(Ok(())) - } -} - const TYPES: &[(u32, &[RangeInclusive])] = &[ (glue::EV_SYN, &[glue::SYN_REPORT..=glue::SYN_REPORT]), (glue::EV_REL, &[0..=glue::REL_MAX]), diff --git a/net/Cargo.toml b/net/Cargo.toml index 5473742..5c8d75f 100644 --- a/net/Cargo.toml +++ b/net/Cargo.toml @@ -10,4 +10,4 @@ edition = "2018" input = { path = "../input" } serde = { version = "1.0.117", features = ["derive"] } bincode = "1.3.1" -tokio = { version = "0.2.22", features = ["io-util"] } +tokio = { version = "0.3.2", features = ["io-util"] } diff --git a/server/Cargo.toml b/server/Cargo.toml index 85106b0..083ab24 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -tokio = { version = "0.2.22", features = ["macros", "time", "fs", "tcp", "signal"] } +tokio = { version = "0.3.2", features = ["macros", "time", "fs", "net", "signal", "rt-multi-thread"] } input = { path = "../input" } net = { path = "../net" } serde = { version = "1.0.117", features = ["derive"] } diff --git a/server/src/main.rs b/server/src/main.rs index d753350..b065d29 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -49,7 +49,7 @@ where } async fn run(listen_address: SocketAddr, switch_keys: &HashSet) -> Result { - let mut listener = TcpListener::bind(listen_address).await?; + let listener = TcpListener::bind(listen_address).await?; log::info!("Listening on {}", listen_address);