Skip to content

Commit 997890c

Browse files
committed
dispatch2: Add fn data_create() which copies a slice
1 parent f7b4c78 commit 997890c

File tree

5 files changed

+84
-7
lines changed

5 files changed

+84
-7
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/dispatch2/src/object.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
//! Dispatch object definition.
22
33
use alloc::boxed::Box;
4+
use core::{ops::Deref, ptr::NonNull};
45

56
use super::{ffi::*, queue::Queue, utils::function_wrapper, QualityOfServiceClass};
67

8+
// TODO: Autogenerate with https://github.com/madsmtm/objc2/issues/609
9+
const DISPATCH_DATA_DESTRUCTOR_DEFAULT: dispatch_block_t = std::ptr::null_mut();
10+
711
/// Error returned by [DispatchObject::set_target_queue].
812
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
913
#[non_exhaustive]
@@ -60,6 +64,77 @@ impl<T> DispatchObject<T> {
6064
result
6165
}
6266

67+
/// Creates a dispatch data object with a copy of the given contiguous buffer of memory.
68+
// TODO: Would it be safe for users to replace the finalizer?
69+
pub fn data_create_copy(data: &[u8], queue: &Queue) -> Self {
70+
// SAFETY: Buffer pointer is valid for the given number of bytes. Queue handle is valid,
71+
// and the destructor is a NULL value which indicates the buffer should be copied.
72+
let object = unsafe {
73+
dispatch_data_create(
74+
NonNull::new_unchecked(data.as_ptr().cast_mut()).cast(),
75+
data.len(),
76+
queue.as_raw(),
77+
DISPATCH_DATA_DESTRUCTOR_DEFAULT,
78+
)
79+
};
80+
81+
Self {
82+
object: object.cast(),
83+
is_activated: false,
84+
}
85+
}
86+
87+
/// Creates a dispatch data object with a reference to the given contiguous buffer of memory.
88+
pub fn data_create_static(data: &'static [u8], queue: &Queue) -> Self {
89+
block2::global_block! {
90+
static NOOP_BLOCK = || {}
91+
}
92+
// SAFETY: Buffer pointer is valid for the given number of bytes. Queue handle is valid,
93+
// and the destructor is a NULL value which indicates the buffer should be copied.
94+
let object = unsafe {
95+
dispatch_data_create(
96+
NonNull::new_unchecked(data.as_ptr().cast_mut()).cast(),
97+
data.len(),
98+
queue.as_raw(),
99+
<*const _>::cast_mut(NOOP_BLOCK.deref()),
100+
)
101+
};
102+
103+
Self {
104+
object: object.cast(),
105+
is_activated: false,
106+
}
107+
}
108+
109+
/// Creates a dispatch data object with ownership of the given contiguous buffer of memory.
110+
// TODO: Would it be safe for users to replace the finalizer?
111+
pub fn data_create(data: Box<[u8]>, queue: &Queue) -> Self {
112+
let data_len = data.len();
113+
let raw = Box::into_raw(data);
114+
let delete_box = block2::RcBlock::new(move || {
115+
// SAFETY: The fat pointer (plus size) was retrieved from Box::into_raw(), and its
116+
// ownership was *not* consumed by dispatch_data_create().
117+
let _ = unsafe { Box::<[u8]>::from_raw(raw) };
118+
});
119+
120+
// SAFETY: Buffer pointer is valid for the given number of bytes. Queue handle is valid,
121+
// and the destructor is a NULL value which indicates the buffer should be copied.
122+
// let t = Box::into_raw(data);
123+
let object = unsafe {
124+
dispatch_data_create(
125+
NonNull::new_unchecked(raw).cast(),
126+
data_len,
127+
queue.as_raw(),
128+
<*const _>::cast_mut(delete_box.deref()),
129+
)
130+
};
131+
132+
Self {
133+
object: object.cast(),
134+
is_activated: false,
135+
}
136+
}
137+
63138
/// Set the finalizer function for the object.
64139
pub fn set_finalizer<F>(&mut self, destructor: F)
65140
where

crates/dispatch2/src/queue.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ pub struct Queue {
127127
}
128128

129129
impl Queue {
130-
/// Create a new [Queue].
130+
/// Create a new [`Queue`].
131131
pub fn new(label: &str, queue_attribute: QueueAttribute) -> Self {
132132
let label = CString::new(label).expect("Invalid label!");
133133

@@ -147,7 +147,7 @@ impl Queue {
147147
}
148148
}
149149

150-
/// Create a new [Queue] with a given target [Queue].
150+
/// Create a new [`Queue`] with a given target [`Queue`].
151151
pub fn new_with_target(label: &str, queue_attribute: QueueAttribute, target: &Queue) -> Self {
152152
let label = CString::new(label).expect("Invalid label!");
153153

framework-crates/objc2-metal/Cargo.toml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

framework-crates/objc2-metal/translation-config.toml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,6 @@ class.MTLRasterizationRateLayerDescriptor.methods.sampleCount.skipped = true
1515
# Swift also skips this.
1616
class.MTLRasterizationRateMapDescriptor.methods."rasterizationRateMapDescriptorWithScreenSize:layerCount:layers:".skipped = true
1717

18-
# Needs dispatch
19-
class.MTLSharedEventListener.methods."initWithDispatchQueue:".skipped = true
20-
class.MTLSharedEventListener.methods.dispatchQueue.skipped = true
21-
protocol.MTLDevice.methods."newLibraryWithData:error:".skipped = true
22-
2318
# Needs mach / kernel types
2419
protocol.MTLResource.methods."setOwnerWithIdentity:".skipped = true
2520

0 commit comments

Comments
 (0)