execute takes nonnull of job, not ref, because harness might free job

This commit is contained in:
Janis 2025-02-21 20:04:35 +01:00
parent cd4c5467ba
commit c25b62ee3e

View file

@ -739,17 +739,19 @@ mod job {
} }
} }
pub fn execute(&self, scope: &super::Scope) { pub fn execute(job: NonNull<Self>, scope: &super::Scope) {
// SAFETY: self is non-null // SAFETY: self is non-null
unsafe { unsafe {
let (ptr, state) = self.harness_and_state.ptr_and_tag(Ordering::Relaxed); let this = job.as_ref();
debug_assert_eq!(state, JobState::Pending as usize); let (ptr, state) = this.harness_and_state.ptr_and_tag(Ordering::Relaxed);
debug_assert_eq!(state, JobState::Pending as usize);
let harness: unsafe fn(*const (), *const Self, scope: &super::Scope) = let harness: unsafe fn(*const (), *const Self, scope: &super::Scope) =
mem::transmute(ptr.as_ptr()); mem::transmute(ptr.as_ptr());
let this = (*self.val_or_this.get()).this;
harness(this.as_ptr().cast(), (self as *const Self).cast(), scope); let this = (*this.val_or_this.get()).this;
harness(this.as_ptr().cast(), job.as_ptr(), scope);
} }
} }
@ -1096,9 +1098,9 @@ impl Scope {
} }
#[inline] #[inline]
fn execute(&self, job: &Job) { fn execute(&self, job: NonNull<Job>) {
self.tick(); self.tick();
job.execute(self); Job::execute(job, self);
} }
#[cold] #[cold]
@ -1125,9 +1127,7 @@ impl Scope {
if ptr.as_ptr() == &*job as *const _ as *mut _ { if ptr.as_ptr() == &*job as *const _ as *mut _ {
return None; return None;
} else { } else {
unsafe { self.execute(ptr);
self.execute(ptr.as_ref());
}
} }
} }
@ -1148,9 +1148,7 @@ impl Scope {
break; break;
}; };
unsafe { self.execute(job);
self.execute(job.as_ref());
}
} }
// while job isn't done, run other jobs. // while job isn't done, run other jobs.
Some(job.wait()) Some(job.wait())
@ -1279,9 +1277,7 @@ fn worker(ctx: Arc<Context>, barrier: Arc<std::sync::Barrier>) {
let mut job = ctx.shared.lock().jobs.pop_first(); let mut job = ctx.shared.lock().jobs.pop_first();
loop { loop {
if let Some((_, job)) = job { if let Some((_, job)) = job {
unsafe { scope.execute(job);
scope.execute(job.as_ref());
}
} }
let mut guard = ctx.shared.lock(); let mut guard = ctx.shared.lock();