1use crate::{
5 ResourceId,
6 core::{Accounting, lock},
7};
8use std::{
9 collections::VecDeque,
10 ops::{Deref, DerefMut},
11 sync::{Arc, Mutex},
12};
13
14pub(crate) struct RetirementQueue<R> {
15 items: Mutex<VecDeque<(ResourceId, R)>>,
16 accounting: Arc<Accounting>,
17}
18impl<R> RetirementQueue<R> {
19 pub fn new(accounting: Arc<Accounting>) -> Self {
20 Self {
21 items: Mutex::new(VecDeque::new()),
22 accounting,
23 }
24 }
25 pub fn push(&self, id: ResourceId, resource: R) {
26 lock(&self.items).push_back((id, resource));
27 self.accounting.notify();
28 }
29 pub fn pop(self: &Arc<Self>) -> Option<Retirement<R>> {
30 let item = lock(&self.items).pop_front();
31 item.map(|item| Retirement {
32 item: Some(item),
33 queue: self.clone(),
34 })
35 }
36}
37
38pub struct Retirement<R> {
43 item: Option<(ResourceId, R)>,
44 queue: Arc<RetirementQueue<R>>,
45}
46impl<R> Retirement<R> {
47 pub fn id(&self) -> ResourceId {
48 self.item.as_ref().unwrap().0
49 }
50 pub fn complete(mut self) {
53 drop(self.item.take().unwrap());
54 lock(&self.queue.accounting.counts).retiring -= 1;
55 self.queue.accounting.notify();
56 }
57}
58impl<R> Deref for Retirement<R> {
59 type Target = R;
60 fn deref(&self) -> &R {
61 &self.item.as_ref().unwrap().1
62 }
63}
64impl<R> DerefMut for Retirement<R> {
65 fn deref_mut(&mut self) -> &mut R {
66 &mut self.item.as_mut().unwrap().1
67 }
68}
69impl<R> Drop for Retirement<R> {
70 fn drop(&mut self) {
71 if let Some((id, resource)) = self.item.take() {
72 self.queue.push(id, resource);
73 }
74 }
75}