1#![allow(dead_code)]
2
3use std::{
4 fmt::{self, Debug},
5 hash::Hash,
6 io,
7 mem::{self, ManuallyDrop},
8 ops::{Deref, DerefMut},
9 ptr,
10 task::Waker,
11};
12
13use compio_buf::{BufResult, IntoInner};
14use compio_send_wrapper::SendWrapper;
15use thin_cell::unsync::{Inner, Ref, ThinCell, Weak};
16
17use crate::{Carry, DriverType, Extra, OpCode, PushEntry, control::Carrier};
18
19#[repr(C)]
24pub(crate) struct RawOp<M: ?Sized> {
25 extra: Extra,
34 cancelled: bool,
36 result: PushEntry<Option<Waker>, io::Result<usize>>,
37 pub(crate) carrier: M,
38}
39
40impl<C: ?Sized> RawOp<C> {
41 pub fn extra(&self) -> &Extra {
42 &self.extra
43 }
44
45 pub fn extra_mut(&mut self) -> &mut Extra {
46 &mut self.extra
47 }
48
49 #[cfg(io_uring)]
50 pub fn wake_by_ref(&mut self) {
51 if let PushEntry::Pending(Some(w)) = &self.result {
52 w.wake_by_ref();
53 }
54 }
55}
56
57#[cfg(io_uring)]
58impl<C: crate::Carry + ?Sized> RawOp<C> {
59 pub fn create_entry<const FALLBACK: bool>(&mut self) -> crate::OpEntry {
60 if FALLBACK {
61 self.carrier.create_entry_fallback().with_extra(&self.extra)
62 } else {
63 self.carrier.create_entry().with_extra(&self.extra)
64 }
65 }
66}
67
68#[cfg(windows)]
69impl<C: crate::Carry + ?Sized> RawOp<C> {
70 pub fn operate_blocking(&mut self) -> io::Result<usize> {
75 use std::{panic::AssertUnwindSafe, task::Poll};
76
77 use crate::panic::catch_unwind_io;
78
79 let optr = self.extra_mut().optr();
80 catch_unwind_io(AssertUnwindSafe(|| unsafe {
81 match self.carrier.operate(optr.cast()) {
82 Poll::Pending => unreachable!("this operation is not overlapped"),
83 Poll::Ready(res) => res,
84 }
85 }))
86 }
87}
88
89impl<C: ?Sized> Debug for RawOp<C> {
90 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
91 f.debug_struct("RawOp")
92 .field("extra", &self.extra)
93 .field("cancelled", &self.cancelled)
94 .field("result", &self.result)
95 .field("Carrier", &"<...>")
96 .finish()
97 }
98}
99
100#[repr(transparent)]
102pub struct Key<T> {
103 erased: ErasedKey,
104 _p: std::marker::PhantomData<T>,
105}
106
107#[derive(Clone)]
113#[repr(transparent)]
114pub struct ErasedKey {
115 inner: ThinCell<RawOp<dyn Carry>>,
116}
117
118#[derive(Clone)]
120#[repr(transparent)]
121pub(crate) struct WeakKey {
122 inner: Weak<RawOp<dyn Carry>>,
123}
124
125impl<T> Clone for Key<T> {
126 fn clone(&self) -> Self {
127 Self {
128 erased: self.erased.clone(),
129 _p: std::marker::PhantomData,
130 }
131 }
132}
133
134impl<T> Debug for Key<T> {
135 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
136 write!(f, "Key({})", self.erased.inner.as_ptr() as usize)
137 }
138}
139
140impl<T> Key<T> {
141 pub(crate) fn into_raw(self) -> usize {
142 self.erased.into_raw()
143 }
144
145 pub(crate) fn erase(self) -> ErasedKey {
146 self.erased
147 }
148}
149
150impl<T: OpCode> Key<T> {
151 pub(crate) fn take_result(self) -> BufResult<usize, T> {
158 unsafe { self.erased.take_result::<T>() }
161 }
162}
163
164impl<T: OpCode + 'static> Key<T> {
165 pub(crate) fn new(op: T, extra: impl Into<Extra>, driver_ty: DriverType) -> Self {
167 let erased = ErasedKey::new(op, extra.into(), driver_ty);
168
169 Self {
170 erased,
171 _p: std::marker::PhantomData,
172 }
173 }
174
175 pub(crate) fn set_extra(&self, extra: impl Into<Extra>) {
176 self.borrow().extra = extra.into();
177 }
178}
179
180impl<T> Deref for Key<T> {
181 type Target = ErasedKey;
182
183 fn deref(&self) -> &Self::Target {
184 &self.erased
185 }
186}
187
188impl<T> DerefMut for Key<T> {
189 fn deref_mut(&mut self) -> &mut Self::Target {
190 &mut self.erased
191 }
192}
193
194impl PartialEq for ErasedKey {
195 fn eq(&self, other: &Self) -> bool {
196 self.inner.ptr_eq(&other.inner)
197 }
198}
199
200impl Eq for ErasedKey {}
201
202impl Hash for ErasedKey {
203 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
204 (self.inner.as_ptr() as usize).hash(state)
205 }
206}
207
208impl Unpin for ErasedKey {}
209
210impl ErasedKey {
211 pub(crate) fn new<T: OpCode + 'static>(op: T, extra: Extra, driver_ty: DriverType) -> Self {
213 let raw_op = RawOp {
214 extra,
215 cancelled: false,
216 result: PushEntry::Pending(None),
217 carrier: Carrier::new(op, driver_ty),
218 };
219 let mut inner = ThinCell::new(raw_op);
220 unsafe { inner.borrow_unchecked().carrier.init() };
225 Self {
226 inner: unsafe { inner.unsize(|p| p as *const Inner<RawOp<dyn Carry>>) },
227 }
228 }
229
230 pub(crate) unsafe fn from_raw(user_data: usize) -> Self {
237 let inner = unsafe { ThinCell::from_raw(user_data as *mut ()) };
238 Self { inner }
239 }
240
241 #[cfg(windows)]
248 pub(crate) unsafe fn from_optr(optr: *mut crate::sys::Overlapped) -> Self {
249 let ptr = unsafe { optr.cast::<usize>().offset(-2).cast() };
250 let inner = unsafe { ThinCell::from_raw(ptr) };
251 Self { inner }
252 }
253
254 #[cfg(windows)]
256 pub(crate) fn into_optr(self) -> *mut crate::sys::Overlapped {
257 unsafe { self.inner.leak().cast::<usize>().add(2).cast() }
258 }
259
260 pub(crate) fn downgrade(&self) -> WeakKey {
267 WeakKey {
268 inner: self.inner.downgrade(),
269 }
270 }
271
272 pub(crate) fn as_raw(&self) -> usize {
277 self.inner.as_ptr() as _
278 }
279
280 pub(crate) fn into_raw(self) -> usize {
282 self.inner.leak() as _
283 }
284
285 #[inline]
286 pub(crate) fn borrow(&self) -> Ref<'_, RawOp<dyn Carry>> {
287 self.inner.borrow()
288 }
289
290 pub(crate) fn set_cancelled(&self) -> bool {
292 let mut op = self.borrow();
293 mem::replace(&mut op.cancelled, true)
294 }
295
296 pub(crate) fn has_result(&self) -> bool {
298 self.borrow().result.is_ready()
299 }
300
301 pub(crate) fn is_unique(&self) -> bool {
303 ThinCell::count(&self.inner) == 1
304 }
305
306 pub(crate) fn set_result(&self, res: io::Result<usize>) {
308 let mut this = self.borrow();
309 {
310 let RawOp { extra, carrier, .. } = &mut *this;
311 unsafe { crate::sys::Carry::set_result(carrier, &res, extra) };
312 }
313 if let PushEntry::Pending(Some(w)) =
314 std::mem::replace(&mut this.result, PushEntry::Ready(res))
315 {
316 w.wake();
317 }
318 }
319
320 pub(crate) fn swap_extra(&self, extra: Extra) -> Extra {
323 std::mem::replace(&mut self.borrow().extra, extra)
324 }
325
326 pub(crate) fn set_waker(&self, waker: &Waker) {
328 let PushEntry::Pending(w) = &mut self.borrow().result else {
329 return;
330 };
331
332 if w.as_ref().is_some_and(|w| w.will_wake(waker)) {
333 return;
334 }
335
336 *w = Some(waker.clone());
337 }
338
339 unsafe fn take_result<T: OpCode>(self) -> BufResult<usize, T> {
350 let this = unsafe { self.inner.downcast_unchecked::<RawOp<Carrier<T>>>() };
352 let op = this.try_unwrap().map_err(|_| ()).expect("Key not unique");
353 let res = op.result.take_ready().expect("Result not ready");
354 BufResult(res, op.carrier.into_inner())
355 }
356
357 pub(crate) unsafe fn freeze(self) -> FrozenKey {
368 FrozenKey {
369 inner: ManuallyDrop::new(self),
370 thread_id: SendWrapper::new(()),
371 }
372 }
373}
374
375impl Debug for ErasedKey {
376 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
377 write!(f, "ErasedKey({})", self.inner.as_ptr() as usize)
378 }
379}
380
381impl WeakKey {
382 pub(crate) fn upgrade(&self) -> Option<ErasedKey> {
383 Some(ErasedKey {
384 inner: self.inner.upgrade()?,
385 })
386 }
387
388 pub(crate) fn as_ptr(&self) -> *const () {
389 self.inner.as_ptr()
390 }
391}
392
393impl PartialEq for WeakKey {
394 fn eq(&self, other: &Self) -> bool {
395 ptr::eq(self.inner.as_ptr(), other.inner.as_ptr())
396 }
397}
398
399impl Eq for WeakKey {}
400
401impl Hash for WeakKey {
402 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
403 (self.inner.as_ptr() as usize).hash(state)
404 }
405}
406
407impl Debug for WeakKey {
408 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
409 if let Some(upgraded) = self.inner.upgrade() {
410 Debug::fmt(&upgraded, f)
411 } else {
412 write!(f, "(Dropped)")
413 }
414 }
415}
416
417#[repr(C)]
421pub(crate) struct FrozenKey {
422 inner: ManuallyDrop<ErasedKey>,
423 thread_id: SendWrapper<()>,
424}
425
426impl FrozenKey {
427 pub fn as_mut(&mut self) -> &mut RawOp<dyn Carry> {
428 unsafe { self.inner.inner.borrow_unchecked() }
429 }
430
431 pub fn into_inner(self) -> ErasedKey {
432 let mut this = ManuallyDrop::new(self);
433 unsafe { ManuallyDrop::take(&mut this.inner) }
434 }
435}
436
437impl Drop for FrozenKey {
438 fn drop(&mut self) {
439 if self.thread_id.valid() {
440 unsafe { ManuallyDrop::drop(&mut self.inner) }
441 }
442 }
443}
444
445unsafe impl Send for FrozenKey {}
446unsafe impl Sync for FrozenKey {}
447
448pub(crate) struct BorrowedKey(ManuallyDrop<ErasedKey>);
454
455impl BorrowedKey {
456 pub unsafe fn from_raw(user_data: usize) -> Self {
457 let key = unsafe { ErasedKey::from_raw(user_data) };
458 Self(ManuallyDrop::new(key))
459 }
460
461 pub fn upgrade(self) -> ErasedKey {
462 ManuallyDrop::into_inner(self.0)
463 }
464}
465
466impl Deref for BorrowedKey {
467 type Target = ErasedKey;
468
469 fn deref(&self) -> &Self::Target {
470 &self.0
471 }
472}