about summary refs log tree commit diff
path: root/compiler/rustc_thread_pool/src/job.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_thread_pool/src/job.rs')
-rw-r--r--compiler/rustc_thread_pool/src/job.rs40
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 });
     }
 }