1
1
use std:: fmt;
2
+ use std:: sync:: atomic:: { AtomicU16 , AtomicU64 , Ordering } ;
2
3
use std:: sync:: Arc ;
3
4
4
- use util:: sync:: Mutex ;
5
-
6
5
/// Sequencer generates sequential sequence numbers for building RTP packets
7
6
pub trait Sequencer : fmt:: Debug {
8
7
fn next_sequence_number ( & self ) -> u16 ;
@@ -20,10 +19,10 @@ impl Clone for Box<dyn Sequencer + Send + Sync> {
20
19
/// number
21
20
pub fn new_random_sequencer ( ) -> impl Sequencer {
22
21
let c = Counters {
23
- sequence_number : rand:: random :: < u16 > ( ) ,
24
- roll_over_count : 0 ,
22
+ sequence_number : Arc :: new ( AtomicU16 :: new ( rand:: random :: < u16 > ( ) ) ) ,
23
+ roll_over_count : Arc :: new ( AtomicU64 :: new ( 0 ) ) ,
25
24
} ;
26
- SequencerImpl ( Arc :: new ( Mutex :: new ( c ) ) )
25
+ SequencerImpl ( c )
27
26
}
28
27
29
28
/// NewFixedSequencer returns a new sequencer starting from a specific
@@ -32,42 +31,39 @@ pub fn new_fixed_sequencer(s: u16) -> impl Sequencer {
32
31
let sequence_number = if s == 0 { u16:: MAX } else { s - 1 } ;
33
32
34
33
let c = Counters {
35
- sequence_number,
36
- roll_over_count : 0 ,
34
+ sequence_number : Arc :: new ( AtomicU16 :: new ( sequence_number ) ) ,
35
+ roll_over_count : Arc :: new ( AtomicU64 :: new ( 0 ) ) ,
37
36
} ;
38
37
39
- SequencerImpl ( Arc :: new ( Mutex :: new ( c ) ) )
38
+ SequencerImpl ( c )
40
39
}
41
40
42
41
#[ derive( Debug , Clone ) ]
43
- struct SequencerImpl ( Arc < Mutex < Counters > > ) ;
42
+ struct SequencerImpl ( Counters ) ;
44
43
45
- #[ derive( Debug ) ]
44
+ #[ derive( Debug , Clone ) ]
46
45
struct Counters {
47
- sequence_number : u16 ,
48
- roll_over_count : u64 ,
46
+ sequence_number : Arc < AtomicU16 > ,
47
+ roll_over_count : Arc < AtomicU64 > ,
49
48
}
50
49
51
50
impl Sequencer for SequencerImpl {
52
51
/// NextSequenceNumber increment and returns a new sequence number for
53
52
/// building RTP packets
54
53
fn next_sequence_number ( & self ) -> u16 {
55
- let mut lock = self . 0 . lock ( ) ;
56
-
57
- if lock. sequence_number == u16:: MAX {
58
- lock. roll_over_count += 1 ;
59
- lock. sequence_number = 0 ;
54
+ if self . 0 . sequence_number . load ( Ordering :: SeqCst ) == u16:: MAX {
55
+ self . 0 . roll_over_count . fetch_add ( 1 , Ordering :: SeqCst ) ;
56
+ self . 0 . sequence_number . store ( 0 , Ordering :: SeqCst ) ;
57
+ 0
60
58
} else {
61
- lock . sequence_number += 1 ;
59
+ self . 0 . sequence_number . fetch_add ( 1 , Ordering :: SeqCst ) + 1
62
60
}
63
-
64
- lock. sequence_number
65
61
}
66
62
67
63
/// RollOverCount returns the amount of times the 16bit sequence number
68
64
/// has wrapped
69
65
fn roll_over_count ( & self ) -> u64 {
70
- self . 0 . lock ( ) . roll_over_count
66
+ self . 0 . roll_over_count . load ( Ordering :: SeqCst )
71
67
}
72
68
73
69
fn clone_to ( & self ) -> Box < dyn Sequencer + Send + Sync > {
0 commit comments