forked from vitrine/wmaker
Compare commits
1 Commits
refactor/r
...
refactor/r
| Author | SHA1 | Date | |
|---|---|---|---|
| fa67563c2b |
@@ -12,7 +12,8 @@ RUST_SOURCES = \
|
||||
src/memory.rs \
|
||||
src/notification.rs \
|
||||
src/prop_list.rs \
|
||||
src/string.rs
|
||||
src/sendable.rs \
|
||||
src/string.rs \
|
||||
src/tree.rs
|
||||
|
||||
RUST_EXTRA = \
|
||||
|
||||
@@ -7,5 +7,6 @@ pub mod hash_table;
|
||||
pub mod memory;
|
||||
pub mod notification;
|
||||
pub mod prop_list;
|
||||
pub mod sendable;
|
||||
pub mod string;
|
||||
pub mod tree;
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
use std::{
|
||||
collections::{btree_map::Entry, BTreeMap},
|
||||
ffi::{c_void, CStr},
|
||||
ptr::{self, NonNull},
|
||||
ptr,
|
||||
sync::Mutex,
|
||||
};
|
||||
use crate::sendable::Sendable;
|
||||
|
||||
// Helper function for adding the entry `(key, (observer, action))` to `map`.
|
||||
fn register<K: Eq + Ord>(
|
||||
@@ -63,29 +64,6 @@ pub struct Notification {
|
||||
/// Callback that notifies `observer` (which may be null) of `notification` (which won't be).
|
||||
pub type Action = unsafe extern "C" fn(observer: *mut c_void, notification: *const Notification);
|
||||
|
||||
/// Wraps a type-erased pointer (which it does not own) and marks it as `Send`.
|
||||
///
|
||||
/// The `Send`-ability of the wrapped pointer must be guaranteed by code that
|
||||
/// instantiates a `Sendable`.
|
||||
#[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd)]
|
||||
pub struct Sendable {
|
||||
ptr: NonNull<c_void>,
|
||||
}
|
||||
|
||||
impl Sendable {
|
||||
/// Creates a `Sendable` wrapping `ptr`.
|
||||
///
|
||||
/// ## Safety
|
||||
///
|
||||
/// `ptr` must be safe to send across threads.
|
||||
pub unsafe fn new(ptr: NonNull<c_void>) -> Self {
|
||||
Sendable { ptr }
|
||||
}
|
||||
}
|
||||
|
||||
// Guaranteed by `Sendable::new`.
|
||||
unsafe impl Send for Sendable {}
|
||||
|
||||
pub struct NotificationCenter {
|
||||
/// Notification subscriptions that match on name and source.
|
||||
exact: BTreeMap<(&'static CStr, Sendable), Vec<(Option<Sendable>, Action)>>,
|
||||
@@ -283,7 +261,7 @@ pub mod ffi {
|
||||
let Some(action) = action else {
|
||||
return;
|
||||
};
|
||||
let observer = NonNull::new(observer).map(|x| unsafe { Sendable::new(x) });
|
||||
let observer = unsafe { Sendable::from_nullable(observer) };
|
||||
let source = NonNull::new(object);
|
||||
NotificationCenter::with_global_default(|c| {
|
||||
if name.is_null() {
|
||||
@@ -340,8 +318,8 @@ pub mod ffi {
|
||||
return;
|
||||
}
|
||||
let name = unsafe { CStr::from_ptr(name) };
|
||||
let source = NonNull::new(object).map(|x| unsafe { Sendable::new(x) });
|
||||
let client_data = NonNull::new(client_data).map(|x| unsafe { Sendable::new(x) });
|
||||
let source = unsafe { Sendable::from_nullable(object) };
|
||||
let client_data = unsafe {Sendable::from_nullable(client_data) };
|
||||
NotificationCenter::with_global_default(|c| {
|
||||
c.dispatch(Notification {
|
||||
name,
|
||||
|
||||
41
wutil-rs/src/sendable.rs
Normal file
41
wutil-rs/src/sendable.rs
Normal file
@@ -0,0 +1,41 @@
|
||||
use std::{ffi::c_void, ptr::{NonNull, self}};
|
||||
|
||||
/// Wraps a type-erased pointer (which it does not own) and marks it as `Send`.
|
||||
///
|
||||
/// The `Send`-ability of the wrapped pointer must be guaranteed by code that
|
||||
/// instantiates a `Sendable`.
|
||||
#[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd)]
|
||||
pub struct Sendable {
|
||||
pub(crate) ptr: NonNull<c_void>,
|
||||
}
|
||||
|
||||
impl Sendable {
|
||||
/// Creates a `Sendable` wrapping `ptr`.
|
||||
///
|
||||
/// ## Safety
|
||||
///
|
||||
/// `ptr` must be safe to send across threads.
|
||||
pub const unsafe fn new(ptr: NonNull<c_void>) -> Self {
|
||||
Sendable { ptr }
|
||||
}
|
||||
|
||||
/// Creates a `Sendable` if `ptr` is not null, returning `None` if it is.
|
||||
/// ## Safety
|
||||
///
|
||||
/// `ptr` must be safe to send across threads.
|
||||
pub unsafe fn from_nullable(ptr: *mut c_void) -> Option<Self> {
|
||||
unsafe {
|
||||
NonNull::new(ptr)
|
||||
.map(|p| Sendable::new(p))
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieves the pointer wrapped by `s`, or a null pointer if `s` is
|
||||
/// `None`.
|
||||
pub fn as_ptr(s: Option<Sendable>) -> *mut c_void {
|
||||
s.map(|s| s.ptr.as_ptr()).unwrap_or(ptr::null_mut())
|
||||
}
|
||||
}
|
||||
|
||||
// Guaranteed by `Sendable::new`.
|
||||
unsafe impl Send for Sendable {}
|
||||
Reference in New Issue
Block a user