bt_a2dp/
permits.rs

1// Copyright 2021 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! A collection which hands out Permits, of which a limited number of are allowed exist at once.
6//! Permits can be granted immediately, or can be reserved in first-come-first-serve order, with a
7//! Future which resolves to a Permit once one becomes available.
8//!
9//! Permits are released upon drop and will be automatically handed off to the next reservation or
10//! returned to the available pool if no one is waiting.
11//!
12//! Permits can be revokable by providing a function which will return a valid Permit when called.
13//! That function can also make a reservation for a future Permit if desired. (see examples in tests)
14//!
15//! A client can take a permit (revoking one if necessary), by using `Permits::take`.
16//! A client can also seize all permits, taking out all permits left unclaimed and revoking all
17//! revokable permits.
18//!
19//! Permits taken or seized are not revokable.
20
21use anyhow::{format_err, Error};
22use fuchsia_sync::Mutex;
23use futures::channel::oneshot;
24use futures::future::FusedFuture;
25use futures::task::{Context, Poll};
26use futures::{ready, Future, FutureExt};
27use slab::Slab;
28use std::collections::VecDeque;
29use std::pin::Pin;
30use std::sync::atomic::{AtomicBool, Ordering};
31use std::sync::{Arc, Weak};
32
33type BoxRevokeFn = Box<dyn FnOnce() -> Permit + Send>;
34
35struct RevokeFnHolder {
36    f: Mutex<Option<BoxRevokeFn>>,
37    label: Mutex<String>,
38}
39
40impl RevokeFnHolder {
41    fn new(f: Option<BoxRevokeFn>) -> Arc<Self> {
42        Arc::new(Self { f: Mutex::new(f), label: Mutex::new(String::default()) })
43    }
44
45    // Replaces the revokable function within, returning the previously stored fn, if there was one.
46    fn replace(&self, f: BoxRevokeFn) -> Option<BoxRevokeFn> {
47        self.f.lock().replace(f)
48    }
49
50    // Replaces the label
51    fn relabel(&self, label: String) {
52        *(self.label.lock()) = label;
53    }
54
55    fn label(&self) -> String {
56        self.label.lock().clone()
57    }
58
59    fn take(&self) -> Option<BoxRevokeFn> {
60        self.f.lock().take()
61    }
62
63    fn is_revokable(&self) -> bool {
64        self.f.lock().is_some()
65    }
66
67    fn extract(weak: &Weak<Self>) -> BoxRevokeFn {
68        weak.upgrade().expect("should be resolvable").take().expect("revokable fn missing")
69    }
70}
71
72impl std::fmt::Debug for RevokeFnHolder {
73    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
74        f.debug_struct("RevokeFnHolder")
75            .field("revokable", &self.is_revokable())
76            .field("label", &self.label())
77            .finish()
78    }
79}
80
81struct WaitingReservation {
82    sender: futures::channel::oneshot::Sender<Permit>,
83}
84
85struct PermitsInner {
86    // The maximum number of permits allowed.
87    limit: usize,
88    // The current permits out. Permits are indexed by their key.
89    // If the permit is out, then Weak::upgrade() will return Some.
90    out: Slab<Weak<RevokeFnHolder>>,
91    // A queue of oneshot senders who are waiting for permits.
92    waiting: VecDeque<WaitingReservation>,
93    // An ordered queue of indexes into `out` which are revokable.
94    // If a permit index is listed here, the Weak at out.get(i) should be upgradable.
95    revocations: VecDeque<usize>,
96    weak: Weak<Mutex<Self>>,
97}
98
99impl std::fmt::Debug for PermitsInner {
100    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
101        let mut debug = f.debug_struct("PermitsInner");
102        let _ = debug.field("limit", &self.limit).field("waiting", &self.waiting.len());
103        for (k, holder) in &self.out {
104            let h = holder.upgrade().unwrap();
105            let holder_str = format!("{}: {}", if h.is_revokable() { "R" } else { "I" }, h.label());
106            let _ = debug.field(format!("permit{k}").as_str(), &holder_str);
107        }
108        debug.finish()
109    }
110}
111
112impl PermitsInner {
113    fn new(limit: usize) -> Arc<Mutex<Self>> {
114        Arc::new_cyclic(|weak| {
115            Mutex::new(Self {
116                limit,
117                out: Slab::with_capacity(limit),
118                waiting: VecDeque::new(),
119                revocations: VecDeque::new(),
120                weak: weak.clone(),
121            })
122        })
123    }
124
125    // Try to reserve a key in the permits. If `revoke_fn` is Some then this permit is
126    // revokable. Returns the permit, or an Error if there are no permits available.
127    fn try_get(&mut self, revoke_fn: Option<BoxRevokeFn>) -> Result<Permit, Error> {
128        if self.out.len() == self.out.capacity() {
129            return Err(format_err!("No permits left"));
130        }
131        let is_revokable = revoke_fn.is_some();
132        let fn_holder = RevokeFnHolder::new(revoke_fn);
133        let key = self.out.insert(Arc::downgrade(&fn_holder));
134        if is_revokable {
135            self.revocations.push_back(key);
136        }
137        Ok(Permit {
138            inner: Some(self.weak.upgrade().unwrap()),
139            committed: Arc::new(AtomicBool::new(true)),
140            fn_holder,
141            key,
142        })
143    }
144
145    // Release a permit that is out. Permits call this function when they are dropped
146    // to hand off their permit to the next waiting reservation.
147    // `key` is the key of the permit being released.
148    //
149    // Panics: if `key` is not currently out.
150    fn release(&mut self, key: usize) {
151        // Not revoked, so drop tracking a possible revocation.
152        self.revocations.retain(|k| *k != key);
153        // Holder should be resolvable as it's held by the releasing Permit.
154        let holder = self.out.get(key).expect("reservation present").upgrade().unwrap();
155        // Drop the revoke fn if it's present.
156        drop(holder.take());
157        let this = self.weak.upgrade().unwrap();
158        while let Some(sender) = self.waiting.pop_front() {
159            if let Ok(()) = Permit::handoff(sender, this.clone(), holder.clone(), key) {
160                return;
161            }
162        }
163        // No permits were handed off, so this one gets turned in.
164        drop(self.out.remove(key));
165    }
166
167    // Create a Reservation future that will complete with a Permit when one becomes available.
168    fn reservation(&mut self, revoke_fn: Option<BoxRevokeFn>) -> Reservation {
169        let (sender, receiver) = oneshot::channel();
170        // If we can get a permit immediately, send it right away.
171        match self.try_get(None).ok() {
172            Some(permit) => sender.send(permit).ok().unwrap(),
173            None => self.waiting.push_back(WaitingReservation { sender }),
174        }
175        Reservation { receiver, revoke_fn, inner: self.weak.clone() }
176    }
177
178    /// Make a previously unrevokable permit revokable by supplying a function to revoke it.
179    fn make_revokable(&mut self, key: usize, revoke_fn: BoxRevokeFn) {
180        let prev = self
181            .out
182            .get(key)
183            .expect("reservation should be out")
184            .upgrade()
185            .expect("holder should resolve")
186            .replace(revoke_fn);
187        assert!(prev.is_none(), "shouldn't be replacing a previous revocation function");
188        self.revocations.push_back(key);
189    }
190
191    /// Get the next revokable permit function.
192    fn pop_revoke(&mut self) -> Option<BoxRevokeFn> {
193        self.revocations.pop_front().map(|idx| RevokeFnHolder::extract(&self.out[idx]))
194    }
195
196    /// Empty the queue of revokable permit functions, returning them all for revocation.
197    fn revoke_all(&mut self) -> Vec<BoxRevokeFn> {
198        let mut indices = std::mem::take(&mut self.revocations);
199        indices.drain(..).map(|idx| RevokeFnHolder::extract(&self.out[idx])).collect()
200    }
201}
202
203/// A Reservation is a future that will eventually receive a permit once one becomes available.
204pub struct Reservation {
205    // Receiver for the Permit when it is granted.
206    receiver: oneshot::Receiver<Permit>,
207    // The revocation function if this reservation will result in a revokable permit
208    revoke_fn: Option<BoxRevokeFn>,
209    // Pointer to the shared permits if it still exists.
210    inner: Weak<Mutex<PermitsInner>>,
211}
212
213impl Future for Reservation {
214    type Output = Permit;
215    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
216        let res = ready!(self.receiver.poll_unpin(cx));
217        let permit = res.expect("sender shouldn't be dropped, polled after termination?");
218        if let (Some(f), Some(inner)) = (self.revoke_fn.take(), self.inner.upgrade()) {
219            inner.lock().make_revokable(permit.key, f);
220        }
221        Poll::Ready(permit)
222    }
223}
224
225impl FusedFuture for Reservation {
226    fn is_terminated(&self) -> bool {
227        self.receiver.is_terminated()
228    }
229}
230
231#[derive(Debug, Clone)]
232pub struct Permits {
233    inner: Arc<Mutex<PermitsInner>>,
234    limit: usize,
235}
236
237impl Permits {
238    /// Make a new set of permits with `limit` maximum concurrent permits available.
239    pub fn new(limit: usize) -> Self {
240        Self { inner: PermitsInner::new(limit), limit }
241    }
242
243    /// Returns the maximum number of permits allowed.
244    pub fn limit(&self) -> usize {
245        self.limit
246    }
247
248    /// Attempts to get a permit. Returns None if there are no permits available.
249    pub fn get(&self) -> Option<Permit> {
250        Permit::try_issue(self.inner.clone(), None)
251    }
252
253    /// Attempts to get a permit that is revokable.  Revokable permits can be revoked at any time
254    /// after this function returns and must return the Permit when asked. `revoked_fn` will be
255    /// called to retrieve the permit when it is revoked.
256    pub fn get_revokable(
257        &self,
258        revoked_fn: impl FnOnce() -> Permit + 'static + Send,
259    ) -> Option<Permit> {
260        Permit::try_issue(self.inner.clone(), Some(Box::new(revoked_fn)))
261    }
262
263    /// Attempts to get a permit. If a permit isn't available, but one can be revoked, one will
264    /// be revoked to return a permit.  Revoked permits are returned here before reservations are
265    /// filled.
266    pub fn take(&self) -> Option<Permit> {
267        if let Some(permit) = self.get() {
268            return Some(permit);
269        }
270        let revoke_fn = self.inner.lock().pop_revoke();
271        revoke_fn.map(|f| f())
272    }
273
274    /// Attempts to reserve all permits, including revoking any permits to do so.
275    /// Permits that are seized are prioritized over any reservations.
276    pub fn seize(&self) -> Vec<Permit> {
277        let mut bunch = Vec::new();
278        let mut revoke_fns = {
279            let mut lock = self.inner.lock();
280            // First get all the unclaimed permits.
281            loop {
282                match lock.try_get(None).ok() {
283                    Some(permit) => bunch.push(permit),
284                    None => break,
285                }
286            }
287            lock.revoke_all()
288        };
289        for f in revoke_fns.drain(..) {
290            bunch.push(f())
291        }
292        bunch
293    }
294
295    /// Reserve a spot in line to receive a permit once one becomes available.
296    /// Returns a future that resolves to a permit
297    /// Reservations are first-come-first-serve, but permits that are revoked ignore reservations.
298    pub fn reserve(&self) -> Reservation {
299        self.inner.lock().reservation(None)
300    }
301
302    /// Reserve a spot in line to receive a permit once one becomes available.
303    /// Returns a future that resovles to a revokable permit.
304    /// Once the permit has been returned from the Reservation, it can be revoked at any time
305    /// afterwards.
306    pub fn reserve_revokable(
307        &self,
308        revoked_fn: impl FnOnce() -> Permit + 'static + Send,
309    ) -> Reservation {
310        self.inner.lock().reservation(Some(Box::new(revoked_fn)))
311    }
312}
313
314#[derive(Debug)]
315pub struct Permit {
316    // The shared permits
317    inner: Option<Arc<Mutex<PermitsInner>>>,
318    committed: Arc<AtomicBool>,
319    fn_holder: Arc<RevokeFnHolder>,
320    key: usize,
321}
322
323impl Permit {
324    /// Relabels this permit, making it easier to track in Debug
325    pub fn relabel(&self, new_label: String) {
326        self.fn_holder.relabel(new_label);
327    }
328
329    /// Issues a permit using the given `inner`. Returns none if there are no permits available or
330    /// in the case of lock contention.
331    fn try_issue(inner: Arc<Mutex<PermitsInner>>, revoke_fn: Option<BoxRevokeFn>) -> Option<Self> {
332        inner.lock().try_get(revoke_fn).ok()
333    }
334
335    // Tries to hand off a permit to a reservation. This creates a new Permit and makes sure it
336    // is in the channel before it returns. The permit is then "real", and guarantees it will
337    // release itself when dropped.
338    fn handoff(
339        waiting: WaitingReservation,
340        inner: Arc<Mutex<PermitsInner>>,
341        fn_holder: Arc<RevokeFnHolder>,
342        key: usize,
343    ) -> Result<(), Error> {
344        let committed = Arc::new(AtomicBool::new(false));
345        let commit_clone = committed.clone();
346        let potential = Self { inner: Some(inner), committed, key, fn_holder };
347        match waiting.sender.send(potential) {
348            Ok(()) => {
349                commit_clone.store(true, Ordering::Relaxed);
350                Ok(())
351            }
352            Err(_) => Err(format_err!("failed to handoff")),
353        }
354    }
355}
356
357impl Drop for Permit {
358    fn drop(&mut self) {
359        let inner = match self.inner.take() {
360            None => return, // Dropped twice, nothing to do.
361            Some(inner) => inner,
362        };
363        let committed = self.committed.load(Ordering::Relaxed);
364        if committed {
365            inner.lock().release(self.key);
366        }
367    }
368}
369
370#[cfg(test)]
371mod tests {
372    use super::*;
373
374    use async_utils::PollExt;
375    use fuchsia_async as fasync;
376
377    #[track_caller]
378    fn expect_none<T>(opt: Option<T>, msg: &str) {
379        if let Some(_) = opt {
380            panic!("{}", msg);
381        }
382    }
383
384    #[track_caller]
385    fn expect_no_permits(exec: &mut fasync::TestExecutor, reservation: &mut Reservation) {
386        exec.run_until_stalled(reservation)
387            .expect_pending("expected reservation to have no permits");
388    }
389
390    #[track_caller]
391    fn expect_permit_available(
392        exec: &mut fasync::TestExecutor,
393        reservation: &mut Reservation,
394    ) -> Permit {
395        exec.run_until_stalled(reservation).expect("reservation to have available permit")
396    }
397
398    #[test]
399    fn no_permits_available() {
400        // Not super useful...
401        let permits = Permits::new(0);
402
403        expect_none(permits.get(), "shouldn't be able to get a permit");
404
405        // Can still get a reservation, that will never complete.
406        let _reservation = permits.reserve();
407    }
408
409    #[test]
410    fn permit_dropping() {
411        // Two permits allowed.
412        let permits = Permits::new(2);
413
414        assert_eq!(2, permits.limit());
415
416        let one = permits.get().expect("first permit");
417        let two = permits.get().expect("second permit");
418        expect_none(permits.get(), "shouln't get a third permit");
419
420        drop(two);
421
422        let three = permits.get().expect("third permit");
423        drop(one);
424        let four = permits.get().expect("fourth permit");
425
426        drop(three);
427        drop(four);
428
429        let _five = permits.get().expect("fifth permit");
430    }
431
432    #[test]
433    fn permit_reservations() {
434        let mut exec = fasync::TestExecutor::new();
435
436        // Two permits allowed.
437        let permits = Permits::new(2);
438
439        let one = permits.get().expect("permit one should be available");
440        let two = permits.get().expect("second permit is also okay");
441        expect_none(permits.get(), "can't get a third item");
442
443        let mut first = permits.reserve();
444        let second = permits.reserve();
445        let mut third = permits.reserve();
446        let mut fourth = permits.reserve();
447
448        // We should be able to drop any of these reservations before they become a Permit
449        drop(second);
450
451        expect_no_permits(&mut exec, &mut first);
452        expect_no_permits(&mut exec, &mut third);
453        expect_no_permits(&mut exec, &mut fourth);
454
455        drop(one);
456
457        let first_out = expect_permit_available(&mut exec, &mut first);
458        expect_no_permits(&mut exec, &mut third);
459        expect_no_permits(&mut exec, &mut fourth);
460
461        drop(first_out);
462
463        let third_out = expect_permit_available(&mut exec, &mut third);
464        expect_no_permits(&mut exec, &mut fourth);
465
466        drop(fourth);
467
468        drop(two);
469
470        // There should be one available now. Let's get it through a reservation.
471        let mut fifth = permits.reserve();
472
473        // Permits out: third_out (a permit) and fifth (a reservation which has a permit waiting to be retrieved).
474
475        // Even though we haven't polled the reservation yet, we can't get another one (fifth has it)
476        expect_none(permits.get(), "no items should be available");
477
478        // Let's get two last reservations, which won't be filled yet.
479        let sixth = permits.reserve();
480        let mut seventh = permits.reserve();
481        let _eighth = permits.reserve();
482
483        // We can drop the Permits structure at any time, the permits and reservations that are out.
484        // will work fine (we just won't be able to make any more)
485        drop(permits);
486
487        let _fifth_out = expect_permit_available(&mut exec, &mut fifth);
488
489        drop(third_out);
490
491        drop(sixth);
492
493        let _seventh_out = expect_permit_available(&mut exec, &mut seventh);
494    }
495
496    #[test]
497    fn revoke_permits() {
498        const TOTAL_PERMITS: usize = 2;
499        let permits = Permits::new(TOTAL_PERMITS);
500
501        let permit_holder = Arc::new(Mutex::new(None));
502
503        let revoke_from_holder_fn = {
504            let holder = permit_holder.clone();
505            move || holder.lock().take().expect("should be holding Permit")
506        };
507
508        let revokable_permit =
509            permits.get_revokable(revoke_from_holder_fn.clone()).expect("permit available");
510        *permit_holder.lock() = Some(revokable_permit);
511
512        let seized_permits = permits.seize();
513
514        // We have two permits.
515        assert_eq!(TOTAL_PERMITS, seized_permits.len());
516        // The permit has been revoked
517        assert!(permit_holder.lock().is_none());
518
519        // Drop the permits
520        drop(seized_permits);
521
522        // Should be able to take a permit when one is just available.
523        let _nonrevokable_permit = permits.take().expect("permit available");
524        let revokable_permit =
525            permits.get_revokable(revoke_from_holder_fn.clone()).expect("two permits");
526        *permit_holder.lock() = Some(revokable_permit);
527
528        // Seizing all the (remaining) permits doesn't get the non-revokable one.
529        let seized_permits = permits.seize();
530        assert_eq!(1, seized_permits.len());
531        // The permit has been revoked
532        assert!(permit_holder.lock().is_none());
533
534        drop(seized_permits);
535
536        let revokable_permit = permits.get_revokable(revoke_from_holder_fn).expect("permit");
537        *permit_holder.lock() = Some(revokable_permit);
538
539        // Can take the permit from the revokable one.
540        let _taken = permits.take().expect("can take the permit");
541        assert!(permit_holder.lock().is_none());
542
543        // Can't take a permit if none are available.
544        assert!(permits.take().is_none());
545    }
546
547    #[test]
548    fn revokable_dropped_before_revokation() {
549        const TOTAL_PERMITS: usize = 2;
550        let permits = Permits::new(TOTAL_PERMITS);
551
552        let permit_holder = Arc::new(Mutex::new(None));
553
554        let revoke_from_holder_fn = {
555            let holder = permit_holder.clone();
556            move || holder.lock().take().expect("should be holding Permit when revoked")
557        };
558
559        let revokable_permit =
560            permits.get_revokable(revoke_from_holder_fn).expect("permit available");
561        // Drop it before we have a chance to revoke it.
562        drop(revokable_permit);
563
564        let seized_permits = permits.seize();
565        // We have both permits.
566        assert_eq!(TOTAL_PERMITS, seized_permits.len());
567    }
568
569    // It's turtles all the way down.
570    // This function revokes a permit by taking it from the permits_holder
571    // Then makes a reservation using itself as the revocation function.
572    // Putting the reservation into reservations_holder.
573    fn revoke_then_reserve_again(
574        permits: Permits,
575        holder: Arc<Mutex<Vec<Permit>>>,
576        reservations: Arc<Mutex<Vec<Reservation>>>,
577    ) -> Permit {
578        let permit = holder.lock().pop().expect("should have a permit");
579        let recurse_fn = {
580            let permits = permits.clone();
581            let reservations = reservations.clone();
582            move || revoke_then_reserve_again(permits, holder, reservations)
583        };
584        let reservation = permits.reserve_revokable(recurse_fn);
585        reservations.lock().push(reservation);
586        permit
587    }
588
589    #[fuchsia::test]
590    fn revokable_reservations() {
591        let mut exec = fasync::TestExecutor::new();
592        const TOTAL_PERMITS: usize = 2;
593        let permits = Permits::new(TOTAL_PERMITS);
594
595        let permits_holder = Arc::new(Mutex::new(Vec::new()));
596        let reservations_holder = Arc::new(Mutex::new(Vec::new()));
597
598        let revoke_from_holder_fn = {
599            let holder = permits_holder.clone();
600            move || holder.lock().pop().expect("should have a Permit")
601        };
602
603        let revokable =
604            permits.get_revokable(revoke_from_holder_fn.clone()).expect("got revokable");
605        permits_holder.lock().push(revokable);
606
607        let revoke_then_reserve_fn = {
608            let permits = permits.clone();
609            let holder = permits_holder.clone();
610            let reservations = reservations_holder.clone();
611            move || revoke_then_reserve_again(permits, holder, reservations)
612        };
613
614        let mut revokable_reservation = permits.reserve_revokable(revoke_then_reserve_fn);
615        let revokable_permit = expect_permit_available(&mut exec, &mut revokable_reservation);
616        permits_holder.lock().push(revokable_permit);
617
618        let seized_permits = permits.seize();
619        // We have both permits.
620        assert_eq!(TOTAL_PERMITS, seized_permits.len());
621        assert_eq!(0, permits_holder.lock().len());
622
623        // But! also a reservation.
624        let mut another_reservation = reservations_holder.lock().pop().expect("reservation");
625        // This one won't get us another reservation, but is still revokable.
626        let mut revokable_reservation_two = permits.reserve_revokable(revoke_from_holder_fn);
627
628        // Dropping both seized permits will deliver both reservations.
629        drop(seized_permits);
630
631        let revokable_permit = expect_permit_available(&mut exec, &mut another_reservation);
632        permits_holder.lock().push(revokable_permit);
633        let revokable_permit = expect_permit_available(&mut exec, &mut revokable_reservation_two);
634        permits_holder.lock().push(revokable_permit);
635
636        // We can seize both of these again! Hah!
637        let seized_permits = permits.seize();
638        // We have both permits.
639        assert_eq!(TOTAL_PERMITS, seized_permits.len());
640        assert_eq!(0, permits_holder.lock().len());
641        // But we have yet another reservation (from the recycling one)
642        let mut yet_another = reservations_holder.lock().pop().expect("reservation");
643        expect_no_permits(&mut exec, &mut yet_another);
644
645        // If we drop both seized permits..
646        drop(seized_permits);
647
648        // We can get one permit (this time unseizable)
649        let one = permits.get().expect("one is available");
650
651        // But not a second one, since the reservation has it.
652        expect_none(permits.get(), "none should be available");
653
654        let revokable_permit = expect_permit_available(&mut exec, &mut yet_another);
655        permits_holder.lock().push(revokable_permit);
656
657        // Seizing now will only seize the revokable one.
658        let seized_permits = permits.seize();
659        assert_eq!(1, seized_permits.len());
660        assert_eq!(0, permits_holder.lock().len());
661
662        // We still get another reservation (from the recycling one)
663        let mut yet_another = reservations_holder.lock().pop().expect("reservation");
664        expect_no_permits(&mut exec, &mut yet_another);
665
666        // Dropping the unrevokable one will fulfill the revokable reservation.
667        drop(one);
668
669        let revokable_permit = expect_permit_available(&mut exec, &mut yet_another);
670        permits_holder.lock().push(revokable_permit);
671
672        // And we can take that one away too.
673        let taken_permit = permits.take().expect("should be able to take one");
674
675        // Drop so that ASAN is happy.
676        drop(taken_permit);
677        // Need to empty the permits holder before dropping it, otherwise the permits
678        // inside will hold a reference loop (the permits hold the revocation function which hold
679        // a ref to the holder)
680        permits_holder.lock().clear();
681        drop(permits_holder);
682        // Same for the reservations.
683        reservations_holder.lock().clear();
684        drop(reservations_holder);
685        drop(permits);
686    }
687}