diff options
Diffstat (limited to 'compiler/rustc_thread_pool/src/job.rs')
| -rw-r--r-- | compiler/rustc_thread_pool/src/job.rs | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/compiler/rustc_thread_pool/src/job.rs b/compiler/rustc_thread_pool/src/job.rs index e6e84ac2320..60a64fe59c9 100644 --- a/compiler/rustc_thread_pool/src/job.rs +++ b/compiler/rustc_thread_pool/src/job.rs @@ -27,6 +27,11 @@ pub(super) trait Job { unsafe fn execute(this: *const ()); } +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub(super) struct JobRefId { + pointer: usize, +} + /// Effectively a Job trait object. Each JobRef **must** be executed /// exactly once, or else data may leak. /// @@ -52,11 +57,9 @@ impl JobRef { JobRef { pointer: data as *const (), execute_fn: <T as Job>::execute } } - /// Returns an opaque handle that can be saved and compared, - /// without making `JobRef` itself `Copy + Eq`. #[inline] - pub(super) fn id(&self) -> impl Eq { - (self.pointer, self.execute_fn) + pub(super) fn id(&self) -> JobRefId { + JobRefId { pointer: self.pointer.expose_provenance() } } #[inline] @@ -100,8 +103,15 @@ where unsafe { JobRef::new(self) } } - pub(super) unsafe fn run_inline(self, stolen: bool) -> R { - self.func.into_inner().unwrap()(stolen) + pub(super) unsafe fn run_inline(&self, stolen: bool) { + unsafe { + let func = (*self.func.get()).take().unwrap(); + *(self.result.get()) = match unwind::halt_unwinding(|| func(stolen)) { + Ok(x) => JobResult::Ok(x), + Err(x) => JobResult::Panic(x), + }; + Latch::set(&self.latch); + } } pub(super) unsafe fn into_result(self) -> R { @@ -138,7 +148,7 @@ where /// (Probably `StackJob` should be refactored in a similar fashion.) pub(super) struct HeapJob<BODY> where - BODY: FnOnce() + Send, + BODY: FnOnce(JobRefId) + Send, { job: BODY, tlv: Tlv, @@ -146,7 +156,7 @@ where impl<BODY> HeapJob<BODY> where - BODY: FnOnce() + Send, + BODY: FnOnce(JobRefId) + Send, { pub(super) fn new(tlv: Tlv, job: BODY) -> Box<Self> { Box::new(HeapJob { job, tlv }) @@ -170,12 +180,13 @@ where impl<BODY> Job for HeapJob<BODY> where - BODY: FnOnce() + Send, + BODY: FnOnce(JobRefId) + Send, { unsafe fn execute(this: *const ()) { + let pointer = this.expose_provenance(); let this = unsafe { Box::from_raw(this as *mut Self) }; tlv::set(this.tlv); - (this.job)(); + (this.job)(JobRefId { pointer }); } } @@ -183,14 +194,14 @@ where /// be turned into multiple `JobRef`s and called multiple times. pub(super) struct ArcJob<BODY> where - BODY: Fn() + Send + Sync, + BODY: Fn(JobRefId) + Send + Sync, { job: BODY, } impl<BODY> ArcJob<BODY> where - BODY: Fn() + Send + Sync, + BODY: Fn(JobRefId) + Send + Sync, { pub(super) fn new(job: BODY) -> Arc<Self> { Arc::new(ArcJob { job }) @@ -214,11 +225,12 @@ where impl<BODY> Job for ArcJob<BODY> where - BODY: Fn() + Send + Sync, + BODY: Fn(JobRefId) + Send + Sync, { unsafe fn execute(this: *const ()) { + let pointer = this.expose_provenance(); let this = unsafe { Arc::from_raw(this as *mut Self) }; - (this.job)(); + (this.job)(JobRefId { pointer }); } } |
