Skip to content

Commit

Permalink
Merge pull request #762 from uuid-rs/fix/double-lock
Browse files Browse the repository at this point in the history
Avoid taking the shared lock when getting usable bits in Uuid::now_v7
  • Loading branch information
KodrAus authored Jun 24, 2024
2 parents c01feb8 + 20911bd commit d0a2461
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 11 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ v3 = ["md5"]
v4 = ["rng"]
v5 = ["sha1"]
v6 = ["atomic"]
v7 = ["atomic", "rng"]
v7 = ["rng"]
v8 = []

js = ["dep:wasm-bindgen", "getrandom?/js"]
Expand Down
50 changes: 40 additions & 10 deletions src/timestamp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -654,13 +654,23 @@ pub mod context {
use core::{cell::Cell, panic::RefUnwindSafe};

#[cfg(feature = "std")]
static CONTEXT_V7: std::sync::Mutex<ContextV7> = std::sync::Mutex::new(ContextV7::new());
static CONTEXT_V7: SharedContextV7 =
SharedContextV7(std::sync::Mutex::new(ContextV7::new()));

#[cfg(feature = "std")]
pub(crate) fn shared_context_v7() -> &'static std::sync::Mutex<ContextV7> {
pub(crate) fn shared_context_v7() -> &'static SharedContextV7 {
&CONTEXT_V7
}

const USABLE_BITS: usize = 42;

// Leave the most significant bit unset
// This guarantees the counter has at least 2,199,023,255,552
// values before it will overflow, which is exceptionally unlikely
// even in the worst case
const RESEED_MASK: u64 = u64::MAX >> 23;
const MAX_COUNTER: u64 = u64::MAX >> 22;

/// An unsynchronized, reseeding counter that produces 42-bit values.
///
/// This type works by:
Expand Down Expand Up @@ -729,13 +739,6 @@ pub mod context {
seconds: u64,
subsec_nanos: u32,
) -> (Self::Output, u64, u32) {
// Leave the most significant bit unset
// This guarantees the counter has at least 2,199,023,255,552
// values before it will overflow, which is exceptionally unlikely
// even in the worst case
const RESEED_MASK: u64 = u64::MAX >> 23;
const MAX_COUNTER: u64 = u64::MAX >> 22;

let millis = (seconds * 1_000).saturating_add(subsec_nanos as u64 / 1_000_000);

let last_reseed = self.last_reseed.get();
Expand Down Expand Up @@ -785,7 +788,34 @@ pub mod context {
}

fn usable_bits(&self) -> usize {
42
USABLE_BITS
}
}

#[cfg(feature = "std")]
pub(crate) struct SharedContextV7(std::sync::Mutex<ContextV7>);

#[cfg(feature = "std")]
impl ClockSequence for SharedContextV7 {
type Output = u64;

fn generate_sequence(&self, seconds: u64, subsec_nanos: u32) -> Self::Output {
self.0.generate_sequence(seconds, subsec_nanos)
}

fn generate_timestamp_sequence(
&self,
seconds: u64,
subsec_nanos: u32,
) -> (Self::Output, u64, u32) {
self.0.generate_timestamp_sequence(seconds, subsec_nanos)
}

fn usable_bits(&self) -> usize
where
Self::Output: Sized,
{
USABLE_BITS
}
}

Expand Down

0 comments on commit d0a2461

Please sign in to comment.