-
-
Notifications
You must be signed in to change notification settings - Fork 330
Make parse errors implement Send and Sync #536
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
use std::fmt::{self, Debug}; | ||
|
||
use self::thread_id::ThreadId; | ||
|
||
/// ThreadBound is a Sync-maker and Send-maker that allows accessing a value | ||
/// of type T only from the original thread on which the ThreadBound was | ||
/// constructed. | ||
pub struct ThreadBound<T> { | ||
value: T, | ||
thread_id: ThreadId, | ||
} | ||
|
||
unsafe impl<T> Sync for ThreadBound<T> {} | ||
|
||
// Send bound requires Copy, as otherwise Drop could run in the wrong place. | ||
unsafe impl<T: Copy> Send for ThreadBound<T> {} | ||
|
||
impl<T> ThreadBound<T> { | ||
pub fn new(value: T) -> Self { | ||
ThreadBound { | ||
value: value, | ||
thread_id: thread_id::current(), | ||
} | ||
} | ||
|
||
pub fn get(&self) -> Option<&T> { | ||
if thread_id::current() == self.thread_id { | ||
Some(&self.value) | ||
} else { | ||
None | ||
} | ||
} | ||
} | ||
|
||
impl<T: Debug> Debug for ThreadBound<T> { | ||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { | ||
match self.get() { | ||
Some(value) => Debug::fmt(value, formatter), | ||
None => formatter.write_str("unknown"), | ||
} | ||
} | ||
} | ||
|
||
#[cfg(syn_can_use_thread_id)] | ||
mod thread_id { | ||
use std::thread; | ||
|
||
pub use std::thread::ThreadId; | ||
|
||
pub fn current() -> ThreadId { | ||
thread::current().id() | ||
} | ||
} | ||
|
||
#[cfg(not(syn_can_use_thread_id))] | ||
mod thread_id { | ||
use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT}; | ||
|
||
thread_local! { | ||
static THREAD_ID: usize = { | ||
static NEXT_THREAD_ID: AtomicUsize = ATOMIC_USIZE_INIT; | ||
|
||
// Ordering::Relaxed because our only requirement for the ids is | ||
// that they are unique. It is okay for the compiler to rearrange | ||
// other memory reads around this fetch. It's still an atomic | ||
// fetch_add, so no two threads will be able to read the same value | ||
// from it. | ||
// | ||
// The main thing which these orderings affect is other memory reads | ||
// around the atomic read, which for our case are irrelevant as this | ||
// atomic guards nothing. | ||
NEXT_THREAD_ID.fetch_add(1, Ordering::Relaxed) | ||
dtolnay marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}; | ||
} | ||
|
||
pub type ThreadId = usize; | ||
|
||
pub fn current() -> ThreadId { | ||
THREAD_ID.with(|id| *id) | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.