@@ -33,6 +33,7 @@ enum AcquirePreference {
3333struct Global {
3434 unlock_event : Event < usize > ,
3535 disconnect_event : Event < usize > ,
36+ locked_set : Box < [ AtomicBool ] > ,
3637 num_connected : AtomicUsize ,
3738 min_connections : usize ,
3839 min_connections_event : Event < ( ) > ,
@@ -63,6 +64,7 @@ impl<C> ConnectionSet<C> {
6364 let global = Arc :: new ( Global {
6465 unlock_event : Event :: with_tag ( ) ,
6566 disconnect_event : Event :: with_tag ( ) ,
67+ locked_set : ( 0 ..* size. end ( ) ) . map ( |_| AtomicBool :: new ( false ) ) . collect ( ) ,
6668 num_connected : AtomicUsize :: new ( 0 ) ,
6769 min_connections : * size. start ( ) ,
6870 min_connections_event : Event :: with_tag ( ) ,
@@ -118,69 +120,41 @@ impl<C> ConnectionSet<C> {
118120 }
119121
120122 async fn acquire_inner ( & self , pref : AcquirePreference ) -> SlotGuard < C > {
121- /// Smallest time-step supported by [`tokio::time::sleep()`].
122- ///
123- /// `async-io` doesn't document a minimum time-step, instead deferring to the platform.
124- const STEP_INTERVAL : Duration = Duration :: from_millis ( 1 ) ;
125-
126- const SEARCH_LIMIT : usize = 5 ;
127-
128- let preferred_slot = current_thread_id ( ) % self . slots . len ( ) ;
123+ let preferred_slot = current_thread_id ( ) % self . slots . len ( ) ;
129124
130125 tracing:: trace!( preferred_slot, ?pref, "acquire_inner" ) ;
131126
132127 // Always try to lock the connection associated with our thread ID
133128 let mut acquire_preferred = pin ! ( self . slots[ preferred_slot] . acquire( pref) ) ;
134129
135- let mut step_interval = pin ! ( rt:: interval_after( STEP_INTERVAL ) ) ;
136-
137- let mut intervals_elapsed = 0usize ;
138-
139- let mut search_slots = FuturesUnordered :: new ( ) ;
140-
141130 let mut listen_global = pin ! ( self . global. listen( pref) ) ;
142131
143- let mut search_slot = self . next_slot ( preferred_slot ) ;
132+ let mut yielded = false ;
144133
145- std:: future:: poll_fn ( |cx| loop {
134+ std:: future:: poll_fn ( |cx| {
146135 if let Poll :: Ready ( locked) = acquire_preferred. as_mut ( ) . poll ( cx) {
147136 return Poll :: Ready ( locked) ;
148137 }
149138
150- // Don't push redundant futures for small sets.
151- let search_limit = cmp:: min ( SEARCH_LIMIT , self . slots . len ( ) ) ;
152-
153- if search_slots. len ( ) < search_limit && step_interval. as_mut ( ) . poll_tick ( cx) . is_ready ( )
154- {
155- intervals_elapsed = intervals_elapsed. saturating_add ( 1 ) ;
156-
157- if search_slot != preferred_slot && self . slots [ search_slot] . matches_pref ( pref) {
158- search_slots. push ( self . slots [ search_slot] . lock ( ) ) ;
159- }
160-
161- search_slot = self . next_slot ( search_slot) ;
162- }
163-
164- if let Poll :: Ready ( Some ( locked) ) = Pin :: new ( & mut search_slots) . poll_next ( cx) {
165- if locked. matches_pref ( pref) {
139+ if let Poll :: Ready ( slot) = listen_global. as_mut ( ) . poll ( cx) {
140+ if let Some ( locked) = self . slots [ slot] . try_acquire ( pref) {
166141 return Poll :: Ready ( locked) ;
167142 }
168143
169- continue ;
144+ listen_global . as_mut ( ) . set ( self . global . listen ( pref ) ) ;
170145 }
171146
172- if intervals_elapsed > search_limit && search_slots . len ( ) < search_limit {
173- if let Poll :: Ready ( slot ) = listen_global . as_mut ( ) . poll ( cx ) {
174- if self . slots [ slot ] . matches_pref ( pref ) {
175- search_slots . push ( self . slots [ slot ] . lock ( ) ) ;
176- }
147+ if !yielded {
148+ cx . waker ( ) . wake_by_ref ( ) ;
149+ yielded = true ;
150+ return Poll :: Pending ;
151+ }
177152
178- listen_global. as_mut ( ) . set ( self . global . listen ( pref) ) ;
179- continue ;
180- }
153+ if let Some ( locked) = self . try_acquire ( pref) {
154+ return Poll :: Ready ( locked) ;
181155 }
182156
183- return Poll :: Pending ;
157+ Poll :: Pending
184158 } )
185159 . await
186160 }
0 commit comments