@@ -47,11 +47,7 @@ fn handle_pair(
47
47
tx2 : UnboundedSender < Stop > ,
48
48
avail : WorkerAvailability ,
49
49
) -> ( WorkerHandleAccept , WorkerHandleServer ) {
50
- let accept = WorkerHandleAccept {
51
- idx,
52
- tx : tx1,
53
- avail,
54
- } ;
50
+ let accept = WorkerHandleAccept { tx : tx1, avail } ;
55
51
56
52
let server = WorkerHandleServer { idx, tx : tx2 } ;
57
53
@@ -63,16 +59,22 @@ fn handle_pair(
63
59
///
64
60
/// Held by [Accept](crate::accept::Accept).
65
61
pub ( crate ) struct WorkerHandleAccept {
66
- pub idx : usize ,
67
62
tx : UnboundedSender < Conn > ,
68
63
avail : WorkerAvailability ,
69
64
}
70
65
71
66
impl WorkerHandleAccept {
67
+ #[ inline( always) ]
68
+ pub ( crate ) fn idx ( & self ) -> usize {
69
+ self . avail . idx
70
+ }
71
+
72
+ #[ inline( always) ]
72
73
pub ( crate ) fn send ( & self , msg : Conn ) -> Result < ( ) , Conn > {
73
74
self . tx . send ( msg) . map_err ( |msg| msg. 0 )
74
75
}
75
76
77
+ #[ inline( always) ]
76
78
pub ( crate ) fn available ( & self ) -> bool {
77
79
self . avail . available ( )
78
80
}
@@ -110,13 +112,18 @@ impl WorkerAvailability {
110
112
}
111
113
}
112
114
115
+ #[ inline( always) ]
113
116
pub fn available ( & self ) -> bool {
114
117
self . available . load ( Ordering :: Acquire )
115
118
}
116
119
117
120
pub fn set ( & self , val : bool ) {
118
- let old = self . available . swap ( val, Ordering :: Release ) ;
119
- // notify the accept on switched to available.
121
+ // Ordering:
122
+ //
123
+ // There could be multiple set calls happen in one <ServerWorker as Future>::poll.
124
+ // Order is important between them.
125
+ let old = self . available . swap ( val, Ordering :: AcqRel ) ;
126
+ // Notify the accept on switched to available.
120
127
if !old && val {
121
128
self . waker . wake ( WakerInterest :: WorkerAvailable ( self . idx ) ) ;
122
129
}
@@ -374,6 +381,10 @@ impl Default for WorkerState {
374
381
375
382
impl Drop for ServerWorker {
376
383
fn drop ( & mut self ) {
384
+ // Set availability to true so if accept try to send connection to this worker
385
+ // it would find worker is gone and remove it.
386
+ // This is helpful when worker is dropped unexpected.
387
+ self . availability . set ( true ) ;
377
388
// Stop the Arbiter ServerWorker runs on on drop.
378
389
Arbiter :: current ( ) . stop ( ) ;
379
390
}
0 commit comments