-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
574 additions
and
378 deletions.
There are no files selected for viewing
This file contains 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 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,61 @@ | ||
//! This example demonstrates how to use an `OSUsers` cache in a | ||
//! multi-threaded situation. The cache uses `RefCell`s internally, so it | ||
//! is distinctly not thread-safe. Instead, you’ll need to place it within | ||
//! some kind of lock in order to have threads access it one-at-a-time. | ||
//! | ||
//! It queries all the users it can find in the range 500..510. This is the | ||
//! default uid range on my Apple laptop -- Linux starts counting from 1000, | ||
//! but I can’t include both in the range! It spawns one thread per user to | ||
//! query, with each thread accessing the same cache. | ||
//! | ||
//! Then, afterwards, it retrieves references to the users that had been | ||
//! cached earlier. | ||
// For extra fun, try uncommenting some of the lines of code below, making | ||
// the code try to access the users cache *without* a Mutex, and see it | ||
// spew compile errors at you. | ||
|
||
extern crate users; | ||
use users::{Users, OSUsers, uid_t}; | ||
|
||
use std::sync::{Arc, Mutex}; | ||
use std::time::Duration; | ||
use std::thread; | ||
|
||
const LO: uid_t = 500; | ||
const HI: uid_t = 510; | ||
|
||
fn main() { | ||
|
||
// For thread-safely, our users cache needs to be within a Mutex, so | ||
// only one thread can access it once. This Mutex needs to be within an | ||
// Arc, so multiple threads can access the Mutex. | ||
let cache = Arc::new(Mutex::new(OSUsers::empty_cache())); | ||
// let cache = OSUsers::empty_cache(); | ||
|
||
// Loop over the range and query all the users in the range. Although we | ||
// could use the `&User` values returned, we just ignore them. | ||
for uid in LO .. HI { | ||
let cache = cache.clone(); | ||
|
||
thread::spawn(move || { | ||
let cache = cache.lock().unwrap(); // Unlock the mutex | ||
let _ = cache.get_user_by_uid(uid); // Query our users cache! | ||
}); | ||
} | ||
|
||
// Wait for all the threads to finish. | ||
thread::sleep(Duration::from_millis(100)); | ||
|
||
// Loop over the same range and print out all the users we find. | ||
// These users will be retrieved from the cache. | ||
for uid in LO .. HI { | ||
let cache = cache.lock().unwrap(); // Re-unlock the mutex | ||
if let Some(u) = cache.get_user_by_uid(uid) { // Re-query our cache! | ||
println!("User #{} is {}", u.uid, u.name) | ||
} | ||
else { | ||
println!("User #{} does not exist", uid); | ||
} | ||
} | ||
} |
Oops, something went wrong.