mirror of
https://github.com/watchexec/watchexec.git
synced 2024-09-20 18:31:29 +02:00
a13bc429eb
Co-authored-by: emilHof <95590295+emilHof@users.noreply.github.com>
68 lines
1.3 KiB
Rust
68 lines
1.3 KiB
Rust
use std::{cell::Cell, num::NonZeroU64};
|
|
|
|
/// Unique opaque identifier.
|
|
#[must_use]
|
|
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
|
|
pub struct Id {
|
|
thread: NonZeroU64,
|
|
counter: u64,
|
|
}
|
|
|
|
thread_local! {
|
|
static COUNTER: Cell<u64> = const { Cell::new(0) };
|
|
}
|
|
|
|
impl Default for Id {
|
|
fn default() -> Self {
|
|
let counter = COUNTER.get();
|
|
COUNTER.set(counter.wrapping_add(1));
|
|
|
|
Self {
|
|
thread: threadid(),
|
|
counter,
|
|
}
|
|
}
|
|
}
|
|
|
|
fn threadid() -> NonZeroU64 {
|
|
use std::hash::{Hash, Hasher};
|
|
|
|
struct Extractor {
|
|
id: u64,
|
|
}
|
|
|
|
impl Hasher for Extractor {
|
|
fn finish(&self) -> u64 {
|
|
self.id
|
|
}
|
|
|
|
fn write(&mut self, _bytes: &[u8]) {}
|
|
fn write_u64(&mut self, n: u64) {
|
|
self.id = n;
|
|
}
|
|
}
|
|
|
|
let mut ex = Extractor { id: 0 };
|
|
std::thread::current().id().hash(&mut ex);
|
|
|
|
// SAFETY: guaranteed to be > 0
|
|
// safeguarded by the max(1), but this is already guaranteed by the thread id being a NonZeroU64
|
|
// internally; as that guarantee is not stable, we do make sure, just to be on the safe side.
|
|
unsafe { NonZeroU64::new_unchecked(ex.finish().max(1)) }
|
|
}
|
|
|
|
// Replace with this when the thread_id_value feature is stable
|
|
// fn threadid() -> NonZeroU64 {
|
|
// std::thread::current().id().as_u64()
|
|
// }
|
|
|
|
#[test]
|
|
fn test_threadid() {
|
|
let top = threadid();
|
|
std::thread::spawn(move || {
|
|
assert_ne!(top, threadid());
|
|
})
|
|
.join()
|
|
.expect("thread failed");
|
|
}
|