@@ -5,9 +5,11 @@ use std::sync::Arc;
55use tokio:: sync:: { AcquireError , Semaphore } ;
66
77/// An adjustable semaphore in which the total number of permits can be adjusted at any time
8- /// between a minimum and a maximum bound. Adjustments do not affect any permits currently
9- /// issued; if an adjustment cannot be permformed immediately, then it is resolved before any
10- /// new permits are issued.
8+ /// between a minimum and a maximum bound.
9+ ///
10+ /// Unlike the tokio Semaphore, decreasing the number of permits may be done at any time and
11+ /// are resolved lazily if needed; any permits currently issued remain valid, but no new permits
12+ /// are issued until any requested decreases are resolved.
1113pub struct AdjustableSemaphore {
1214 semaphore : Arc < Semaphore > ,
1315 total_permits : AtomicUsize ,
@@ -17,7 +19,7 @@ pub struct AdjustableSemaphore {
1719}
1820
1921/// A permit issued by the AdjustableSemaphore. On drop, this attempts to
20- /// resolve an enqueued permit decrease if one is needed.
22+ /// resolve any enqueued permit decrease if one is needed.
2123pub struct AdjustableSemaphorePermit {
2224 permit : Option < tokio:: sync:: OwnedSemaphorePermit > ,
2325 parent : Arc < AdjustableSemaphore > ,
@@ -65,6 +67,11 @@ impl AdjustableSemaphore {
6567 // A few debug mode consistency checks.
6668 debug_assert ! ( self . semaphore. available_permits( ) <= self . max_permits) ;
6769
70+ // To ensure that the fairness property of the enclosed tokio semaphore is respected,
71+ // this function must only call this class and not attempt to resolve anything else.
72+ //
73+ // As a result, any decreases are resolved by the Drop trait of this permit, which may
74+ // mean that permit is forgotten to resolve an outstanding decrease.
6875 let permit = self . semaphore . clone ( ) . acquire_owned ( ) . await ?;
6976
7077 Ok ( AdjustableSemaphorePermit {
0 commit comments