Struct happylock::ThreadKey

source ·
pub struct ThreadKey { /* private fields */ }
Expand description

The key for the current thread.

Only one of these exist per thread. To get the current thread’s key, call ThreadKey::get. If the ThreadKey is dropped, it can be reobtained.

Implementations§

source§

impl ThreadKey

source

pub fn get() -> Option<Self>

Get the current thread’s ThreadKey, if it’s not already taken.

The first time this is called, it will successfully return a ThreadKey. However, future calls to this function on the same thread will return None, unless the key is dropped or unlocked first.

§Examples
use happylock::ThreadKey;

let key = ThreadKey::get().unwrap();
Examples found in repository?
examples/basic.rs (line 13)
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
fn main() {
	let mut threads = Vec::new();
	for _ in 0..N {
		let th = thread::spawn(move || {
			let key = ThreadKey::get().unwrap();
			let mut data = DATA.lock(key);
			*data += 1;
		});
		threads.push(th);
	}

	for th in threads {
		_ = th.join();
	}

	let key = ThreadKey::get().unwrap();
	let data = DATA.lock(key);
	println!("{}", *data);
}
More examples
Hide additional examples
examples/dining_philosophers.rs (line 49)
48
49
50
51
52
53
54
55
56
57
58
59
60
	fn cycle(&self) {
		let key = ThreadKey::get().unwrap();
		thread::sleep(Duration::from_secs(1));

		// safety: no philosopher asks for the same fork twice
		let forks =
			unsafe { LockCollection::new_unchecked([&FORKS[self.left], &FORKS[self.right]]) };
		let forks = forks.lock(key);
		println!("{} is eating...", self.name);
		thread::sleep(Duration::from_secs(1));
		println!("{} is done eating", self.name);
		drop(forks);
	}
examples/double_mutex.rs (line 13)
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
fn main() {
	let mut threads = Vec::new();
	for _ in 0..N {
		let th = thread::spawn(move || {
			let key = ThreadKey::get().unwrap();
			let lock = LockCollection::new_ref(&DATA);
			let mut guard = lock.lock(key);
			*guard.1 = (100 - *guard.0).to_string();
			*guard.0 += 1;
		});
		threads.push(th);
	}

	for th in threads {
		_ = th.join();
	}

	let key = ThreadKey::get().unwrap();
	let data = LockCollection::new_ref(&DATA);
	let data = data.lock(key);
	println!("{}", *data.0);
	println!("{}", *data.1);
}
examples/list.rs (line 32)
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
fn main() {
	let mut threads = Vec::new();
	for _ in 0..N {
		let th = thread::spawn(move || {
			let mut key = ThreadKey::get().unwrap();
			loop {
				let mut data = Vec::new();
				for _ in 0..3 {
					let rand = random(&mut key);
					data.push(&DATA[rand % 6]);
				}

				let Some(lock) = LockCollection::try_new(data) else {
					continue;
				};
				let mut guard = lock.lock(&mut key);
				*guard[0] += *guard[1];
				*guard[1] += *guard[2];
				*guard[2] += *guard[0];

				return;
			}
		});
		threads.push(th);
	}

	for th in threads {
		_ = th.join();
	}

	let key = ThreadKey::get().unwrap();
	let data = LockCollection::new_ref(&DATA);
	let data = data.lock(key);
	for val in &*data {
		println!("{}", **val);
	}
}

Trait Implementations§

source§

impl Debug for ThreadKey

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Drop for ThreadKey

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl Keyable for &mut ThreadKey

source§

impl Keyable for ThreadKey

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.