summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxVerevkin <maxxverrr@gmail.com>2023-03-31 21:06:35 +0300
committerMaxVerevkin <maxxverrr@gmail.com>2023-03-31 21:06:35 +0300
commit91381b2c1bb0ee5cb4755ac80769a7838874bbe6 (patch)
tree3d22527c78d6bcdb8b6e77dddcea02e81a36c504
parent4d23983c1f048c2301bf464ba949d578b98d4426 (diff)
downloadi3bar-mango-91381b2c1bb0ee5cb4755ac80769a7838874bbe6.tar.gz
poll() instead of tokio
-rw-r--r--Cargo.lock246
-rw-r--r--Cargo.toml13
-rw-r--r--src/main.rs76
-rw-r--r--src/state.rs32
-rw-r--r--src/status_cmd.rs56
5 files changed, 134 insertions, 289 deletions
diff --git a/Cargo.lock b/Cargo.lock
index c17aec9..66a050d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -21,12 +21,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
-name = "bytes"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
-
-[[package]]
name = "cairo-rs"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -76,40 +70,25 @@ dependencies = [
]
[[package]]
-name = "futures"
-version = "0.3.27"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "531ac96c6ff5fd7c62263c5e3c67a603af4fcaee2e1a0ae5565ba3a11e69e549"
-dependencies = [
- "futures-channel",
- "futures-core",
- "futures-io",
- "futures-sink",
- "futures-task",
- "futures-util",
-]
-
-[[package]]
name = "futures-channel"
-version = "0.3.27"
+version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "164713a5a0dcc3e7b4b1ed7d3b433cabc18025386f9339346e8daf15963cf7ac"
+checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2"
dependencies = [
"futures-core",
- "futures-sink",
]
[[package]]
name = "futures-core"
-version = "0.3.27"
+version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "86d7a0c1aa76363dac491de0ee99faf6941128376f1cf96f07db7603b7de69dd"
+checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
[[package]]
name = "futures-executor"
-version = "0.3.27"
+version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1997dd9df74cdac935c76252744c1ed5794fac083242ea4fe77ef3ed60ba0f83"
+checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0"
dependencies = [
"futures-core",
"futures-task",
@@ -118,42 +97,35 @@ dependencies = [
[[package]]
name = "futures-io"
-version = "0.3.27"
+version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89d422fa3cbe3b40dca574ab087abb5bc98258ea57eea3fd6f1fa7162c778b91"
+checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964"
[[package]]
name = "futures-macro"
-version = "0.3.27"
+version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3eb14ed937631bd8b8b8977f2c198443447a8355b6e3ca599f38c975e5a963b6"
+checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
dependencies = [
"proc-macro2",
"quote",
- "syn 1.0.109",
+ "syn 2.0.12",
]
[[package]]
-name = "futures-sink"
-version = "0.3.27"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec93083a4aecafb2a80a885c9de1f0ccae9dbd32c2bb54b0c3a65690e0b8d2f2"
-
-[[package]]
name = "futures-task"
-version = "0.3.27"
+version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd65540d33b37b16542a0438c12e6aeead10d4ac5d05bd3f805b8f35ab592879"
+checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65"
[[package]]
name = "futures-util"
-version = "0.3.27"
+version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ef6b17e481503ec85211fed8f39d1970f128935ca1f814cd32ac4a6842e84ab"
+checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533"
dependencies = [
"futures-core",
"futures-macro",
- "futures-sink",
"futures-task",
"pin-project-lite",
"pin-utils",
@@ -269,15 +241,13 @@ name = "i3bar-river"
version = "0.1.0"
dependencies = [
"anyhow",
- "futures",
"memchr",
+ "nix",
"pangocairo",
"serde",
"serde_json",
"signal-hook",
- "signal-hook-tokio",
"thiserror",
- "tokio",
"toml",
"wayrs-client",
"wayrs-protocols",
@@ -307,15 +277,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
[[package]]
-name = "log"
-version = "0.4.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -346,18 +307,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
-name = "mio"
-version = "0.8.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9"
-dependencies = [
- "libc",
- "log",
- "wasi",
- "windows-sys",
-]
-
-[[package]]
name = "nix"
version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -367,6 +316,7 @@ dependencies = [
"cfg-if",
"libc",
"memoffset",
+ "pin-utils",
"static_assertions",
]
@@ -493,9 +443,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
-version = "1.0.53"
+version = "1.0.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba466839c78239c09faf015484e5cc04860f88242cff4d03eb038f04b4699b73"
+checksum = "e472a104799c74b514a57226160104aa483546de37e839ec50e3c2e41dd87534"
dependencies = [
"unicode-ident",
]
@@ -526,29 +476,29 @@ checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
[[package]]
name = "serde"
-version = "1.0.158"
+version = "1.0.159"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "771d4d9c4163ee138805e12c710dd365e4f44be8be0503cb1bb9eb989425d9c9"
+checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.158"
+version = "1.0.159"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e801c1712f48475582b7696ac71e0ca34ebb30e09338425384269d9717c62cad"
+checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.10",
+ "syn 2.0.12",
]
[[package]]
name = "serde_json"
-version = "1.0.94"
+version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea"
+checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744"
dependencies = [
"itoa",
"ryu",
@@ -593,18 +543,6 @@ dependencies = [
]
[[package]]
-name = "signal-hook-tokio"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "213241f76fb1e37e27de3b6aa1b068a2c333233b59cca6634f634b80a27ecf1e"
-dependencies = [
- "futures-core",
- "libc",
- "signal-hook",
- "tokio",
-]
-
-[[package]]
name = "slab"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -620,16 +558,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
[[package]]
-name = "socket2"
-version = "0.4.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662"
-dependencies = [
- "libc",
- "winapi",
-]
-
-[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -648,9 +576,9 @@ dependencies = [
[[package]]
name = "syn"
-version = "2.0.10"
+version = "2.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5aad1363ed6d37b84299588d62d3a7d95b5a5c2d9aad5c85609fda12afaa1f40"
+checksum = "79d9531f94112cfc3e4c8f5f02cb2b58f72c97b7efd85f70203cc6d8efda5927"
dependencies = [
"proc-macro2",
"quote",
@@ -687,36 +615,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.10",
-]
-
-[[package]]
-name = "tokio"
-version = "1.26.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03201d01c3c27a29c8a5cee5b55a93ddae1ccf6f08f65365c2c918f8c1b76f64"
-dependencies = [
- "autocfg",
- "bytes",
- "libc",
- "memchr",
- "mio",
- "pin-project-lite",
- "signal-hook-registry",
- "socket2",
- "tokio-macros",
- "windows-sys",
-]
-
-[[package]]
-name = "tokio-macros"
-version = "1.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 1.0.109",
+ "syn 2.0.12",
]
[[package]]
@@ -778,28 +677,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
-name = "wasi"
-version = "0.11.0+wasi-snapshot-preview1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
-
-[[package]]
name = "wayrs-client"
-version = "0.4.1"
+version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78b5b3238dba61ad62cb0abeb01b8dff0cb37176e85e709aa5bcfcd77ced6e8b"
+checksum = "9db989c01a4c0bf6549c82c08b325cc3ee0f87f0e12137859686b329202a2707"
dependencies = [
"nix",
"thiserror",
- "tokio",
"wayrs-scanner",
]
[[package]]
name = "wayrs-protocols"
-version = "0.4.0"
+version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49ba0e64945dc0fe741fa63bcc6bbe9a82a5636de4f74ceead396d5534efbdbc"
+checksum = "89f2cc382c222b490e76071afc66d752433822bdeb2fd691ae7527f77adc66a7"
dependencies = [
"wayrs-client",
]
@@ -814,14 +706,14 @@ dependencies = [
"proc-macro2",
"quick-xml",
"quote",
- "syn 2.0.10",
+ "syn 2.0.12",
]
[[package]]
name = "wayrs-utils"
-version = "0.4.0-beta.0"
+version = "0.4.0-beta.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a2950db7610db7119bdb2b3ea5983dc01c2303e511e3a193959b5ed2d7f1854"
+checksum = "85f5b5d29578e9bf93fa800c1fe168d648f49e422ab1385da85e8f4222cc28aa"
dependencies = [
"memmap2",
"shmemfdrs",
@@ -853,72 +745,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
-name = "windows-sys"
-version = "0.45.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
-dependencies = [
- "windows-targets",
-]
-
-[[package]]
-name = "windows-targets"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
-dependencies = [
- "windows_aarch64_gnullvm",
- "windows_aarch64_msvc",
- "windows_i686_gnu",
- "windows_i686_msvc",
- "windows_x86_64_gnu",
- "windows_x86_64_gnullvm",
- "windows_x86_64_msvc",
-]
-
-[[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
-
-[[package]]
-name = "windows_aarch64_msvc"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
-
-[[package]]
-name = "windows_i686_gnu"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
-
-[[package]]
-name = "windows_i686_msvc"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
-
-[[package]]
-name = "windows_x86_64_gnu"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
-
-[[package]]
-name = "windows_x86_64_gnullvm"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
-
-[[package]]
-name = "windows_x86_64_msvc"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
-
-[[package]]
name = "winnow"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 7b2e9d4..6af1bcd 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,17 +11,12 @@ serde = { version = "1", features = ["derive"] }
serde_json = "1"
memchr = "2"
thiserror = "1.0.38"
-futures = { version = "0.3", default-features = false }
signal-hook = { version = "0.3", default-features = false }
-signal-hook-tokio = { version = "0.3", features = ["futures-v0_3"] }
+nix = "0.26"
-wayrs-client = { version = "0.4", features = ["tokio"] }
-wayrs-utils = { version = "0.4.0-beta.0", features = ["cursor", "shm_alloc", "seats"] }
-wayrs-protocols = { version = "0.4", features = ["wlr-layer-shell-unstable-v1", "viewporter", "fractional-scale-v1"] }
-
-[dependencies.tokio]
-version = "1"
-features = ["macros", "net", "rt", "io-util", "process"]
+wayrs-client = "0.5"
+wayrs-utils = { version = "0.4.0-beta.1", features = ["cursor", "shm_alloc", "seats"] }
+wayrs-protocols = { version = "0.5", features = ["wlr-layer-shell-unstable-v1", "viewporter", "fractional-scale-v1"] }
[profile.release]
lto = "fat"
diff --git a/src/main.rs b/src/main.rs
index c6cc525..befd750 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -18,42 +18,72 @@ mod utils;
mod wm_info_provider;
use signal_hook::consts::*;
-use signal_hook_tokio::Signals;
-use futures::stream::StreamExt;
+use std::{io::ErrorKind, os::fd::AsRawFd};
use wayrs_client::connection::Connection;
+use wayrs_client::IoMode;
+
+use nix::{
+ errno::Errno,
+ fcntl::OFlag,
+ poll::{poll, PollFd, PollFlags},
+};
use state::State;
-#[tokio::main(flavor = "current_thread")]
-async fn main() -> anyhow::Result<()> {
- let mut signals = Signals::new([SIGUSR1])?;
+fn main() -> anyhow::Result<()> {
+ let (sig_read, sig_write) = nix::unistd::pipe2(OFlag::O_NONBLOCK | OFlag::O_CLOEXEC)?;
+ signal_hook::low_level::pipe::register(SIGUSR1, sig_write)?;
let mut conn = Connection::connect()?;
- let globals = conn.async_collect_initial_globals().await?;
+ let globals = conn.blocking_collect_initial_globals()?;
let mut state = State::new(&mut conn, &globals);
- conn.async_flush().await?;
+ conn.flush(IoMode::Blocking)?;
+
+ let mut fds = Vec::with_capacity(3);
+ fds.push(PollFd::new(conn.as_raw_fd(), PollFlags::POLLIN));
+ fds.push(PollFd::new(sig_read, PollFlags::POLLIN));
+ if let Some(cmd_fd) = state.status_cmd_fd() {
+ fds.push(PollFd::new(cmd_fd, PollFlags::POLLIN));
+ }
loop {
- tokio::select! {
- recv_events = conn.async_recv_events() => {
- recv_events?;
- conn.dispatch_events(&mut state);
- conn.async_flush().await?;
- }
- reat_res = state.status_cmd_read() => {
- if let Err(e) = reat_res.and_then(|_| state.status_cmd_notify_available(&mut conn)) {
- if let Some(mut status_cmd) = state.shared_state.status_cmd.take() {
- let _ = status_cmd.child.kill();
- }
- state.set_error(&mut conn, e.to_string());
+ match poll(&mut fds, -1) {
+ Ok(_) => (),
+ Err(Errno::EINTR) => continue,
+ Err(e) => bail!(e),
+ }
+
+ if fds[0].any().unwrap_or(false) {
+ match conn.recv_events(IoMode::NonBlocking) {
+ Ok(()) => {
+ conn.dispatch_events(&mut state);
+ conn.flush(IoMode::Blocking)?;
}
- conn.async_flush().await?;
+ Err(e) if e.kind() == ErrorKind::WouldBlock => (),
+ Err(e) => return Err(e.into()),
}
- Some(signal) = signals.next() => match signal {
- SIGUSR1 => state.toggle_visibility(&mut conn),
- _ => unreachable!(),
+ }
+
+ if fds[1].any().unwrap_or(false) {
+ nix::unistd::read(sig_read, &mut [0; 1])?;
+ state.toggle_visibility(&mut conn);
+ }
+
+ if fds.len() > 2 && fds[2].any().unwrap_or(false) {
+ match state.shared_state.status_cmd.as_mut().unwrap().read() {
+ Ok(None) => (),
+ Ok(Some(blocks)) => {
+ state.set_blocks(&mut conn, blocks);
+ conn.flush(IoMode::Blocking)?;
+ }
+ Err(e) => {
+ let _ = state.shared_state.status_cmd.take().unwrap().child.kill();
+ fds.pop().unwrap();
+ state.set_error(&mut conn, e);
+ conn.flush(IoMode::Blocking)?;
+ }
}
}
}
diff --git a/src/state.rs b/src/state.rs
index 53ef4ff..4741efa 100644
--- a/src/state.rs
+++ b/src/state.rs
@@ -1,7 +1,8 @@
use crate::protocol::*;
use crate::wm_info_provider::*;
-use std::future::pending;
+use std::fmt::Display;
+use std::os::fd::{AsRawFd, RawFd};
use wayrs_client::connection::Connection;
use wayrs_client::global::{Global, GlobalExt, Globals, GlobalsExt};
@@ -108,11 +109,11 @@ impl State {
self.draw_all(conn);
}
- pub fn set_error(&mut self, conn: &mut Connection<Self>, error: impl Into<String>) {
+ pub fn set_error(&mut self, conn: &mut Connection<Self>, error: impl Display) {
self.set_blocks(
conn,
vec![Block {
- full_text: error.into(),
+ full_text: error.to_string(),
..Default::default()
}],
);
@@ -124,26 +125,11 @@ impl State {
}
}
- pub async fn status_cmd_read(&mut self) -> anyhow::Result<()> {
- match &mut self.shared_state.status_cmd {
- Some(cmd) => cmd.read().await,
- None => {
- pending::<()>().await;
- unreachable!()
- }
- }
- }
-
- pub fn status_cmd_notify_available(
- &mut self,
- conn: &mut Connection<Self>,
- ) -> anyhow::Result<()> {
- if let Some(cmd) = &mut self.shared_state.status_cmd {
- if let Some(blocks) = cmd.notify_available()? {
- self.set_blocks(conn, blocks);
- }
- }
- Ok(())
+ pub fn status_cmd_fd(&self) -> Option<RawFd> {
+ self.shared_state
+ .status_cmd
+ .as_ref()
+ .map(|cmd| cmd.output.as_raw_fd())
}
fn bind_output(&mut self, conn: &mut Connection<Self>, global: &Global) {
diff --git a/src/status_cmd.rs b/src/status_cmd.rs
index f6c9c2c..6123a7c 100644
--- a/src/status_cmd.rs
+++ b/src/status_cmd.rs
@@ -1,11 +1,9 @@
use std::io::Write;
-use std::process::{Child, ChildStdin, Command, Stdio};
+use std::os::fd::AsRawFd;
+use std::process::{Child, ChildStdin, ChildStdout, Command, Stdio};
use anyhow::Result;
-use tokio::io::AsyncReadExt;
-use tokio::process::ChildStdout;
-
use crate::i3bar_protocol::{Block, Event, Protocol};
const INITIAL_BUF_CAPACITY: usize = 4096;
@@ -17,6 +15,7 @@ pub struct StatusCmd {
input: ChildStdin,
protocol: Protocol,
buf: Vec<u8>,
+ buf_used: usize,
}
impl StatusCmd {
@@ -28,39 +27,48 @@ impl StatusCmd {
.spawn()?;
let output = child.stdout.take().unwrap();
let input = child.stdin.take().unwrap();
+ nix::fcntl::fcntl(
+ output.as_raw_fd(),
+ nix::fcntl::F_SETFL(nix::fcntl::OFlag::O_NONBLOCK),
+ )?;
Ok(Self {
child,
- output: ChildStdout::from_std(output)?,
+ output,
input,
protocol: Protocol::Unknown,
- buf: Vec::with_capacity(INITIAL_BUF_CAPACITY),
+ buf: vec![0; INITIAL_BUF_CAPACITY],
+ buf_used: 0,
})
}
- pub fn notify_available(&mut self) -> Result<Option<Vec<Block>>> {
- let rem = self.protocol.process_new_bytes(&self.buf)?;
- if rem.is_empty() {
- self.buf.clear();
- } else {
- let used = self.buf.len() - rem.len();
- self.buf.drain(..used);
+ pub fn read(&mut self) -> Result<Option<Vec<Block>>> {
+ assert!(self.buf.len() >= INITIAL_BUF_CAPACITY);
+ if self.buf.len() == self.buf_used {
+ // Double the capacity
+ self.buf.resize(self.buf_used * 2, 0);
}
- Ok(self.protocol.get_blocks())
- }
- pub async fn read(&mut self) -> Result<()> {
- assert!(self.buf.capacity() >= INITIAL_BUF_CAPACITY);
- if self.buf.capacity() == self.buf.len() {
- // Double the capacity
- self.buf.reserve(self.buf.len());
+ match nix::unistd::read(self.output.as_raw_fd(), &mut self.buf[self.buf_used..]) {
+ Ok(0) => bail!("status command exited"),
+ Ok(n) => self.buf_used += n,
+ Err(nix::errno::Errno::EAGAIN) => return Ok(None),
+ Err(e) => bail!(e),
}
- let read_len = self.output.read_buf(&mut self.buf).await?;
- if read_len == 0 {
- bail!("status command exited");
+ let rem = self
+ .protocol
+ .process_new_bytes(&self.buf[..self.buf_used])?;
+
+ if rem.is_empty() {
+ self.buf_used = 0;
+ } else {
+ let rem_len = rem.len();
+ self.buf
+ .copy_within((self.buf_used - rem_len)..self.buf_used, 0);
+ self.buf_used = rem_len;
}
- Ok(())
+ Ok(self.protocol.get_blocks())
}
pub fn send_click_event(&mut self, event: &Event) -> Result<()> {