In this code example, from the Github page of r2d2:
fn main() {
let manager = r2d2_foodb::FooConnectionManager::new("localhost:1234");
let pool = r2d2::Pool::builder()
.max_size(15)
.build(manager)
.unwrap();
for _ in 0..20 {
let pool = pool.clone();
thread::spawn(move || {
let conn = pool.get().unwrap();
})
}
}
Why is the Pool struct being cloned in the loop?
This is because the threads spawned inside the loop need to take ownership of
pool, as each thread could run for longer thanmain. Referencingpoolowned bymainfrom inside a thread could lead to referencing a value that has already been destroyed ifmainexits while the threads are still running.Taking ownership of
poolrequires you to clone it each time the loop executes, so each thread has its own copy.Internally, a
Poolis anstd::sync::Arcand theCloneimplementation simply clones theArc. That is, each clone ofPoolis just an incremented reference count. As the threads are created, the reference count is increased. When the threads finish, they decrement the reference count by dropping theirPool, destroying the underlying connection when the reference count reaches zero.