From ad5527601da19b32c63b2c049706f11a22b46d26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Drago=C8=99=20Tiselice?= Date: Fri, 13 Sep 2024 13:04:40 +0300 Subject: [PATCH] Fix racy drop. --- src/job.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/job.rs b/src/job.rs index b61309c..e8ce551 100644 --- a/src/job.rs +++ b/src/job.rs @@ -190,11 +190,18 @@ impl Job { /// It should only be called after being popped from a `JobQueue`. pub unsafe fn wait(&self) -> Option> { - self.fut_or_next - .get() - // Before being popped, the `JobQueue` allocates and store a + self.fut_or_next.get().and_then(|fut| { + // Before being popped, the `JobQueue` allocates and stores a // `Future` in `self.fur_or_next` that should get passed here. - .and_then(|fut| unsafe { Box::from_raw(fut.as_ptr()).wait() }) + let result = unsafe { (*fut.as_ptr()).wait() }; + // We only can drop the `Box` *after* waiting on the `Future` + // in order to ensure unique access. + unsafe { + drop(Box::from_raw(fut.as_ptr())); + } + + result + }) } /// It should only be called in the case where the job has been popped