@@ -482,6 +482,9 @@ feature! {
482
482
#![ feature = "signal" ]
483
483
484
484
use crate :: unistd:: Pid ;
485
+ use std:: iter:: Extend ;
486
+ use std:: iter:: FromIterator ;
487
+ use std:: iter:: IntoIterator ;
485
488
486
489
/// Specifies a set of [`Signal`]s that may be blocked, waited for, etc.
487
490
#[ derive( Clone , Copy , Debug , Eq , Hash , PartialEq ) ]
@@ -532,14 +535,9 @@ impl SigSet {
532
535
}
533
536
}
534
537
535
- /// Merge all of `other`'s signals into this set.
536
- // TODO: use libc::sigorset on supported operating systems.
537
- pub fn extend( & mut self , other: & SigSet ) {
538
- for signal in Signal :: iterator( ) {
539
- if other. contains( signal) {
540
- self . add( signal) ;
541
- }
542
- }
538
+ /// Returns an iterator that yields the signals contained in this set.
539
+ pub fn iter( & self ) -> SigSetIter <' _> {
540
+ self . into_iter( )
543
541
}
544
542
545
543
/// Gets the currently blocked (masked) set of signals for the calling thread.
@@ -593,6 +591,55 @@ impl AsRef<libc::sigset_t> for SigSet {
593
591
}
594
592
}
595
593
594
+ // TODO: Consider specialization for the case where T is &SigSet and libc::sigorset is available.
595
+ impl Extend <Signal > for SigSet {
596
+ fn extend<T >( & mut self , iter: T )
597
+ where T : IntoIterator <Item = Signal > {
598
+ for signal in iter {
599
+ self . add( signal) ;
600
+ }
601
+ }
602
+ }
603
+
604
+ impl FromIterator <Signal > for SigSet {
605
+ fn from_iter<T >( iter: T ) -> Self
606
+ where T : IntoIterator <Item = Signal > {
607
+ let mut sigset = SigSet :: empty( ) ;
608
+ sigset. extend( iter) ;
609
+ sigset
610
+ }
611
+ }
612
+
613
+ /// Iterator for a [`SigSet`].
614
+ ///
615
+ /// Call [`SigSet::iter`] to create an iterator.
616
+ #[ derive( Clone , Debug ) ]
617
+ pub struct SigSetIter <' a> {
618
+ sigset: & ' a SigSet ,
619
+ inner: SignalIterator ,
620
+ }
621
+
622
+ impl Iterator for SigSetIter <' _> {
623
+ type Item = Signal ;
624
+ fn next( & mut self ) -> Option <Signal > {
625
+ loop {
626
+ match self . inner. next( ) {
627
+ None => return None ,
628
+ Some ( signal) if self . sigset. contains( signal) => return Some ( signal) ,
629
+ Some ( _signal) => continue ,
630
+ }
631
+ }
632
+ }
633
+ }
634
+
635
+ impl <' a> IntoIterator for & ' a SigSet {
636
+ type Item = Signal ;
637
+ type IntoIter = SigSetIter <' a>;
638
+ fn into_iter( self ) -> Self :: IntoIter {
639
+ SigSetIter { sigset: self , inner: Signal :: iterator( ) }
640
+ }
641
+ }
642
+
596
643
/// A signal handler.
597
644
#[ allow( unknown_lints) ]
598
645
#[ derive( Clone , Copy , Debug , Eq , Hash , PartialEq ) ]
@@ -1235,6 +1282,13 @@ mod tests {
1235
1282
} ) . join ( ) . unwrap ( ) ;
1236
1283
}
1237
1284
1285
+ #[ test]
1286
+ fn test_from_and_into_iterator ( ) {
1287
+ let sigset = SigSet :: from_iter ( vec ! [ Signal :: SIGUSR1 , Signal :: SIGUSR2 ] ) ;
1288
+ let signals = sigset. into_iter ( ) . collect :: < Vec < Signal > > ( ) ;
1289
+ assert_eq ! ( signals, [ Signal :: SIGUSR1 , Signal :: SIGUSR2 ] ) ;
1290
+ }
1291
+
1238
1292
#[ test]
1239
1293
#[ cfg( not( target_os = "redox" ) ) ]
1240
1294
fn test_sigaction ( ) {
0 commit comments