hawkw / sharded-slab

a lock-free concurrent slab (experimental)
MIT License
273 stars 19 forks source link

Consider making `PoolGuard: Send` #43

Open oxalica opened 4 years ago

oxalica commented 4 years ago

I'm not sure if it is possible. But currently we cannot simply store an async Mutex in Pool. Since the lifetime of PoolGuard will cross await.

Example:

use async_std::{sync::Mutex, task::spawn};
use sharded_slab::{Clear, Pool};

#[derive(Default)]
struct Data(Mutex<()>);
impl Clear for Data { fn clear(&mut self) {} }

#[async_std::main]
async fn main() {
    let pool: Pool<Data> = Default::default();
    let key = pool.create(|_| {}).unwrap();
    spawn(async move {
        let guard = pool.get(key).unwrap();
        *guard.0.lock().await = (); // <-- error: `guard` is not `Send`
        // -- `guard` is dropped here, crossing `await`
    });
}
hawkw commented 4 years ago

Off the top of my head, I think that it should be possible to make the guard Send. I believe the Shard reference is what is currently making it not Send, but I'm pretty sure it would be safe to add a Send impl for guards. I'll have to think about it to make sure I'm not overlooking anything, though.