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