Skip to content
This repository has been archived by the owner on Nov 5, 2018. It is now read-only.

Avoid panics when exiting thread #83

Merged
5 commits merged into from Sep 10, 2018
Merged

Avoid panics when exiting thread #83

5 commits merged into from Sep 10, 2018

Conversation

ghost
Copy link

@ghost ghost commented Sep 7, 2018

If we try to call pin() when exiting the thread, it is possible that we'll access the thread-local HANDLE after it has already been destroyed.

This is sometimes a problem when using crossbeam-epoch while the thread is unwinding from a panic. In that case, double panics cause aborts.

To fix the problem, we register a temporary Handle in case HANDLE has already been destroyed.

@ghost
Copy link
Author

ghost commented Sep 7, 2018

Note: servo/servo#21325 is waiting on this PR.

src/default.rs Outdated
#[inline]
fn with_handle<F, R>(mut f: F) -> R
where
F: FnMut(&Handle) -> R,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe FnOnce would be better, since it's only called once anyway? This might require a slight change in the code however.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, that doesn't compile and I don't know how to do better.

error[E0382]: capture of moved value: `f`
  --> src/default.rs:49:50
   |
49 |     HANDLE.try_with(|h| f(h)).unwrap_or_else(|_| f(&COLLECTOR.register()))
   |                     ---                          ^ value captured here after move
   |                     |
   |                     value moved (into closure) here
   |
   = note: move occurs because `f` has type `F`, which does not implement the `Copy` trait

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I thought that it might work with a match statement, however after trying it I see that it doesn't work.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But I think you can pass f directly to try_with right? It doesn't need an extra closure.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need an extra closure. :) Otherwise we get this:

error[E0382]: capture of moved value:
  --> src/default.rs:49:39
   |
49 |     HANDLE.try_with(f).unwrap_or_else(|_| f(&COLLECTOR.register()))
   |                     -                 ^^^ value captured here after move
   |                     |
   |                     value moved here
   |
   = note: move occurs because `f` has type `F`, which does not implement the `Copy` trait

use crossbeam_utils::thread;

#[test]
fn pin_while_exiting() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this only meant to not abort? If so a comment explaining that would be useful, now the test doesn't really make much sense.

src/default.rs Outdated
}

/// Returns the default handle associated with the current thread.
#[inline]
pub fn default_handle() -> Handle {
HANDLE.with(|handle| handle.clone())
with_handle(|handle| handle.clone())
Copy link
Member

@Vtec234 Vtec234 Sep 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is removed in #84.

@ghost ghost merged commit 09d1779 into crossbeam-rs:master Sep 10, 2018
@ghost ghost deleted the fix-abort-when-unwinding branch September 10, 2018 16:16
This pull request was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants