@@ -445,8 +445,12 @@ const MAX_RECEIVERS: usize = usize::MAX >> 2;
445
445
/// than `usize::MAX / 2`.
446
446
#[ track_caller]
447
447
pub fn channel < T : Clone > ( capacity : usize ) -> ( Sender < T > , Receiver < T > ) {
448
- let tx = Sender :: new ( capacity) ;
449
- let rx = tx. subscribe ( ) ;
448
+ // SAFETY: In the line below we are creating one extra receiver, so there will be 1 in total.
449
+ let tx = unsafe { Sender :: new_with_receiver_count ( 1 , capacity) } ;
450
+ let rx = Receiver {
451
+ shared : tx. shared . clone ( ) ,
452
+ next : 0 ,
453
+ } ;
450
454
( tx, rx)
451
455
}
452
456
@@ -464,9 +468,28 @@ impl<T> Sender<T> {
464
468
/// [`broadcast`]: crate::sync::broadcast
465
469
/// [`broadcast::channel`]: crate::sync::broadcast
466
470
#[ track_caller]
467
- pub fn new ( mut capacity : usize ) -> Self {
468
- assert ! ( capacity > 0 , "capacity is empty" ) ;
469
- assert ! ( capacity <= usize :: MAX >> 1 , "requested capacity too large" ) ;
471
+ pub fn new ( capacity : usize ) -> Self {
472
+ // SAFETY: We don't create extra receivers, so there are 0.
473
+ unsafe { Self :: new_with_receiver_count ( 0 , capacity) }
474
+ }
475
+
476
+ /// Creates the sending-half of the [`broadcast`] channel, and provide the receiver count.
477
+ ///
478
+ /// See the documentation of [`broadcast::channel`] for more errors when calling this
479
+ /// function.
480
+ ///
481
+ /// # Safety:
482
+ ///
483
+ /// The caller must ensure that the amount of receivers for this Sender is correct before
484
+ /// the channel functionalities are used, the count is zero by default, as this function
485
+ /// does not create any receivers by itself.
486
+ #[ track_caller]
487
+ unsafe fn new_with_receiver_count ( receiver_count : usize , mut capacity : usize ) -> Self {
488
+ assert ! ( capacity > 0 , "broadcast channel capacity cannot be zero" ) ;
489
+ assert ! (
490
+ capacity <= usize :: MAX >> 1 ,
491
+ "broadcast channel capacity exceeded `usize::MAX / 2`"
492
+ ) ;
470
493
471
494
// Round to a power of two
472
495
capacity = capacity. next_power_of_two ( ) ;
@@ -486,7 +509,7 @@ impl<T> Sender<T> {
486
509
mask : capacity - 1 ,
487
510
tail : Mutex :: new ( Tail {
488
511
pos : 0 ,
489
- rx_cnt : 0 ,
512
+ rx_cnt : receiver_count ,
490
513
closed : false ,
491
514
waiters : LinkedList :: new ( ) ,
492
515
} ) ,
@@ -1383,37 +1406,33 @@ mod tests {
1383
1406
1384
1407
#[ test]
1385
1408
fn receiver_count_on_sender_constructor ( ) {
1386
- let count_of = |sender : & Sender < i32 > | sender. shared . tail . lock ( ) . rx_cnt ;
1387
-
1388
1409
let sender = Sender :: < i32 > :: new ( 16 ) ;
1389
- assert_eq ! ( count_of ( & sender) , 0 ) ;
1410
+ assert_eq ! ( sender. receiver_count ( ) , 0 ) ;
1390
1411
1391
1412
let rx_1 = sender. subscribe ( ) ;
1392
- assert_eq ! ( count_of ( & sender) , 1 ) ;
1413
+ assert_eq ! ( sender. receiver_count ( ) , 1 ) ;
1393
1414
1394
1415
let rx_2 = rx_1. resubscribe ( ) ;
1395
- assert_eq ! ( count_of ( & sender) , 2 ) ;
1416
+ assert_eq ! ( sender. receiver_count ( ) , 2 ) ;
1396
1417
1397
1418
let rx_3 = sender. subscribe ( ) ;
1398
- assert_eq ! ( count_of ( & sender) , 3 ) ;
1419
+ assert_eq ! ( sender. receiver_count ( ) , 3 ) ;
1399
1420
1400
1421
drop ( rx_3) ;
1401
1422
drop ( rx_1) ;
1402
- assert_eq ! ( count_of ( & sender) , 1 ) ;
1423
+ assert_eq ! ( sender. receiver_count ( ) , 1 ) ;
1403
1424
1404
1425
drop ( rx_2) ;
1405
- assert_eq ! ( count_of ( & sender) , 0 ) ;
1426
+ assert_eq ! ( sender. receiver_count ( ) , 0 ) ;
1406
1427
}
1407
1428
1408
1429
#[ cfg( not( loom) ) ]
1409
1430
#[ test]
1410
1431
fn receiver_count_on_channel_constructor ( ) {
1411
- let count_of = |sender : & Sender < i32 > | sender. shared . tail . lock ( ) . rx_cnt ;
1412
-
1413
1432
let ( sender, rx) = channel :: < i32 > ( 16 ) ;
1414
- assert_eq ! ( count_of ( & sender) , 1 ) ;
1433
+ assert_eq ! ( sender. receiver_count ( ) , 1 ) ;
1415
1434
1416
1435
let _rx_2 = rx. resubscribe ( ) ;
1417
- assert_eq ! ( count_of ( & sender) , 2 ) ;
1436
+ assert_eq ! ( sender. receiver_count ( ) , 2 ) ;
1418
1437
}
1419
1438
}
0 commit comments