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 than main
. Referencing pool
owned by main
from inside a thread could lead to referencing a value that has already been destroyed if main
exits while the threads are still running.
Taking ownership of pool
requires you to clone it each time the loop executes, so each thread has its own copy.
Internally, a Pool
is an std::sync::Arc
and the Clone
implementation simply clones the Arc
. That is, each clone of Pool
is 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 their Pool
, destroying the underlying connection when the reference count reaches zero.