1 //! A lock-free concurrent object pool. 2 //! 3 //! See the [`Pool` type's documentation][pool] for details on the object pool API and how 4 //! it differs from the [`Slab`] API. 5 //! 6 //! [pool]: ../struct.Pool.html 7 //! [`Slab`]: ../struct.Slab.html 8 use crate::{ 9 cfg::{self, CfgPrivate, DefaultConfig}, 10 clear::Clear, 11 page, shard, 12 tid::Tid, 13 Pack, Shard, 14 }; 15 16 use std::{fmt, marker::PhantomData, sync::Arc}; 17 18 /// A lock-free concurrent object pool. 19 /// 20 /// Slabs provide pre-allocated storage for many instances of a single type. But, when working with 21 /// heap allocated objects, the advantages of a slab are lost, as the memory allocated for the 22 /// object is freed when the object is removed from the slab. With a pool, we can instead reuse 23 /// this memory for objects being added to the pool in the future, therefore reducing memory 24 /// fragmentation and avoiding additional allocations. 25 /// 26 /// This type implements a lock-free concurrent pool, indexed by `usize`s. The items stored in this 27 /// type need to implement [`Clear`] and `Default`. 28 /// 29 /// The `Pool` type shares similar semantics to [`Slab`] when it comes to sharing across threads 30 /// and storing mutable shared data. The biggest difference is there are no [`Slab::insert`] and 31 /// [`Slab::take`] analouges for the `Pool` type. Instead new items are added to the pool by using 32 /// the [`Pool::create`] method, and marked for clearing by the [`Pool::clear`] method. 33 /// 34 /// # Examples 35 /// 36 /// Add an entry to the pool, returning an index: 37 /// ``` 38 /// # use sharded_slab::Pool; 39 /// let pool: Pool<String> = Pool::new(); 40 /// 41 /// let key = pool.create_with(|item| item.push_str("hello world")).unwrap(); 42 /// assert_eq!(pool.get(key).unwrap(), String::from("hello world")); 43 /// ``` 44 /// 45 /// Create a new pooled item, returning a guard that allows mutable access: 46 /// ``` 47 /// # use sharded_slab::Pool; 48 /// let pool: Pool<String> = Pool::new(); 49 /// 50 /// let mut guard = pool.create().unwrap(); 51 /// let key = guard.key(); 52 /// guard.push_str("hello world"); 53 /// 54 /// drop(guard); // release the guard, allowing immutable access. 55 /// assert_eq!(pool.get(key).unwrap(), String::from("hello world")); 56 /// ``` 57 /// 58 /// Pool entries can be cleared by calling [`Pool::clear`]. This marks the entry to 59 /// be cleared when the guards referencing to it are dropped. 60 /// ``` 61 /// # use sharded_slab::Pool; 62 /// let pool: Pool<String> = Pool::new(); 63 /// 64 /// let key = pool.create_with(|item| item.push_str("hello world")).unwrap(); 65 /// 66 /// // Mark this entry to be cleared. 67 /// pool.clear(key); 68 /// 69 /// // The cleared entry is no longer available in the pool 70 /// assert!(pool.get(key).is_none()); 71 /// ``` 72 /// # Configuration 73 /// 74 /// Both `Pool` and [`Slab`] share the same configuration mechanism. See [crate level documentation][config-doc] 75 /// for more details. 76 /// 77 /// [`Slab::take`]: crate::Slab::take 78 /// [`Slab::insert`]: crate::Slab::insert 79 /// [`Pool::create`]: Pool::create 80 /// [`Pool::clear`]: Pool::clear 81 /// [config-doc]: crate#configuration 82 /// [`Clear`]: crate::Clear 83 /// [`Slab`]: crate::Slab 84 pub struct Pool<T, C = DefaultConfig> 85 where 86 T: Clear + Default, 87 C: cfg::Config, 88 { 89 shards: shard::Array<T, C>, 90 _cfg: PhantomData<C>, 91 } 92 93 /// A guard that allows access to an object in a pool. 94 /// 95 /// While the guard exists, it indicates to the pool that the item the guard references is 96 /// currently being accessed. If the item is removed from the pool while the guard exists, the 97 /// removal will be deferred until all guards are dropped. 98 pub struct Ref<'a, T, C = DefaultConfig> 99 where 100 T: Clear + Default, 101 C: cfg::Config, 102 { 103 inner: page::slot::Guard<T, C>, 104 shard: &'a Shard<T, C>, 105 key: usize, 106 } 107 108 /// A guard that allows exclusive mutable access to an object in a pool. 109 /// 110 /// While the guard exists, it indicates to the pool that the item the guard 111 /// references is currently being accessed. If the item is removed from the pool 112 /// while a guard exists, the removal will be deferred until the guard is 113 /// dropped. The slot cannot be accessed by other threads while it is accessed 114 /// mutably. 115 pub struct RefMut<'a, T, C = DefaultConfig> 116 where 117 T: Clear + Default, 118 C: cfg::Config, 119 { 120 inner: page::slot::InitGuard<T, C>, 121 shard: &'a Shard<T, C>, 122 key: usize, 123 } 124 125 /// An owned guard that allows shared immutable access to an object in a pool. 126 /// 127 /// While the guard exists, it indicates to the pool that the item the guard references is 128 /// currently being accessed. If the item is removed from the pool while the guard exists, the 129 /// removal will be deferred until all guards are dropped. 130 /// 131 /// Unlike [`Ref`], which borrows the pool, an `OwnedRef` clones the `Arc` 132 /// around the pool. Therefore, it keeps the pool from being dropped until all 133 /// such guards have been dropped. This means that an `OwnedRef` may be held for 134 /// an arbitrary lifetime. 135 /// 136 /// 137 /// # Examples 138 /// 139 /// ``` 140 /// # use sharded_slab::Pool; 141 /// use std::sync::Arc; 142 /// 143 /// let pool: Arc<Pool<String>> = Arc::new(Pool::new()); 144 /// let key = pool.create_with(|item| item.push_str("hello world")).unwrap(); 145 /// 146 /// // Look up the created `Key`, returning an `OwnedRef`. 147 /// let value = pool.clone().get_owned(key).unwrap(); 148 /// 149 /// // Now, the original `Arc` clone of the pool may be dropped, but the 150 /// // returned `OwnedRef` can still access the value. 151 /// assert_eq!(value, String::from("hello world")); 152 /// ``` 153 /// 154 /// Unlike [`Ref`], an `OwnedRef` may be stored in a struct which must live 155 /// for the `'static` lifetime: 156 /// 157 /// ``` 158 /// # use sharded_slab::Pool; 159 /// use sharded_slab::pool::OwnedRef; 160 /// use std::sync::Arc; 161 /// 162 /// pub struct MyStruct { 163 /// pool_ref: OwnedRef<String>, 164 /// // ... other fields ... 165 /// } 166 /// 167 /// // Suppose this is some arbitrary function which requires a value that 168 /// // lives for the 'static lifetime... 169 /// fn function_requiring_static<T: 'static>(t: &T) { 170 /// // ... do something extremely important and interesting ... 171 /// } 172 /// 173 /// let pool: Arc<Pool<String>> = Arc::new(Pool::new()); 174 /// let key = pool.create_with(|item| item.push_str("hello world")).unwrap(); 175 /// 176 /// // Look up the created `Key`, returning an `OwnedRef`. 177 /// let pool_ref = pool.clone().get_owned(key).unwrap(); 178 /// let my_struct = MyStruct { 179 /// pool_ref, 180 /// // ... 181 /// }; 182 /// 183 /// // We can use `my_struct` anywhere where it is required to have the 184 /// // `'static` lifetime: 185 /// function_requiring_static(&my_struct); 186 /// ``` 187 /// 188 /// `OwnedRef`s may be sent between threads: 189 /// 190 /// ``` 191 /// # use sharded_slab::Pool; 192 /// use std::{thread, sync::Arc}; 193 /// 194 /// let pool: Arc<Pool<String>> = Arc::new(Pool::new()); 195 /// let key = pool.create_with(|item| item.push_str("hello world")).unwrap(); 196 /// 197 /// // Look up the created `Key`, returning an `OwnedRef`. 198 /// let value = pool.clone().get_owned(key).unwrap(); 199 /// 200 /// thread::spawn(move || { 201 /// assert_eq!(value, String::from("hello world")); 202 /// // ... 203 /// }).join().unwrap(); 204 /// ``` 205 /// 206 /// [`Ref`]: crate::pool::Ref 207 pub struct OwnedRef<T, C = DefaultConfig> 208 where 209 T: Clear + Default, 210 C: cfg::Config, 211 { 212 inner: page::slot::Guard<T, C>, 213 pool: Arc<Pool<T, C>>, 214 key: usize, 215 } 216 217 /// An owned guard that allows exclusive, mutable access to an object in a pool. 218 /// 219 /// An `OwnedRefMut<T>` functions more or less identically to an owned 220 /// `Box<T>`: it can be passed to functions, stored in structure fields, and 221 /// borrowed mutably or immutably, and can be owned for arbitrary lifetimes. 222 /// The difference is that, unlike a `Box<T>`, the memory allocation for the 223 /// `T` lives in the `Pool`; when an `OwnedRefMut` is created, it may reuse 224 /// memory that was allocated for a previous pooled object that has been 225 /// cleared. Additionally, the `OwnedRefMut` may be [downgraded] to an 226 /// [`OwnedRef`] which may be shared freely, essentially turning the `Box` 227 /// into an `Arc`. 228 /// 229 /// This is returned by [`Pool::create_owned`]. 230 /// 231 /// While the guard exists, it indicates to the pool that the item the guard 232 /// references is currently being accessed. If the item is removed from the pool 233 /// while the guard exists, theremoval will be deferred until all guards are 234 /// dropped. 235 /// 236 /// Unlike [`RefMut`], which borrows the pool, an `OwnedRefMut` clones the `Arc` 237 /// around the pool. Therefore, it keeps the pool from being dropped until all 238 /// such guards have been dropped. This means that an `OwnedRefMut` may be held for 239 /// an arbitrary lifetime. 240 /// 241 /// # Examples 242 /// 243 /// ```rust 244 /// # use sharded_slab::Pool; 245 /// # use std::thread; 246 /// use std::sync::Arc; 247 /// 248 /// let pool: Arc<Pool<String>> = Arc::new(Pool::new()); 249 /// 250 /// // Create a new pooled item, returning an owned guard that allows mutable 251 /// // access to the new item. 252 /// let mut item = pool.clone().create_owned().unwrap(); 253 /// // Return a key that allows indexing the created item once the guard 254 /// // has been dropped. 255 /// let key = item.key(); 256 /// 257 /// // Mutate the item. 258 /// item.push_str("Hello"); 259 /// // Drop the guard, releasing mutable access to the new item. 260 /// drop(item); 261 /// 262 /// /// Other threads may now (immutably) access the item using the returned key. 263 /// thread::spawn(move || { 264 /// assert_eq!(pool.get(key).unwrap(), String::from("Hello")); 265 /// }).join().unwrap(); 266 /// ``` 267 /// 268 /// ```rust 269 /// # use sharded_slab::Pool; 270 /// use std::sync::Arc; 271 /// 272 /// let pool: Arc<Pool<String>> = Arc::new(Pool::new()); 273 /// 274 /// // Create a new item, returning an owned, mutable guard. 275 /// let mut value = pool.clone().create_owned().unwrap(); 276 /// 277 /// // Now, the original `Arc` clone of the pool may be dropped, but the 278 /// // returned `OwnedRefMut` can still access the value. 279 /// drop(pool); 280 /// 281 /// value.push_str("hello world"); 282 /// assert_eq!(value, String::from("hello world")); 283 /// ``` 284 /// 285 /// Unlike [`RefMut`], an `OwnedRefMut` may be stored in a struct which must live 286 /// for the `'static` lifetime: 287 /// 288 /// ``` 289 /// # use sharded_slab::Pool; 290 /// use sharded_slab::pool::OwnedRefMut; 291 /// use std::sync::Arc; 292 /// 293 /// pub struct MyStruct { 294 /// pool_ref: OwnedRefMut<String>, 295 /// // ... other fields ... 296 /// } 297 /// 298 /// // Suppose this is some arbitrary function which requires a value that 299 /// // lives for the 'static lifetime... 300 /// fn function_requiring_static<T: 'static>(t: &T) { 301 /// // ... do something extremely important and interesting ... 302 /// } 303 /// 304 /// let pool: Arc<Pool<String>> = Arc::new(Pool::new()); 305 /// 306 /// // Create a new item, returning a mutable owned reference. 307 /// let pool_ref = pool.clone().create_owned().unwrap(); 308 /// 309 /// let my_struct = MyStruct { 310 /// pool_ref, 311 /// // ... 312 /// }; 313 /// 314 /// // We can use `my_struct` anywhere where it is required to have the 315 /// // `'static` lifetime: 316 /// function_requiring_static(&my_struct); 317 /// ``` 318 /// 319 /// `OwnedRefMut`s may be sent between threads: 320 /// 321 /// ``` 322 /// # use sharded_slab::Pool; 323 /// use std::{thread, sync::Arc}; 324 /// 325 /// let pool: Arc<Pool<String>> = Arc::new(Pool::new()); 326 /// 327 /// let mut value = pool.clone().create_owned().unwrap(); 328 /// let key = value.key(); 329 /// 330 /// thread::spawn(move || { 331 /// value.push_str("hello world"); 332 /// // ... 333 /// }).join().unwrap(); 334 /// 335 /// // Once the `OwnedRefMut` has been dropped by the other thread, we may 336 /// // now access the value immutably on this thread. 337 /// 338 /// assert_eq!(pool.get(key).unwrap(), String::from("hello world")); 339 /// ``` 340 /// 341 /// Downgrading from a mutable to an immutable reference: 342 /// 343 /// ``` 344 /// # use sharded_slab::Pool; 345 /// use std::{thread, sync::Arc}; 346 /// 347 /// let pool: Arc<Pool<String>> = Arc::new(Pool::new()); 348 /// 349 /// let mut value = pool.clone().create_owned().unwrap(); 350 /// let key = value.key(); 351 /// value.push_str("hello world"); 352 /// 353 /// // Downgrade the mutable owned ref to an immutable owned ref. 354 /// let value = value.downgrade(); 355 /// 356 /// // Once the `OwnedRefMut` has been downgraded, other threads may 357 /// // immutably access the pooled value: 358 /// thread::spawn(move || { 359 /// assert_eq!(pool.get(key).unwrap(), String::from("hello world")); 360 /// }).join().unwrap(); 361 /// 362 /// // This thread can still access the pooled value through the 363 /// // immutable owned ref: 364 /// assert_eq!(value, String::from("hello world")); 365 /// ``` 366 /// 367 /// [`Pool::create_owned`]: crate::Pool::create_owned 368 /// [`RefMut`]: crate::pool::RefMut 369 /// [`OwnedRefMut`]: crate::pool::OwnedRefMut 370 /// [downgraded]: crate::pool::OwnedRefMut::downgrade 371 pub struct OwnedRefMut<T, C = DefaultConfig> 372 where 373 T: Clear + Default, 374 C: cfg::Config, 375 { 376 inner: page::slot::InitGuard<T, C>, 377 pool: Arc<Pool<T, C>>, 378 key: usize, 379 } 380 381 impl<T> Pool<T> 382 where 383 T: Clear + Default, 384 { 385 /// Returns a new `Pool` with the default configuration parameters. new() -> Self386 pub fn new() -> Self { 387 Self::new_with_config() 388 } 389 390 /// Returns a new `Pool` with the provided configuration parameters. new_with_config<C: cfg::Config>() -> Pool<T, C>391 pub fn new_with_config<C: cfg::Config>() -> Pool<T, C> { 392 C::validate(); 393 Pool { 394 shards: shard::Array::new(), 395 _cfg: PhantomData, 396 } 397 } 398 } 399 400 impl<T, C> Pool<T, C> 401 where 402 T: Clear + Default, 403 C: cfg::Config, 404 { 405 /// The number of bits in each index which are used by the pool. 406 /// 407 /// If other data is packed into the `usize` indices returned by 408 /// [`Pool::create`], user code is free to use any bits higher than the 409 /// `USED_BITS`-th bit freely. 410 /// 411 /// This is determined by the [`Config`] type that configures the pool's 412 /// parameters. By default, all bits are used; this can be changed by 413 /// overriding the [`Config::RESERVED_BITS`][res] constant. 414 /// 415 /// [`Config`]: trait.Config.html 416 /// [res]: trait.Config.html#associatedconstant.RESERVED_BITS 417 /// [`Slab::insert`]: struct.Slab.html#method.insert 418 pub const USED_BITS: usize = C::USED_BITS; 419 420 /// Creates a new object in the pool, returning an [`RefMut`] guard that 421 /// may be used to mutate the new object. 422 /// 423 /// If this function returns `None`, then the shard for the current thread is full and no items 424 /// can be added until some are removed, or the maximum number of shards has been reached. 425 /// 426 /// # Examples 427 /// ```rust 428 /// # use sharded_slab::Pool; 429 /// # use std::thread; 430 /// let pool: Pool<String> = Pool::new(); 431 /// 432 /// // Create a new pooled item, returning a guard that allows mutable 433 /// // access to the new item. 434 /// let mut item = pool.create().unwrap(); 435 /// // Return a key that allows indexing the created item once the guard 436 /// // has been dropped. 437 /// let key = item.key(); 438 /// 439 /// // Mutate the item. 440 /// item.push_str("Hello"); 441 /// // Drop the guard, releasing mutable access to the new item. 442 /// drop(item); 443 /// 444 /// /// Other threads may now (immutably) access the item using the returned key. 445 /// thread::spawn(move || { 446 /// assert_eq!(pool.get(key).unwrap(), String::from("Hello")); 447 /// }).join().unwrap(); 448 /// ``` 449 /// 450 /// [`RefMut`]: crate::pool::RefMut create(&self) -> Option<RefMut<'_, T, C>>451 pub fn create(&self) -> Option<RefMut<'_, T, C>> { 452 let (tid, shard) = self.shards.current(); 453 test_println!("pool: create {:?}", tid); 454 let (key, inner) = shard.init_with(|idx, slot| { 455 let guard = slot.init()?; 456 let gen = guard.generation(); 457 Some((gen.pack(idx), guard)) 458 })?; 459 Some(RefMut { 460 inner, 461 key: tid.pack(key), 462 shard, 463 }) 464 } 465 466 /// Creates a new object in the pool, returning an [`OwnedRefMut`] guard that 467 /// may be used to mutate the new object. 468 /// 469 /// If this function returns `None`, then the shard for the current thread 470 /// is full and no items can be added until some are removed, or the maximum 471 /// number of shards has been reached. 472 /// 473 /// Unlike [`create`], which borrows the pool, this method _clones_ the `Arc` 474 /// around the pool if a value exists for the given key. This means that the 475 /// returned [`OwnedRefMut`] can be held for an arbitrary lifetime. However, 476 /// this method requires that the pool itself be wrapped in an `Arc`. 477 /// 478 /// An `OwnedRefMut<T>` functions more or less identically to an owned 479 /// `Box<T>`: it can be passed to functions, stored in structure fields, and 480 /// borrowed mutably or immutably, and can be owned for arbitrary lifetimes. 481 /// The difference is that, unlike a `Box<T>`, the memory allocation for the 482 /// `T` lives in the `Pool`; when an `OwnedRefMut` is created, it may reuse 483 /// memory that was allocated for a previous pooled object that has been 484 /// cleared. Additionally, the `OwnedRefMut` may be [downgraded] to an 485 /// [`OwnedRef`] which may be shared freely, essentially turning the `Box` 486 /// into an `Arc`. 487 /// 488 /// # Examples 489 /// 490 /// ```rust 491 /// # use sharded_slab::Pool; 492 /// # use std::thread; 493 /// use std::sync::Arc; 494 /// 495 /// let pool: Arc<Pool<String>> = Arc::new(Pool::new()); 496 /// 497 /// // Create a new pooled item, returning an owned guard that allows mutable 498 /// // access to the new item. 499 /// let mut item = pool.clone().create_owned().unwrap(); 500 /// // Return a key that allows indexing the created item once the guard 501 /// // has been dropped. 502 /// let key = item.key(); 503 /// 504 /// // Mutate the item. 505 /// item.push_str("Hello"); 506 /// // Drop the guard, releasing mutable access to the new item. 507 /// drop(item); 508 /// 509 /// /// Other threads may now (immutably) access the item using the returned key. 510 /// thread::spawn(move || { 511 /// assert_eq!(pool.get(key).unwrap(), String::from("Hello")); 512 /// }).join().unwrap(); 513 /// ``` 514 /// 515 /// ```rust 516 /// # use sharded_slab::Pool; 517 /// use std::sync::Arc; 518 /// 519 /// let pool: Arc<Pool<String>> = Arc::new(Pool::new()); 520 /// 521 /// // Create a new item, returning an owned, mutable guard. 522 /// let mut value = pool.clone().create_owned().unwrap(); 523 /// 524 /// // Now, the original `Arc` clone of the pool may be dropped, but the 525 /// // returned `OwnedRefMut` can still access the value. 526 /// drop(pool); 527 /// 528 /// value.push_str("hello world"); 529 /// assert_eq!(value, String::from("hello world")); 530 /// ``` 531 /// 532 /// Unlike [`RefMut`], an `OwnedRefMut` may be stored in a struct which must live 533 /// for the `'static` lifetime: 534 /// 535 /// ``` 536 /// # use sharded_slab::Pool; 537 /// use sharded_slab::pool::OwnedRefMut; 538 /// use std::sync::Arc; 539 /// 540 /// pub struct MyStruct { 541 /// pool_ref: OwnedRefMut<String>, 542 /// // ... other fields ... 543 /// } 544 /// 545 /// // Suppose this is some arbitrary function which requires a value that 546 /// // lives for the 'static lifetime... 547 /// fn function_requiring_static<T: 'static>(t: &T) { 548 /// // ... do something extremely important and interesting ... 549 /// } 550 /// 551 /// let pool: Arc<Pool<String>> = Arc::new(Pool::new()); 552 /// 553 /// // Create a new item, returning a mutable owned reference. 554 /// let pool_ref = pool.clone().create_owned().unwrap(); 555 /// 556 /// let my_struct = MyStruct { 557 /// pool_ref, 558 /// // ... 559 /// }; 560 /// 561 /// // We can use `my_struct` anywhere where it is required to have the 562 /// // `'static` lifetime: 563 /// function_requiring_static(&my_struct); 564 /// ``` 565 /// 566 /// `OwnedRefMut`s may be sent between threads: 567 /// 568 /// ``` 569 /// # use sharded_slab::Pool; 570 /// use std::{thread, sync::Arc}; 571 /// 572 /// let pool: Arc<Pool<String>> = Arc::new(Pool::new()); 573 /// 574 /// let mut value = pool.clone().create_owned().unwrap(); 575 /// let key = value.key(); 576 /// 577 /// thread::spawn(move || { 578 /// value.push_str("hello world"); 579 /// // ... 580 /// }).join().unwrap(); 581 /// 582 /// // Once the `OwnedRefMut` has been dropped by the other thread, we may 583 /// // now access the value immutably on this thread. 584 /// 585 /// assert_eq!(pool.get(key).unwrap(), String::from("hello world")); 586 /// ``` 587 /// 588 /// Downgrading from a mutable to an immutable reference: 589 /// 590 /// ``` 591 /// # use sharded_slab::Pool; 592 /// use std::{thread, sync::Arc}; 593 /// 594 /// let pool: Arc<Pool<String>> = Arc::new(Pool::new()); 595 /// 596 /// let mut value = pool.clone().create_owned().unwrap(); 597 /// let key = value.key(); 598 /// value.push_str("hello world"); 599 /// 600 /// // Downgrade the mutable owned ref to an immutable owned ref. 601 /// let value = value.downgrade(); 602 /// 603 /// // Once the `OwnedRefMut` has been downgraded, other threads may 604 /// // immutably access the pooled value: 605 /// thread::spawn(move || { 606 /// assert_eq!(pool.get(key).unwrap(), String::from("hello world")); 607 /// }).join().unwrap(); 608 /// 609 /// // This thread can still access the pooled value through the 610 /// // immutable owned ref: 611 /// assert_eq!(value, String::from("hello world")); 612 /// ``` 613 /// 614 /// [`create`]: Pool::create 615 /// [`OwnedRef`]: crate::pool::OwnedRef 616 /// [`RefMut`]: crate::pool::RefMut 617 /// [`OwnedRefMut`]: crate::pool::OwnedRefMut 618 /// [downgraded]: crate::pool::OwnedRefMut::downgrade create_owned(self: Arc<Self>) -> Option<OwnedRefMut<T, C>>619 pub fn create_owned(self: Arc<Self>) -> Option<OwnedRefMut<T, C>> { 620 let (tid, shard) = self.shards.current(); 621 test_println!("pool: create_owned {:?}", tid); 622 let (inner, key) = shard.init_with(|idx, slot| { 623 let inner = slot.init()?; 624 let gen = inner.generation(); 625 Some((inner, tid.pack(gen.pack(idx)))) 626 })?; 627 Some(OwnedRefMut { 628 inner, 629 pool: self, 630 key, 631 }) 632 } 633 634 /// Creates a new object in the pool with the provided initializer, 635 /// returning a key that may be used to access the new object. 636 /// 637 /// If this function returns `None`, then the shard for the current thread is full and no items 638 /// can be added until some are removed, or the maximum number of shards has been reached. 639 /// 640 /// # Examples 641 /// ```rust 642 /// # use sharded_slab::Pool; 643 /// # use std::thread; 644 /// let pool: Pool<String> = Pool::new(); 645 /// 646 /// // Create a new pooled item, returning its integer key. 647 /// let key = pool.create_with(|s| s.push_str("Hello")).unwrap(); 648 /// 649 /// /// Other threads may now (immutably) access the item using the key. 650 /// thread::spawn(move || { 651 /// assert_eq!(pool.get(key).unwrap(), String::from("Hello")); 652 /// }).join().unwrap(); 653 /// ``` create_with(&self, init: impl FnOnce(&mut T)) -> Option<usize>654 pub fn create_with(&self, init: impl FnOnce(&mut T)) -> Option<usize> { 655 test_println!("pool: create_with"); 656 let mut guard = self.create()?; 657 init(&mut guard); 658 Some(guard.key()) 659 } 660 661 /// Return a borrowed reference to the value associated with the given key. 662 /// 663 /// If the pool does not contain a value for the given key, `None` is returned instead. 664 /// 665 /// # Examples 666 /// 667 /// ```rust 668 /// # use sharded_slab::Pool; 669 /// let pool: Pool<String> = Pool::new(); 670 /// let key = pool.create_with(|item| item.push_str("hello world")).unwrap(); 671 /// 672 /// assert_eq!(pool.get(key).unwrap(), String::from("hello world")); 673 /// assert!(pool.get(12345).is_none()); 674 /// ``` get(&self, key: usize) -> Option<Ref<'_, T, C>>675 pub fn get(&self, key: usize) -> Option<Ref<'_, T, C>> { 676 let tid = C::unpack_tid(key); 677 678 test_println!("pool: get{:?}; current={:?}", tid, Tid::<C>::current()); 679 let shard = self.shards.get(tid.as_usize())?; 680 let inner = shard.with_slot(key, |slot| slot.get(C::unpack_gen(key)))?; 681 Some(Ref { inner, shard, key }) 682 } 683 684 /// Return an owned reference to the value associated with the given key. 685 /// 686 /// If the pool does not contain a value for the given key, `None` is 687 /// returned instead. 688 /// 689 /// Unlike [`get`], which borrows the pool, this method _clones_ the `Arc` 690 /// around the pool if a value exists for the given key. This means that the 691 /// returned [`OwnedRef`] can be held for an arbitrary lifetime. However, 692 /// this method requires that the pool itself be wrapped in an `Arc`. 693 /// 694 /// # Examples 695 /// 696 /// ```rust 697 /// # use sharded_slab::Pool; 698 /// use std::sync::Arc; 699 /// 700 /// let pool: Arc<Pool<String>> = Arc::new(Pool::new()); 701 /// let key = pool.create_with(|item| item.push_str("hello world")).unwrap(); 702 /// 703 /// // Look up the created `Key`, returning an `OwnedRef`. 704 /// let value = pool.clone().get_owned(key).unwrap(); 705 /// 706 /// // Now, the original `Arc` clone of the pool may be dropped, but the 707 /// // returned `OwnedRef` can still access the value. 708 /// assert_eq!(value, String::from("hello world")); 709 /// ``` 710 /// 711 /// Unlike [`Ref`], an `OwnedRef` may be stored in a struct which must live 712 /// for the `'static` lifetime: 713 /// 714 /// ``` 715 /// # use sharded_slab::Pool; 716 /// use sharded_slab::pool::OwnedRef; 717 /// use std::sync::Arc; 718 /// 719 /// pub struct MyStruct { 720 /// pool_ref: OwnedRef<String>, 721 /// // ... other fields ... 722 /// } 723 /// 724 /// // Suppose this is some arbitrary function which requires a value that 725 /// // lives for the 'static lifetime... 726 /// fn function_requiring_static<T: 'static>(t: &T) { 727 /// // ... do something extremely important and interesting ... 728 /// } 729 /// 730 /// let pool: Arc<Pool<String>> = Arc::new(Pool::new()); 731 /// let key = pool.create_with(|item| item.push_str("hello world")).unwrap(); 732 /// 733 /// // Look up the created `Key`, returning an `OwnedRef`. 734 /// let pool_ref = pool.clone().get_owned(key).unwrap(); 735 /// let my_struct = MyStruct { 736 /// pool_ref, 737 /// // ... 738 /// }; 739 /// 740 /// // We can use `my_struct` anywhere where it is required to have the 741 /// // `'static` lifetime: 742 /// function_requiring_static(&my_struct); 743 /// ``` 744 /// 745 /// `OwnedRef`s may be sent between threads: 746 /// 747 /// ``` 748 /// # use sharded_slab::Pool; 749 /// use std::{thread, sync::Arc}; 750 /// 751 /// let pool: Arc<Pool<String>> = Arc::new(Pool::new()); 752 /// let key = pool.create_with(|item| item.push_str("hello world")).unwrap(); 753 /// 754 /// // Look up the created `Key`, returning an `OwnedRef`. 755 /// let value = pool.clone().get_owned(key).unwrap(); 756 /// 757 /// thread::spawn(move || { 758 /// assert_eq!(value, String::from("hello world")); 759 /// // ... 760 /// }).join().unwrap(); 761 /// ``` 762 /// 763 /// [`get`]: Pool::get 764 /// [`OwnedRef`]: crate::pool::OwnedRef 765 /// [`Ref`]: crate::pool::Ref get_owned(self: Arc<Self>, key: usize) -> Option<OwnedRef<T, C>>766 pub fn get_owned(self: Arc<Self>, key: usize) -> Option<OwnedRef<T, C>> { 767 let tid = C::unpack_tid(key); 768 769 test_println!("pool: get{:?}; current={:?}", tid, Tid::<C>::current()); 770 let shard = self.shards.get(tid.as_usize())?; 771 let inner = shard.with_slot(key, |slot| slot.get(C::unpack_gen(key)))?; 772 Some(OwnedRef { 773 inner, 774 pool: self.clone(), 775 key, 776 }) 777 } 778 779 /// Remove the value using the storage associated with the given key from the pool, returning 780 /// `true` if the value was removed. 781 /// 782 /// This method does _not_ block the current thread until the value can be 783 /// cleared. Instead, if another thread is currently accessing that value, this marks it to be 784 /// cleared by that thread when it is done accessing that value. 785 /// 786 /// # Examples 787 /// 788 /// ```rust 789 /// # use sharded_slab::Pool; 790 /// let pool: Pool<String> = Pool::new(); 791 /// 792 /// // Check out an item from the pool. 793 /// let mut item = pool.create().unwrap(); 794 /// let key = item.key(); 795 /// item.push_str("hello world"); 796 /// drop(item); 797 /// 798 /// assert_eq!(pool.get(key).unwrap(), String::from("hello world")); 799 /// 800 /// pool.clear(key); 801 /// assert!(pool.get(key).is_none()); 802 /// ``` 803 /// 804 /// ``` 805 /// # use sharded_slab::Pool; 806 /// let pool: Pool<String> = Pool::new(); 807 /// 808 /// let key = pool.create_with(|item| item.push_str("Hello world!")).unwrap(); 809 /// 810 /// // Clearing a key that doesn't exist in the `Pool` will return `false` 811 /// assert_eq!(pool.clear(key + 69420), false); 812 /// 813 /// // Clearing a key that does exist returns `true` 814 /// assert!(pool.clear(key)); 815 /// 816 /// // Clearing a key that has previously been cleared will return `false` 817 /// assert_eq!(pool.clear(key), false); 818 /// ``` 819 /// [`clear`]: #method.clear clear(&self, key: usize) -> bool820 pub fn clear(&self, key: usize) -> bool { 821 let tid = C::unpack_tid(key); 822 823 let shard = self.shards.get(tid.as_usize()); 824 if tid.is_current() { 825 shard 826 .map(|shard| shard.mark_clear_local(key)) 827 .unwrap_or(false) 828 } else { 829 shard 830 .map(|shard| shard.mark_clear_remote(key)) 831 .unwrap_or(false) 832 } 833 } 834 } 835 836 unsafe impl<T, C> Send for Pool<T, C> 837 where 838 T: Send + Clear + Default, 839 C: cfg::Config, 840 { 841 } 842 unsafe impl<T, C> Sync for Pool<T, C> 843 where 844 T: Sync + Clear + Default, 845 C: cfg::Config, 846 { 847 } 848 849 impl<T> Default for Pool<T> 850 where 851 T: Clear + Default, 852 { default() -> Self853 fn default() -> Self { 854 Self::new() 855 } 856 } 857 858 impl<T, C> fmt::Debug for Pool<T, C> 859 where 860 T: fmt::Debug + Clear + Default, 861 C: cfg::Config, 862 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result863 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 864 f.debug_struct("Pool") 865 .field("shards", &self.shards) 866 .field("config", &C::debug()) 867 .finish() 868 } 869 } 870 871 // === impl Ref === 872 873 impl<'a, T, C> Ref<'a, T, C> 874 where 875 T: Clear + Default, 876 C: cfg::Config, 877 { 878 /// Returns the key used to access this guard key(&self) -> usize879 pub fn key(&self) -> usize { 880 self.key 881 } 882 883 #[inline] value(&self) -> &T884 fn value(&self) -> &T { 885 unsafe { 886 // Safety: calling `slot::Guard::value` is unsafe, since the `Guard` 887 // value contains a pointer to the slot that may outlive the slab 888 // containing that slot. Here, the `Ref` has a borrowed reference to 889 // the shard containing that slot, which ensures that the slot will 890 // not be dropped while this `Guard` exists. 891 self.inner.value() 892 } 893 } 894 } 895 896 impl<'a, T, C> std::ops::Deref for Ref<'a, T, C> 897 where 898 T: Clear + Default, 899 C: cfg::Config, 900 { 901 type Target = T; 902 deref(&self) -> &Self::Target903 fn deref(&self) -> &Self::Target { 904 self.value() 905 } 906 } 907 908 impl<'a, T, C> Drop for Ref<'a, T, C> 909 where 910 T: Clear + Default, 911 C: cfg::Config, 912 { drop(&mut self)913 fn drop(&mut self) { 914 test_println!("drop Ref: try clearing data"); 915 let should_clear = unsafe { 916 // Safety: calling `slot::Guard::release` is unsafe, since the 917 // `Guard` value contains a pointer to the slot that may outlive the 918 // slab containing that slot. Here, the `Ref` guard owns a 919 // borrowed reference to the shard containing that slot, which 920 // ensures that the slot will not be dropped while this `Ref` 921 // exists. 922 self.inner.release() 923 }; 924 if should_clear { 925 self.shard.clear_after_release(self.key); 926 } 927 } 928 } 929 930 impl<'a, T, C> fmt::Debug for Ref<'a, T, C> 931 where 932 T: fmt::Debug + Clear + Default, 933 C: cfg::Config, 934 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result935 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 936 fmt::Debug::fmt(self.value(), f) 937 } 938 } 939 940 impl<'a, T, C> PartialEq<T> for Ref<'a, T, C> 941 where 942 T: PartialEq<T> + Clear + Default, 943 C: cfg::Config, 944 { eq(&self, other: &T) -> bool945 fn eq(&self, other: &T) -> bool { 946 *self.value() == *other 947 } 948 } 949 950 // === impl GuardMut === 951 952 impl<'a, T, C: cfg::Config> RefMut<'a, T, C> 953 where 954 T: Clear + Default, 955 C: cfg::Config, 956 { 957 /// Returns the key used to access the guard. key(&self) -> usize958 pub fn key(&self) -> usize { 959 self.key 960 } 961 962 /// Downgrades the mutable guard to an immutable guard, allowing access to 963 /// the pooled value from other threads. 964 /// 965 /// ## Examples 966 /// 967 /// ``` 968 /// # use sharded_slab::Pool; 969 /// # use std::{sync::Arc, thread}; 970 /// let pool = Arc::new(Pool::<String>::new()); 971 /// 972 /// let mut guard_mut = pool.clone().create_owned().unwrap(); 973 /// let key = guard_mut.key(); 974 /// guard_mut.push_str("Hello"); 975 /// 976 /// // The pooled string is currently borrowed mutably, so other threads 977 /// // may not access it. 978 /// let pool2 = pool.clone(); 979 /// thread::spawn(move || { 980 /// assert!(pool2.get(key).is_none()) 981 /// }).join().unwrap(); 982 /// 983 /// // Downgrade the guard to an immutable reference. 984 /// let guard = guard_mut.downgrade(); 985 /// 986 /// // Now, other threads may also access the pooled value. 987 /// let pool2 = pool.clone(); 988 /// thread::spawn(move || { 989 /// let guard = pool2.get(key) 990 /// .expect("the item may now be referenced by other threads"); 991 /// assert_eq!(guard, String::from("Hello")); 992 /// }).join().unwrap(); 993 /// 994 /// // We can still access the value immutably through the downgraded guard. 995 /// assert_eq!(guard, String::from("Hello")); 996 /// ``` downgrade(mut self) -> Ref<'a, T, C>997 pub fn downgrade(mut self) -> Ref<'a, T, C> { 998 let inner = unsafe { self.inner.downgrade() }; 999 Ref { 1000 inner, 1001 shard: self.shard, 1002 key: self.key, 1003 } 1004 } 1005 1006 #[inline] value(&self) -> &T1007 fn value(&self) -> &T { 1008 unsafe { 1009 // Safety: we are holding a reference to the shard which keeps the 1010 // pointed slot alive. The returned reference will not outlive 1011 // `self`. 1012 self.inner.value() 1013 } 1014 } 1015 } 1016 1017 impl<'a, T, C: cfg::Config> std::ops::Deref for RefMut<'a, T, C> 1018 where 1019 T: Clear + Default, 1020 C: cfg::Config, 1021 { 1022 type Target = T; 1023 deref(&self) -> &Self::Target1024 fn deref(&self) -> &Self::Target { 1025 self.value() 1026 } 1027 } 1028 1029 impl<'a, T, C> std::ops::DerefMut for RefMut<'a, T, C> 1030 where 1031 T: Clear + Default, 1032 C: cfg::Config, 1033 { deref_mut(&mut self) -> &mut Self::Target1034 fn deref_mut(&mut self) -> &mut Self::Target { 1035 unsafe { 1036 // Safety: we are holding a reference to the shard which keeps the 1037 // pointed slot alive. The returned reference will not outlive `self`. 1038 self.inner.value_mut() 1039 } 1040 } 1041 } 1042 1043 impl<'a, T, C> Drop for RefMut<'a, T, C> 1044 where 1045 T: Clear + Default, 1046 C: cfg::Config, 1047 { drop(&mut self)1048 fn drop(&mut self) { 1049 test_println!(" -> drop RefMut: try clearing data"); 1050 let should_clear = unsafe { 1051 // Safety: we are holding a reference to the shard which keeps the 1052 // pointed slot alive. The returned reference will not outlive `self`. 1053 self.inner.release() 1054 }; 1055 if should_clear { 1056 self.shard.clear_after_release(self.key); 1057 } 1058 } 1059 } 1060 1061 impl<'a, T, C> fmt::Debug for RefMut<'a, T, C> 1062 where 1063 T: fmt::Debug + Clear + Default, 1064 C: cfg::Config, 1065 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1066 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 1067 fmt::Debug::fmt(self.value(), f) 1068 } 1069 } 1070 1071 impl<'a, T, C> PartialEq<T> for RefMut<'a, T, C> 1072 where 1073 T: PartialEq<T> + Clear + Default, 1074 C: cfg::Config, 1075 { eq(&self, other: &T) -> bool1076 fn eq(&self, other: &T) -> bool { 1077 self.value().eq(other) 1078 } 1079 } 1080 1081 // === impl OwnedRef === 1082 1083 impl<T, C> OwnedRef<T, C> 1084 where 1085 T: Clear + Default, 1086 C: cfg::Config, 1087 { 1088 /// Returns the key used to access this guard key(&self) -> usize1089 pub fn key(&self) -> usize { 1090 self.key 1091 } 1092 1093 #[inline] value(&self) -> &T1094 fn value(&self) -> &T { 1095 unsafe { 1096 // Safety: calling `slot::Guard::value` is unsafe, since the `Guard` 1097 // value contains a pointer to the slot that may outlive the slab 1098 // containing that slot. Here, the `Ref` has a borrowed reference to 1099 // the shard containing that slot, which ensures that the slot will 1100 // not be dropped while this `Guard` exists. 1101 self.inner.value() 1102 } 1103 } 1104 } 1105 1106 impl<T, C> std::ops::Deref for OwnedRef<T, C> 1107 where 1108 T: Clear + Default, 1109 C: cfg::Config, 1110 { 1111 type Target = T; 1112 deref(&self) -> &Self::Target1113 fn deref(&self) -> &Self::Target { 1114 self.value() 1115 } 1116 } 1117 1118 impl<T, C> Drop for OwnedRef<T, C> 1119 where 1120 T: Clear + Default, 1121 C: cfg::Config, 1122 { drop(&mut self)1123 fn drop(&mut self) { 1124 test_println!("drop OwnedRef: try clearing data"); 1125 let should_clear = unsafe { 1126 // Safety: calling `slot::Guard::release` is unsafe, since the 1127 // `Guard` value contains a pointer to the slot that may outlive the 1128 // slab containing that slot. Here, the `OwnedRef` owns an `Arc` 1129 // clone of the pool, which keeps it alive as long as the `OwnedRef` 1130 // exists. 1131 self.inner.release() 1132 }; 1133 if should_clear { 1134 let shard_idx = Tid::<C>::from_packed(self.key); 1135 test_println!("-> shard={:?}", shard_idx); 1136 if let Some(shard) = self.pool.shards.get(shard_idx.as_usize()) { 1137 shard.clear_after_release(self.key); 1138 } else { 1139 test_println!("-> shard={:?} does not exist! THIS IS A BUG", shard_idx); 1140 debug_assert!(std::thread::panicking(), "[internal error] tried to drop an `OwnedRef` to a slot on a shard that never existed!"); 1141 } 1142 } 1143 } 1144 } 1145 1146 impl<T, C> fmt::Debug for OwnedRef<T, C> 1147 where 1148 T: fmt::Debug + Clear + Default, 1149 C: cfg::Config, 1150 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1151 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 1152 fmt::Debug::fmt(self.value(), f) 1153 } 1154 } 1155 1156 impl<T, C> PartialEq<T> for OwnedRef<T, C> 1157 where 1158 T: PartialEq<T> + Clear + Default, 1159 C: cfg::Config, 1160 { eq(&self, other: &T) -> bool1161 fn eq(&self, other: &T) -> bool { 1162 *self.value() == *other 1163 } 1164 } 1165 1166 unsafe impl<T, C> Sync for OwnedRef<T, C> 1167 where 1168 T: Sync + Clear + Default, 1169 C: cfg::Config, 1170 { 1171 } 1172 1173 unsafe impl<T, C> Send for OwnedRef<T, C> 1174 where 1175 T: Sync + Clear + Default, 1176 C: cfg::Config, 1177 { 1178 } 1179 1180 // === impl OwnedRefMut === 1181 1182 impl<T, C> OwnedRefMut<T, C> 1183 where 1184 T: Clear + Default, 1185 C: cfg::Config, 1186 { 1187 /// Returns the key used to access this guard key(&self) -> usize1188 pub fn key(&self) -> usize { 1189 self.key 1190 } 1191 1192 /// Downgrades the owned mutable guard to an owned immutable guard, allowing 1193 /// access to the pooled value from other threads. 1194 /// 1195 /// ## Examples 1196 /// 1197 /// ``` 1198 /// # use sharded_slab::Pool; 1199 /// # use std::{sync::Arc, thread}; 1200 /// let pool = Arc::new(Pool::<String>::new()); 1201 /// 1202 /// let mut guard_mut = pool.clone().create_owned().unwrap(); 1203 /// let key = guard_mut.key(); 1204 /// guard_mut.push_str("Hello"); 1205 /// 1206 /// // The pooled string is currently borrowed mutably, so other threads 1207 /// // may not access it. 1208 /// let pool2 = pool.clone(); 1209 /// thread::spawn(move || { 1210 /// assert!(pool2.get(key).is_none()) 1211 /// }).join().unwrap(); 1212 /// 1213 /// // Downgrade the guard to an immutable reference. 1214 /// let guard = guard_mut.downgrade(); 1215 /// 1216 /// // Now, other threads may also access the pooled value. 1217 /// let pool2 = pool.clone(); 1218 /// thread::spawn(move || { 1219 /// let guard = pool2.get(key) 1220 /// .expect("the item may now be referenced by other threads"); 1221 /// assert_eq!(guard, String::from("Hello")); 1222 /// }).join().unwrap(); 1223 /// 1224 /// // We can still access the value immutably through the downgraded guard. 1225 /// assert_eq!(guard, String::from("Hello")); 1226 /// ``` downgrade(mut self) -> OwnedRef<T, C>1227 pub fn downgrade(mut self) -> OwnedRef<T, C> { 1228 let inner = unsafe { self.inner.downgrade() }; 1229 OwnedRef { 1230 inner, 1231 pool: self.pool.clone(), 1232 key: self.key, 1233 } 1234 } 1235 shard(&self) -> Option<&Shard<T, C>>1236 fn shard(&self) -> Option<&Shard<T, C>> { 1237 let shard_idx = Tid::<C>::from_packed(self.key); 1238 test_println!("-> shard={:?}", shard_idx); 1239 self.pool.shards.get(shard_idx.as_usize()) 1240 } 1241 1242 #[inline] value(&self) -> &T1243 fn value(&self) -> &T { 1244 unsafe { 1245 // Safety: calling `slot::InitGuard::value` is unsafe, since the `Guard` 1246 // value contains a pointer to the slot that may outlive the slab 1247 // containing that slot. Here, the `OwnedRefMut` has an `Arc` clone of 1248 // the shard containing that slot, which ensures that the slot will 1249 // not be dropped while this `Guard` exists. 1250 self.inner.value() 1251 } 1252 } 1253 } 1254 1255 impl<T, C> std::ops::Deref for OwnedRefMut<T, C> 1256 where 1257 T: Clear + Default, 1258 C: cfg::Config, 1259 { 1260 type Target = T; 1261 deref(&self) -> &Self::Target1262 fn deref(&self) -> &Self::Target { 1263 self.value() 1264 } 1265 } 1266 1267 impl<T, C> std::ops::DerefMut for OwnedRefMut<T, C> 1268 where 1269 T: Clear + Default, 1270 C: cfg::Config, 1271 { deref_mut(&mut self) -> &mut Self::Target1272 fn deref_mut(&mut self) -> &mut Self::Target { 1273 unsafe { 1274 // Safety: calling `slot::InitGuard::value_mut` is unsafe, since the 1275 // `Guard` value contains a pointer to the slot that may outlive 1276 // the slab containing that slot. Here, the `OwnedRefMut` has an 1277 // `Arc` clone of the shard containing that slot, which ensures that 1278 // the slot will not be dropped while this `Guard` exists. 1279 self.inner.value_mut() 1280 } 1281 } 1282 } 1283 1284 impl<T, C> Drop for OwnedRefMut<T, C> 1285 where 1286 T: Clear + Default, 1287 C: cfg::Config, 1288 { drop(&mut self)1289 fn drop(&mut self) { 1290 test_println!("drop OwnedRefMut: try clearing data"); 1291 let should_clear = unsafe { 1292 // Safety: calling `slot::Guard::release` is unsafe, since the 1293 // `Guard` value contains a pointer to the slot that may outlive the 1294 // slab containing that slot. Here, the `OwnedRefMut` owns an `Arc` 1295 // clone of the pool, which keeps it alive as long as the 1296 // `OwnedRefMut` exists. 1297 self.inner.release() 1298 }; 1299 if should_clear { 1300 if let Some(shard) = self.shard() { 1301 shard.clear_after_release(self.key); 1302 } else { 1303 test_println!("-> shard does not exist! THIS IS A BUG"); 1304 debug_assert!(std::thread::panicking(), "[internal error] tried to drop an `OwnedRefMut` to a slot on a shard that never existed!"); 1305 } 1306 } 1307 } 1308 } 1309 1310 impl<T, C> fmt::Debug for OwnedRefMut<T, C> 1311 where 1312 T: fmt::Debug + Clear + Default, 1313 C: cfg::Config, 1314 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1315 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 1316 fmt::Debug::fmt(self.value(), f) 1317 } 1318 } 1319 1320 impl<T, C> PartialEq<T> for OwnedRefMut<T, C> 1321 where 1322 T: PartialEq<T> + Clear + Default, 1323 C: cfg::Config, 1324 { eq(&self, other: &T) -> bool1325 fn eq(&self, other: &T) -> bool { 1326 *self.value() == *other 1327 } 1328 } 1329 1330 unsafe impl<T, C> Sync for OwnedRefMut<T, C> 1331 where 1332 T: Sync + Clear + Default, 1333 C: cfg::Config, 1334 { 1335 } 1336 1337 unsafe impl<T, C> Send for OwnedRefMut<T, C> 1338 where 1339 T: Sync + Clear + Default, 1340 C: cfg::Config, 1341 { 1342 } 1343