I'm trying to implement a very naive Thread Pool model. For now the responsibilities of the thread pool are:
create
a new thread and return a reference to it- Maintain a map of created threads
- Mutate threads according to different events triggered by threads
My main problem is that the requirement above forces me to let the thread pool keep a HashMap<Id, Thread>
of threads, but also provide a reference to threads when they are created.
On top of that, I need to be able to call methods of the thread pool from inside any thread that effectively end up mutating 1 or more threads (the caller and the targets).
Here is a non functional implementation:
use std::collections::HashMap;
use std::cell::RefCell;
type Id = u32;
type ThreadPoolRef = RefCell<ThreadPool>;
#[derive(Debug)]
struct ThreadPool {
pool: HashMap<Id, RefCell<Thread>>,
id_count: Id
}
impl ThreadPool {
fn new() -> ThreadPool {
ThreadPool {
pool: HashMap::new(),
id_count: 1
}
}
fn create(&mut self) -> &RefCell<Thread> {
let thread: RefCell<Thread> =
RefCell::new(
Thread::new(self.id_count, RefCell::new(self))
);
self.id_count = self.id_count + 1;
self.pool.insert(self.id_count, thread);
self.pool.get(&self.id_count).unwrap()
}
}
#[derive(Debug, Clone)]
struct Thread {
id: Id,
pool: ThreadPoolRef
}
impl Thread {
fn new(id: Id, pool: ThreadPoolRef) -> Thread {
Thread {
id: id,
pool: pool
}
}
}
fn main() {
let thread_pool = ThreadPool::new();
let thread1 = thread_pool.create();
let thread2 = thread_pool.create();
// The final goal is to call thread1.method()
// that mutates thread1 and calls thread_pool.method2()
// which in turn will call thread2.method3() that will effectively
// mutate thread 2
}
I tried several things, like the use of RefCell
but I started to get a lot of lifetime parameters missing errors.
This is a stripped-down version that I expect to be the most simple to explain.