Skip to content

Commit 1ccd394

Browse files
committed
Try dropchk patch again
1 parent 36aa41a commit 1ccd394

File tree

2 files changed

+51
-13
lines changed

2 files changed

+51
-13
lines changed

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#![feature(sync_unsafe_cell)]
2929
#![feature(never_type)]
3030
#![feature(layout_for_ptr)]
31+
#![feature(dropck_eyepatch)]
3132
#![feature(cfg_version)]
3233
#![cfg_attr(not(version("1.76.0")), feature(c_str_literals))]
3334
#![cfg_attr(not(version("1.76.0")), feature(ptr_from_ref))]

src/utils/async.rs

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
#[cfg(feature = "host")]
2-
use std::{borrow::BorrowMut, future::Future, future::IntoFuture, marker::PhantomData, task::Poll};
2+
use std::{
3+
borrow::BorrowMut, future::Future, future::IntoFuture, marker::PhantomData, ptr::NonNull,
4+
task::Poll,
5+
};
36

47
#[cfg(feature = "host")]
58
use rustacuda::{
@@ -272,7 +275,7 @@ impl<'a, 'stream, T: BorrowMut<C::Completed>, C: Completion<T>> Async<'a, 'strea
272275
}
273276
}
274277

275-
pub const fn as_ref(&self) -> AsyncProj<'_, 'stream, &T> {
278+
pub fn as_ref(&self) -> AsyncProj<'_, 'stream, &T> {
276279
// Safety: this projection captures this async
277280
unsafe { AsyncProj::new(&self.value, None) }
278281
}
@@ -327,7 +330,7 @@ impl<'a, 'stream, T: BorrowMut<C::Completed>, C: Completion<T>> Async<'a, 'strea
327330
(
328331
this.stream,
329332
std::ptr::read(&this.value),
330-
(std::ptr::read(&this.status)),
333+
std::ptr::read(&this.status),
331334
)
332335
}
333336
}
@@ -478,7 +481,19 @@ pub struct AsyncProj<'a, 'stream, T: 'a> {
478481
_capture: PhantomData<&'a ()>,
479482
_stream: PhantomData<Stream<'stream>>,
480483
value: T,
481-
use_callback: Option<Box<dyn FnMut() -> CudaResult<()> + 'a>>,
484+
use_callback: Option<NonNull<dyn FnMut() -> CudaResult<()> + 'a>>,
485+
}
486+
487+
#[cfg(feature = "host")]
488+
unsafe impl<#[may_dangle] 'a, 'stream, T: 'a> Drop for AsyncProj<'a, 'stream, T> {
489+
fn drop(&mut self) {
490+
if let Some(use_callback) = self.use_callback.take() {
491+
let layout = unsafe { std::alloc::Layout::for_value_raw(use_callback.as_ptr()) };
492+
if layout.size() != 0 {
493+
unsafe { std::alloc::dealloc(use_callback.as_ptr().cast(), layout) };
494+
}
495+
}
496+
}
482497
}
483498

484499
#[cfg(feature = "host")]
@@ -489,15 +504,16 @@ impl<'a, 'stream, T: 'a> AsyncProj<'a, 'stream, T> {
489504
/// This projection must either capture an existing [`Async`] or come from
490505
/// a source that ensures that the projected value can never (async) move
491506
/// to a different [`Stream`].
492-
pub(crate) const unsafe fn new(
507+
pub(crate) unsafe fn new(
493508
value: T,
494509
use_callback: Option<Box<dyn FnMut() -> CudaResult<()> + 'a>>,
495510
) -> Self {
496511
Self {
497512
_capture: PhantomData::<&'a ()>,
498513
_stream: PhantomData::<Stream<'stream>>,
499514
value,
500-
use_callback,
515+
use_callback: use_callback
516+
.map(|use_callback| unsafe { NonNull::new_unchecked(Box::into_raw(use_callback)) }),
501517
}
502518
}
503519

@@ -511,7 +527,8 @@ impl<'a, 'stream, T: 'a> AsyncProj<'a, 'stream, T> {
511527
/// computation out of smaller ones that have all been submitted to the
512528
/// same [`Stream`].
513529
pub(crate) unsafe fn unwrap_unchecked(self) -> T {
514-
self.value
530+
let (value, _use_callback) = self.unwrap_unchecked_with_use();
531+
value
515532
}
516533

517534
#[allow(clippy::type_complexity)]
@@ -527,7 +544,21 @@ impl<'a, 'stream, T: 'a> AsyncProj<'a, 'stream, T> {
527544
pub(crate) unsafe fn unwrap_unchecked_with_use(
528545
self,
529546
) -> (T, Option<Box<dyn FnMut() -> CudaResult<()> + 'a>>) {
530-
(self.value, self.use_callback)
547+
let this = std::mem::ManuallyDrop::new(self);
548+
549+
// Safety: we destructure self into its droppable components,
550+
// value and use_callback, without dropping self itself
551+
let (value, use_callback) = unsafe {
552+
(
553+
std::ptr::read(&this.value),
554+
std::ptr::read(&this.use_callback),
555+
)
556+
};
557+
558+
(
559+
value,
560+
use_callback.map(|use_callback| Box::from_raw(use_callback.as_ptr())),
561+
)
531562
}
532563
}
533564

@@ -556,16 +587,20 @@ impl<'a, 'stream, T: 'a> AsyncProj<'a, 'stream, T> {
556587
_stream: PhantomData::<Stream<'stream>>,
557588
value: &mut self.value,
558589
use_callback: self.use_callback.as_mut().map(|use_callback| {
590+
let use_callback: &mut dyn FnMut() -> CudaResult<()> =
591+
unsafe { &mut *use_callback.as_ptr() };
559592
let use_callback: Box<dyn FnMut() -> CudaResult<()>> = Box::new(use_callback);
560-
use_callback
593+
unsafe { NonNull::new_unchecked(Box::into_raw(use_callback)) }
561594
}),
562595
}
563596
}
564597

565598
pub(crate) fn record_mut_use(&mut self) -> CudaResult<()> {
566-
self.use_callback
567-
.as_mut()
568-
.map_or(Ok(()), |use_callback| use_callback())
599+
self.use_callback.as_mut().map_or(Ok(()), |use_callback| {
600+
let use_callback: &mut dyn FnMut() -> CudaResult<()> =
601+
unsafe { &mut *use_callback.as_ptr() };
602+
use_callback()
603+
})
569604
}
570605
}
571606

@@ -623,8 +658,10 @@ impl<'a, 'stream, T: 'a> AsyncProj<'a, 'stream, &'a mut T> {
623658
_stream: PhantomData::<Stream<'stream>>,
624659
value: self.value,
625660
use_callback: self.use_callback.as_mut().map(|use_callback| {
661+
let use_callback: &mut dyn FnMut() -> CudaResult<()> =
662+
unsafe { &mut *use_callback.as_ptr() };
626663
let use_callback: Box<dyn FnMut() -> CudaResult<()>> = Box::new(use_callback);
627-
use_callback
664+
unsafe { NonNull::new_unchecked(Box::into_raw(use_callback)) }
628665
}),
629666
}
630667
}

0 commit comments

Comments
 (0)