Skip to content

Commit

Permalink
Support Rust 1.24
Browse files Browse the repository at this point in the history
  • Loading branch information
Amanieu committed Sep 9, 2018
1 parent cdfd7ca commit f587876
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 12 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ language: rust
sudo: false

rust:
- 1.24.0
- 1.26.2
- stable
- beta
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ changes to the core API do not cause breaking changes for users of `parking_lot`

## Minimum Rust version

The current minimum required Rust version is 1.26. Any change to this is
The current minimum required Rust version is 1.24. Any change to this is
considered a breaking change and will require a major version bump.

## License
Expand Down
3 changes: 3 additions & 0 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,6 @@ winapi = { version = "0.3", features = ["winnt", "ntstatus", "minwindef",
[features]
nightly = []
deadlock_detection = ["petgraph", "thread-id", "backtrace"]

[build-dependencies]
rustc_version = "0.2"
8 changes: 8 additions & 0 deletions core/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
extern crate rustc_version;
use rustc_version::{version, Version};

fn main() {
if version().unwrap() >= Version::parse("1.26.0").unwrap() {
println!("cargo:rustc-cfg=has_localkey_try_with");
}
}
24 changes: 17 additions & 7 deletions core/src/parking_lot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

use rand::{Rng, FromEntropy};
use rand::rngs::SmallRng;
use rand::{FromEntropy, Rng};
use smallvec::SmallVec;
use std::cell::{Cell, UnsafeCell};
use std::mem;
#[cfg(not(has_localkey_try_with))]
use std::panic;
use std::ptr;
use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
use std::thread::LocalKey;
use std::time::{Duration, Instant};
use thread_parker::ThreadParker;
use util::UncheckedOptionExt;
Expand Down Expand Up @@ -160,13 +163,21 @@ impl ThreadData {

// Returns a ThreadData structure for the current thread
unsafe fn get_thread_data(local: &mut Option<ThreadData>) -> &ThreadData {
// Try to read from thread-local storage, but return a local copy if the TLS
// has already been destroyed.
//
// Try to read from thread-local storage, but return None if the TLS has
// already been destroyed.
#[cfg(has_localkey_try_with)]
fn try_get_tls(key: &'static LocalKey<ThreadData>) -> Option<*const ThreadData> {
key.try_with(|x| x as *const ThreadData).ok()
}
#[cfg(not(has_localkey_try_with))]
fn try_get_tls(key: &'static LocalKey<ThreadData>) -> Option<*const ThreadData> {
panic::catch_unwind(|| key.with(|x| x as *const ThreadData)).ok()
}

// Unlike word_lock::ThreadData, parking_lot::ThreadData is always expensive
// to construct. Try to use a thread-local version if possible.
thread_local!(static THREAD_DATA: ThreadData = ThreadData::new());
if let Ok(tls) = THREAD_DATA.try_with(|x| x as *const ThreadData) {
if let Some(tls) = try_get_tls(&THREAD_DATA) {
return &*tls;
}

Expand Down Expand Up @@ -1176,8 +1187,7 @@ mod deadlock_impl {
.send(DeadlockedThread {
thread_id: td.deadlock_data.thread_id,
backtrace: Backtrace::new(),
})
.unwrap();
}).unwrap();
// make sure to close this sender
drop(sender);

Expand Down
19 changes: 15 additions & 4 deletions core/src/word_lock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@
use spinwait::SpinWait;
use std::cell::Cell;
use std::mem;
#[cfg(not(has_localkey_try_with))]
use std::panic;
use std::ptr;
use std::sync::atomic::{fence, AtomicUsize, Ordering};
use std::thread::LocalKey;
use thread_parker::ThreadParker;

struct ThreadData {
Expand Down Expand Up @@ -45,14 +48,22 @@ impl ThreadData {

// Returns a ThreadData structure for the current thread
unsafe fn get_thread_data(local: &mut Option<ThreadData>) -> &ThreadData {
// Try to read from thread-local storage, but return a local copy if the TLS
// has already been destroyed.
//
// Try to read from thread-local storage, but return None if the TLS has
// already been destroyed.
#[cfg(has_localkey_try_with)]
fn try_get_tls(key: &'static LocalKey<ThreadData>) -> Option<*const ThreadData> {
key.try_with(|x| x as *const ThreadData).ok()
}
#[cfg(not(has_localkey_try_with))]
fn try_get_tls(key: &'static LocalKey<ThreadData>) -> Option<*const ThreadData> {
panic::catch_unwind(|| key.with(|x| x as *const ThreadData)).ok()
}

// If ThreadData is expensive to construct, then we want to use a cached
// version in thread-local storage if possible.
if !cfg!(windows) && !cfg!(all(feature = "nightly", target_os = "linux")) {
thread_local!(static THREAD_DATA: ThreadData = ThreadData::new());
if let Ok(tls) = THREAD_DATA.try_with(|x| x as *const ThreadData) {
if let Some(tls) = try_get_tls(&THREAD_DATA) {
return &*tls;
}
}
Expand Down

0 comments on commit f587876

Please sign in to comment.