Skip to content

Commit

Permalink
Simplified crate API - no dependencies.
Browse files Browse the repository at this point in the history
  • Loading branch information
AldaronLau committed Nov 1, 2021
1 parent 6a0b55b commit 43beed1
Show file tree
Hide file tree
Showing 5 changed files with 195 additions and 275 deletions.
5 changes: 0 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,5 @@ keywords = ["futures", "platform-agnostic", "cross-platform", "io", "waker"]
readme = "README.md"
edition = "2018"

[dependencies.flume]
version = "0.10"
default-features = false
features = ["async"]

[dev-dependencies]
pasts = "0.8"
66 changes: 25 additions & 41 deletions examples/pipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,69 +4,55 @@
mod pipe {
#![allow(unsafe_code)]

use flume::Sender;
use smelling_salts::linux::{Device, Driver, RawDevice, Watcher};
use smelling_salts::linux::{Device, Watcher};
use std::convert::TryInto;
use std::future::Future;
use std::mem::{self, MaybeUninit};
use std::os::raw;
use std::os::unix::io::RawFd;
use std::pin::Pin;
use std::sync::Once;
use std::task::{Context, Poll};

fn driver() -> &'static Driver {
static mut DRIVER: MaybeUninit<Driver> = MaybeUninit::uninit();
static ONCE: Once = Once::new();
unsafe {
ONCE.call_once(|| DRIVER = MaybeUninit::new(Driver::new()));
&*DRIVER.as_ptr()
}
}

// From fcntl.h
const O_CLOEXEC: raw::c_int = 0o2000000;
const O_NONBLOCK: raw::c_int = 0o0004000;
const O_DIRECT: raw::c_int = 0o0040000;

extern "C" {
fn pipe2(pipefd: *mut [raw::c_int; 2], flags: raw::c_int) -> RawDevice;
fn write(fd: RawDevice, buf: *const raw::c_void, count: usize)
fn pipe2(pipefd: *mut [RawFd; 2], flags: raw::c_int) -> RawFd;
fn write(fd: RawFd, buf: *const raw::c_void, count: usize)
-> isize;
fn read(fd: RawDevice, buf: *mut raw::c_void, count: usize) -> isize;
fn close(fd: RawDevice) -> raw::c_int;
}

struct PipeDriver(Sender<u32>, RawDevice);

impl PipeDriver {
unsafe fn callback(&mut self) -> Option<()> {
let mut x = MaybeUninit::<u32>::uninit();
let v = read(self.1, x.as_mut_ptr().cast(), mem::size_of::<u32>());
if v == mem::size_of::<u32>().try_into().unwrap()
&& self.0.send(x.assume_init()).is_err()
{
driver().discard(self.1);
let _ret = close(self.1);
assert_eq!(0, _ret);
std::mem::drop(std::ptr::read(self));
return None;
}
Some(())
}
fn read(fd: RawFd, buf: *mut raw::c_void, count: usize) -> isize;
fn close(fd: RawFd) -> raw::c_int;
}

/// A `PipeReceiver` device future.
pub struct PipeReceiver(Device<u32>);
pub struct PipeReceiver(Device, RawFd);

impl Future for PipeReceiver {
type Output = u32;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<u32> {
Pin::new(&mut self.get_mut().0).poll(cx)
let fd = self.1;
let mut this = self.get_mut();
let ret = Pin::new(&mut this.0).poll(cx).map(|()| unsafe {
let mut x = MaybeUninit::<u32>::uninit();
let v = read(fd, x.as_mut_ptr().cast(), mem::size_of::<u32>());
if v == mem::size_of::<u32>().try_into().unwrap() {
Some(x.assume_init().try_into().unwrap())
} else {
None
}
});
match ret {
Poll::Ready(None) => Pin::new(&mut this).poll(cx),
Poll::Ready(Some(x)) => Poll::Ready(x),
Poll::Pending => Poll::Pending,
}
}
}

/// A `PipeSender` device.
pub struct PipeSender(RawDevice);
pub struct PipeSender(RawFd);

impl PipeSender {
/// Send a 32-bit value over the pipe.
Expand Down Expand Up @@ -101,11 +87,9 @@ mod pipe {
pipe.assume_init()
};

let constructor = |sender| PipeDriver(sender, fd);
let callback = PipeDriver::callback;
let watcher = Watcher::new().input();
(
PipeReceiver(driver().device(constructor, fd, callback, watcher)),
PipeReceiver(Device::new(fd, watcher, true), fd),
PipeSender(sender),
)
}
Expand Down
63 changes: 23 additions & 40 deletions examples/sleep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,17 @@
mod timer {
#![allow(unsafe_code)]

use flume::Sender;
use smelling_salts::linux::{Device, Driver, RawDevice, Watcher};
use smelling_salts::linux::{Device, Watcher};
use std::convert::TryInto;
use std::future::Future;
use std::mem::{self, MaybeUninit};
use std::os::raw;
use std::os::unix::io::RawFd;
use std::pin::Pin;
use std::ptr;
use std::sync::Once;
use std::task::{Context, Poll};
use std::time::Duration;

fn driver() -> &'static Driver {
static mut DRIVER: MaybeUninit<Driver> = MaybeUninit::uninit();
static ONCE: Once = Once::new();
unsafe {
ONCE.call_once(|| DRIVER = MaybeUninit::new(Driver::new()));
&*DRIVER.as_ptr()
}
}

#[repr(C)]
struct TimeSpec {
sec: isize,
Expand All @@ -38,38 +28,18 @@ mod timer {
}

extern "C" {
fn timerfd_create(clockid: raw::c_int, flags: raw::c_int) -> RawDevice;
fn timerfd_create(clockid: raw::c_int, flags: raw::c_int) -> RawFd;
fn timerfd_settime(
fd: RawDevice,
fd: RawFd,
flags: raw::c_int,
new_value: *const ITimerSpec,
old_value: *mut ITimerSpec,
) -> raw::c_int;
fn read(fd: RawDevice, buf: *mut u64, count: usize) -> isize;
fn close(fd: RawDevice) -> raw::c_int;
}

struct TimerDriver(Sender<usize>, RawDevice);

impl TimerDriver {
unsafe fn callback(&mut self) -> Option<()> {
let mut x = MaybeUninit::<u64>::uninit();
let v = read(self.1, x.as_mut_ptr(), mem::size_of::<u64>());
if v == mem::size_of::<u64>().try_into().unwrap()
&& self.0.send(x.assume_init().try_into().unwrap()).is_err()
{
driver().discard(self.1);
let _ret = close(self.1);
assert_eq!(0, _ret);
std::mem::drop(std::ptr::read(self));
return None;
}
Some(())
}
fn read(fd: RawFd, buf: *mut u64, count: usize) -> isize;
}

/// A `Timer` device future.
pub struct Timer(Device<usize>);
pub struct Timer(Device, RawFd);

impl Timer {
/// Create a new `Timer`.
Expand All @@ -84,17 +54,30 @@ mod timer {
};
let _ret = unsafe { timerfd_settime(fd, 0, &its, ptr::null_mut()) };
assert_eq!(0, _ret);
let constructor = |sender| TimerDriver(sender, fd);
let callback = TimerDriver::callback;
let watcher = Watcher::new().input();
Self(driver().device(constructor, fd, callback, watcher))
Self(Device::new(fd, watcher, true), fd)
}
}

impl Future for Timer {
type Output = usize;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<usize> {
Pin::new(&mut self.get_mut().0).poll(cx)
let fd = self.1;
let mut this = self.get_mut();
let ret = Pin::new(&mut this.0).poll(cx).map(|()| unsafe {
let mut x = MaybeUninit::<u64>::uninit();
let v = read(fd, x.as_mut_ptr(), mem::size_of::<u64>());
if v == mem::size_of::<u64>().try_into().unwrap() {
x.assume_init().try_into().unwrap()
} else {
0
}
});
if ret == Poll::Ready(0) {
Pin::new(&mut this).poll(cx)
} else {
ret
}
}
}
}
Expand Down
9 changes: 6 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
//! ####################
//! # For Applications #
//! ####################
//!
//!
//! [dependencies.pasts]
//! version = "0.8"
//! ```
Expand All @@ -55,7 +55,10 @@
variant_size_differences
)]

#[cfg(target_os = "linux")]
pub mod linux;
// #[cfg(target_os = "linux")]
// pub mod linux;
#[cfg(target_os = "linux")]
mod watcher;

#[cfg(target_os = "linux")]
pub mod linux;
Loading

0 comments on commit 43beed1

Please sign in to comment.