Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,19 @@ jobs:
- name: Check the spelling of the files in our repo
uses: crate-ci/typos@master

deny:
name: Check dependencies
runs-on: ubuntu-latest

steps:
- name: Checkout the repo
uses: actions/checkout@v4

- name: Cargo deny
uses: EmbarkStudios/cargo-deny-action@v2
with:
command: check

clippy:
name: Run clippy
needs: [style]
Expand Down
2 changes: 1 addition & 1 deletion crates/weechat-macro/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ proc-macro = true

[dependencies]
libc = "0.2.132"
syn = "1.0.99"
syn = "3.0.3"
proc-macro2 = "1.0.43"
quote = "1.0.21"

Expand Down
2 changes: 1 addition & 1 deletion crates/weechat-macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ impl Parse for WeechatPluginInfo {
input.parse::<syn::Token![,]>()?;

let args: Punctuated<WeechatVariable, syn::Token![,]> =
input.parse_terminated(WeechatVariable::parse)?;
input.parse_terminated(WeechatVariable::parse, syn::Token![,])?;
let mut variables = HashMap::new();

for arg in args.pairs() {
Expand Down
18 changes: 9 additions & 9 deletions crates/weechat/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ rustdoc-args = ["--cfg", "feature=\"docs\""]

[features]
# Support to run futures on the Weechat main thread.
async = ["async-task", "pipe-channel", "futures", "async-trait"]
async = ["async-task", "os_pipe", "futures", "async-trait"]

# Declarative configuration macro.
config_macro = ["paste", "strum"]
config_macro = ["pastey", "strum"]

# Still unsound or experimental features will be hidden behind this flag.
unsound = []
Expand All @@ -33,19 +33,19 @@ libc = "0.2.132"
backtrace = "0.3.66"
async-task = { version = "4.3.0", optional = true }
async-trait = { version = "0.1.57", optional = true }
pipe-channel = { version = "1.3.0", optional = true }
os_pipe = { version = "1.2.3", optional = true }
futures = { version = "0.3.24", optional = true }
paste = { version = "1.0.9", optional = true }
strum = { version = "0.24.1", optional = true }
pastey = { version = "0.2.3", optional = true }
strum = { version = "0.28.0", optional = true }

weechat-macro = { version = "0.4.0", path = "../weechat-macro" }
weechat-sys = { version = "0.4.0", path = "../weechat-sys" }

[dev-dependencies]
async-std = "1.12.0"
pipe-channel = "1.3.0"
strum = "0.24.1"
strum_macros = "0.24.3"
async-channel = "2.5.0"
os_pipe = "1.2.3"
strum = "0.28.0"
strum_macros = "0.28.0"
futures = "0.3.24"

[build-dependencies]
Expand Down
56 changes: 47 additions & 9 deletions crates/weechat/src/executor.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,56 @@
use std::{
collections::VecDeque,
io::{Read, Result, Write},
os::unix::io::{AsRawFd, RawFd},
panic,
sync::{Arc, Mutex},
};

pub use async_task::{Runnable, Task};
use futures::future::{BoxFuture, Future};
use pipe_channel::{channel, Receiver, Sender};
use os_pipe::{PipeReader, PipeWriter};

use crate::{
hooks::{FdHook, FdHookCallback, FdHookMode},
Weechat,
};

// These are `pub` rather than `pub(crate)` only because `FdHookCallback` is a
// public trait, so the compiler wants its associated types to also be
// `pub`, but since the `executor` module is private, these types aren't
// actually accessible via the public API.

/// Create a pipe whose receiving half can be watched by an [`FdHook`], letting
/// other threads wake up the Weechat main thread.
pub fn pipe() -> Result<(Sender, Receiver)> {
let (reader, writer) = os_pipe::pipe()?;

Ok((Sender(writer), Receiver(reader)))
}

pub struct Sender(PipeWriter);

impl Sender {
fn send(&mut self) -> Result<()> {
self.0.write_all(&[0])
}
}

pub struct Receiver(PipeReader);

impl Receiver {
fn recv(&mut self) -> Result<()> {
let mut byte = [0];
self.0.read_exact(&mut byte)
}
}

impl AsRawFd for Receiver {
fn as_raw_fd(&self) -> RawFd {
self.0.as_raw_fd()
}
}

static mut _EXECUTOR: Option<WeechatExecutor> = None;

type BufferName = String;
Expand Down Expand Up @@ -43,16 +81,16 @@ type FutureQueue = Arc<Mutex<VecDeque<ExecutorJob>>>;

#[derive(Clone)]
pub struct WeechatExecutor {
_hook: Arc<Mutex<Option<FdHook<Receiver<()>>>>>,
sender: Arc<Mutex<Sender<()>>>,
_hook: Arc<Mutex<Option<FdHook<Receiver>>>>,
sender: Arc<Mutex<Sender>>,
futures: FutureQueue,
non_local_futures: Arc<Mutex<VecDeque<BoxFuture<'static, ()>>>>,
}

impl FdHookCallback for WeechatExecutor {
type FdObject = Receiver<()>;
type FdObject = Receiver;

fn callback(&mut self, _weechat: &Weechat, receiver: &mut Receiver<()>) {
fn callback(&mut self, _weechat: &Weechat, receiver: &mut Receiver) {
if receiver.recv().is_err() {
return;
}
Expand Down Expand Up @@ -90,7 +128,7 @@ impl FdHookCallback for WeechatExecutor {

impl WeechatExecutor {
fn new() -> Self {
let (sender, receiver) = channel();
let (sender, receiver) = pipe().expect("Can't create executor wakeup pipe");
let sender = Arc::new(Mutex::new(sender));
let queue = Arc::new(Mutex::new(VecDeque::new()));
let non_local = Arc::new(Mutex::new(VecDeque::new()));
Expand Down Expand Up @@ -132,7 +170,7 @@ impl WeechatExecutor {
q.lock().expect("Lock of the future queue of the Weechat executor is poisoned");

queue.push_back(ExecutorJob::Job(runnable));
weechat_notify.send(()).expect("Can't notify Weechat to run a future");
weechat_notify.send().expect("Can't notify Weechat to run a future");
}
};

Expand Down Expand Up @@ -173,7 +211,7 @@ impl WeechatExecutor {
.sender
.lock()
.unwrap()
.send(())
.send()
.expect("Can't notify Weechat to spawn a non-local future");
}

Expand Down Expand Up @@ -212,7 +250,7 @@ impl WeechatExecutor {
q.lock().expect("Lock of the future queue of the Weechat executor is poisoned");

queue.push_back(ExecutorJob::BufferJob(BufferJob(runnable, buffer_name.clone())));
weechat_notify.send(()).expect("Can't notify Weechat to run a future");
weechat_notify.send().expect("Can't notify Weechat to run a future");
}
};

Expand Down
15 changes: 9 additions & 6 deletions crates/weechat/src/hooks/fd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,24 +90,27 @@ impl<F> FdHook<F> {
/// # Example
///
/// ```no_run
/// # use std::io::Read;
/// # use weechat::{Weechat, hooks::{FdHook, FdHookMode, FdHookCallback}};
/// # use pipe_channel::{channel, Receiver, Sender};
/// # use os_pipe::PipeReader;
///
/// struct Data;
///
/// impl FdHookCallback for Data {
/// type FdObject = Receiver<String>;
/// type FdObject = PipeReader;
///
/// fn callback(&mut self, _: &Weechat, receiver: &mut Receiver<String>) {
/// if let Ok(data) = receiver.recv() {
/// fn callback(&mut self, _: &Weechat, reader: &mut PipeReader) {
/// let mut data = String::new();
///
/// if reader.read_to_string(&mut data).is_ok() {
/// Weechat::print(&data)
/// }
/// }
/// }
///
/// let (sender, receiver): (Sender<String>, Receiver<String>) = channel();
/// let (reader, writer) = os_pipe::pipe().expect("Can't create pipe");
///
/// let hook = FdHook::new(receiver, FdHookMode::Read, Data)
/// let hook = FdHook::new(reader, FdHookMode::Read, Data)
/// .expect("Can't create executor FD hook");
/// ```
pub fn new(
Expand Down
2 changes: 1 addition & 1 deletion crates/weechat/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ mod weechat;
mod config_macros;

#[cfg(feature = "config_macro")]
pub use paste;
pub use pastey as paste;
#[cfg(feature = "config_macro")]
pub use strum;

Expand Down
4 changes: 2 additions & 2 deletions crates/weechat/src/weechat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,7 @@ impl Weechat {
///
/// ```no_run
/// use weechat::Weechat;
/// use async_std::channel::{bounded as channel, Receiver};
/// use async_channel::{bounded as channel, Receiver};
/// use futures::executor::block_on;
///
/// pub async fn task(receiver: Receiver<String>) {
Expand Down Expand Up @@ -653,7 +653,7 @@ impl Weechat {
///
/// ```no_run
/// use weechat::Weechat;
/// use async_std::channel::{bounded as channel, Receiver};
/// use async_channel::{bounded as channel, Receiver};
/// use futures::executor::block_on;
///
/// pub async fn task(receiver: Receiver<String>) {
Expand Down
27 changes: 27 additions & 0 deletions deny.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[graph]
all-features = true

[licenses]
# Unicode-3.0 is required by unicode-ident, whose expression ANDs it with the
# usual MIT/Apache choice rather than offering it as an alternative.
allow = [
"0BSD",
"Apache-2.0",
"BSD-3-Clause",
"ISC",
"MIT",
"Unicode-3.0",
"Unlicense",
"Zlib",
]

[bans]
multiple-versions = "warn"
skip = [{ crate = "syn:2", reason = "transitive dependency of bindgen" }]

[advisories]
ignore = []

[sources]
unknown-registry = "deny"
unknown-git = "deny"
Loading