@@ -24,7 +24,7 @@ use crate::service::static_config::message_type_details::MessageTypeDetails;
24
24
use crate :: service:: ServiceState ;
25
25
use crate :: service:: { self , config_scheme:: connection_config, naming_scheme:: connection_name} ;
26
26
use alloc:: sync:: Arc ;
27
- use iceoryx2_bb_container:: queue :: Queue ;
27
+ use iceoryx2_bb_container:: vec :: Vec ;
28
28
use iceoryx2_bb_elementary:: cyclic_tagger:: * ;
29
29
use iceoryx2_bb_log:: { fail, warn} ;
30
30
use iceoryx2_cal:: named_concept:: NamedConceptBuilder ;
@@ -111,7 +111,7 @@ pub(crate) struct Receiver<Service: service::Service> {
111
111
pub ( crate ) service_state : Arc < ServiceState < Service > > ,
112
112
pub ( crate ) buffer_size : usize ,
113
113
pub ( crate ) tagger : CyclicTagger ,
114
- pub ( crate ) to_be_removed_connections : Option < UnsafeCell < Queue < Arc < Connection < Service > > > > > ,
114
+ pub ( crate ) to_be_removed_connections : Option < UnsafeCell < Vec < Arc < Connection < Service > > > > > ,
115
115
pub ( crate ) degradation_callback : Option < DegradationCallback < ' static > > ,
116
116
pub ( crate ) message_type_details : MessageTypeDetails ,
117
117
pub ( crate ) receiver_max_borrowed_samples : usize ,
@@ -278,22 +278,45 @@ impl<Service: service::Service> Receiver<Service> {
278
278
& self ,
279
279
channel_id : ChannelId ,
280
280
) -> Result < Option < ( ChunkDetails < Service > , Chunk ) > , ReceiveError > {
281
+ let msg = "Unable to receive data" ;
281
282
if let Some ( to_be_removed_connections) = & self . to_be_removed_connections {
282
283
let to_be_removed_connections = unsafe { & mut * to_be_removed_connections. get ( ) } ;
283
284
284
- if let Some ( connection) = to_be_removed_connections. peek ( ) {
285
+ let mut clean_connections = Vec :: new ( to_be_removed_connections. capacity ( ) ) ;
286
+ for ( n, connection) in to_be_removed_connections. iter_mut ( ) . enumerate ( ) {
287
+ if connection. receiver . borrow_count ( channel_id)
288
+ == connection. receiver . max_borrowed_samples ( )
289
+ {
290
+ continue ;
291
+ }
292
+
285
293
if let Some ( ( details, absolute_address) ) =
286
294
self . receive_from_connection ( connection, channel_id) ?
287
295
{
288
296
return Ok ( Some ( ( details, absolute_address) ) ) ;
289
297
} else {
290
- to_be_removed_connections . pop ( ) ;
298
+ clean_connections . push ( n ) ;
291
299
}
292
300
}
301
+
302
+ for idx in clean_connections. iter ( ) . rev ( ) {
303
+ to_be_removed_connections. remove ( * idx) ;
304
+ }
293
305
}
294
306
307
+ let mut active_channel_count = 0 ;
308
+ let mut all_channels_exceed_max_borrows = true ;
295
309
for id in 0 ..self . len ( ) {
296
310
if let Some ( ref mut connection) = & mut self . get_mut ( id) {
311
+ active_channel_count += 0 ;
312
+ if connection. receiver . borrow_count ( channel_id)
313
+ >= connection. receiver . max_borrowed_samples ( )
314
+ {
315
+ continue ;
316
+ } else {
317
+ all_channels_exceed_max_borrows = false ;
318
+ }
319
+
297
320
if let Some ( ( details, absolute_address) ) =
298
321
self . receive_from_connection ( connection, channel_id) ?
299
322
{
@@ -302,6 +325,11 @@ impl<Service: service::Service> Receiver<Service> {
302
325
}
303
326
}
304
327
328
+ if all_channels_exceed_max_borrows && active_channel_count != 0 {
329
+ fail ! ( from self , with ReceiveError :: ExceedsMaxBorrows ,
330
+ "{msg} since every channel exceeds the max number of borrows." ) ;
331
+ }
332
+
305
333
Ok ( None )
306
334
}
307
335
0 commit comments