Skip to content

Commit b8eb431

Browse files
committed
doc(driver): clearify Key::into_box and Key::into_inner
1 parent 3bdd4ab commit b8eb431

File tree

2 files changed

+16
-15
lines changed

2 files changed

+16
-15
lines changed

compio-driver/src/key.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ use crate::{OpCode, Overlapped, PushEntry, RawFd};
88
/// heap. The pointer to this struct is used as `user_data`, and on Windows, it
99
/// is used as the pointer to `OVERLAPPED`.
1010
///
11-
/// Convert any `user_data` to `*const RawOp<()>` is valid. Then it could be
12-
/// converted to `*mut RawOp<dyn OpCode>` with `upcast_fn`.
11+
/// `*const RawOp<dyn OpCode>` can be obtained from any `Key<T: OpCode>` by
12+
/// first casting `Key::user_data` to `*const RawOp<()>`, then upcasted with
13+
/// `upcast_fn`. It is done in [`Key::as_op_pin`].
1314
#[repr(C)]
1415
pub(crate) struct RawOp<T: ?Sized> {
1516
header: Overlapped,
@@ -132,7 +133,9 @@ impl<T: ?Sized> Key<T> {
132133
///
133134
/// # Safety
134135
///
135-
/// Call it when the op is cancelled and completed.
136+
/// Call it only when the op is cancelled and completed, which is the case
137+
/// when the ref count becomes zero. See doc of [`Key::set_cancelled`]
138+
/// and [`Key::set_result`].
136139
pub(crate) unsafe fn into_box(mut self) -> Box<RawOp<dyn OpCode>> {
137140
let this = self.as_opaque_mut();
138141
let ptr = (this.upcast_fn)(self.user_data);
@@ -143,12 +146,12 @@ impl<T: ?Sized> Key<T> {
143146
impl<T> Key<T> {
144147
/// Get the inner result if it is completed.
145148
///
146-
/// # Panics
149+
/// # Safety
147150
///
148-
/// Panics if the op is not completed.
149-
pub(crate) fn into_inner(self) -> BufResult<usize, T> {
151+
/// Call it only when the op is completed, otherwise it is UB.
152+
pub(crate) unsafe fn into_inner(self) -> BufResult<usize, T> {
150153
let op = unsafe { Box::from_raw(self.user_data as *mut RawOp<T>) };
151-
BufResult(op.result.take_ready().unwrap(), op.op)
154+
BufResult(op.result.take_ready().unwrap_unchecked(), op.op)
152155
}
153156
}
154157

compio-driver/src/lib.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -247,15 +247,11 @@ impl Proactor {
247247
/// The cancellation is not reliable. The underlying operation may continue,
248248
/// but just don't return from [`Proactor::poll`]. Therefore, although an
249249
/// operation is cancelled, you should not reuse its `user_data`.
250-
///
251-
/// It is *safe* to cancel before polling. If the submitted operation
252-
/// contains a cancelled user-defined data, the operation will be ignored.
253-
/// However, to make the operation dropped correctly, you should cancel
254-
/// after push.
255250
pub fn cancel<T: OpCode>(&mut self, mut op: Key<T>) -> Option<BufResult<usize, T>> {
256251
instrument!(compio_log::Level::DEBUG, "cancel", ?op);
257252
if op.set_cancelled() {
258-
Some(op.into_inner())
253+
// SAFETY: completed.
254+
Some(unsafe { op.into_inner() })
259255
} else {
260256
self.driver.cancel(op);
261257
None
@@ -270,7 +266,8 @@ impl Proactor {
270266
Poll::Pending => PushEntry::Pending(op),
271267
Poll::Ready(res) => {
272268
op.set_result(res);
273-
PushEntry::Ready(op.into_inner())
269+
// SAFETY: just completed.
270+
PushEntry::Ready(unsafe { op.into_inner() })
274271
}
275272
}
276273
}
@@ -296,7 +293,8 @@ impl Proactor {
296293
pub fn pop<T>(&mut self, op: Key<T>) -> PushEntry<Key<T>, BufResult<usize, T>> {
297294
instrument!(compio_log::Level::DEBUG, "pop", ?op);
298295
if op.has_result() {
299-
PushEntry::Ready(op.into_inner())
296+
// SAFETY: completed.
297+
PushEntry::Ready(unsafe { op.into_inner() })
300298
} else {
301299
PushEntry::Pending(op)
302300
}

0 commit comments

Comments
 (0)