Created
February 24, 2024 17:35
-
-
Save IAmJSD/3972dc739626f8e24a128acb7d953a07 to your computer and use it in GitHub Desktop.
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
use std::thread; | |
// A container that holds data and the thread ID of the thread that created the container. Note that | |
// this container must be dropped in the same thread that created it, otherwise this will panic since | |
// the thread ID will be different. | |
pub struct ThreadBoundContainer<T> { | |
data: T, | |
thread_id: thread::ThreadId, | |
} | |
impl<T> ThreadBoundContainer<T> { | |
// Creates a new container with the given data. | |
pub fn new(data: T) -> ThreadBoundContainer<T> { | |
ThreadBoundContainer { | |
data, | |
thread_id: thread::current().id(), | |
} | |
} | |
// Gets a reference to the data if the current thread is the same as the one that created the container. | |
pub fn as_ref(&self) -> Result<&T, &'static str> { | |
if self.thread_id == thread::current().id() { | |
Ok(&self.data) | |
} else { | |
Err("Data accessed from wrong thread") | |
} | |
} | |
// Gets a mutable reference to the data if the current thread is the same as the one that created the container. | |
pub fn as_mut(&mut self) -> Result<&mut T, &'static str> { | |
if self.thread_id == thread::current().id() { | |
Ok(&mut self.data) | |
} else { | |
Err("Data accessed from wrong thread") | |
} | |
} | |
} | |
// This is safe to pass between threads because the data is not accessible from other threads. | |
unsafe impl<T> Send for ThreadBoundContainer<T> {} | |
unsafe impl<T> Sync for ThreadBoundContainer<T> {} | |
// Implements drop. Note that this will panic if the container is dropped in a different thread than | |
// the one that created it. | |
impl<T> Drop for ThreadBoundContainer<T> { | |
fn drop(&mut self) { | |
assert_eq!(self.thread_id, thread::current().id()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment