1
1
use std:: collections:: VecDeque ;
2
- use std:: num:: NonZeroU32 ;
3
2
4
3
use rustc_hash:: FxHashMap ;
5
4
@@ -20,144 +19,155 @@ impl<X> Runtime<X> {
20
19
crate :: logger:: debug!( event = "handle_message" , ?msg) ;
21
20
match msg {
22
21
Message :: PromiseResolved {
23
- promise_id ,
22
+ promise ,
24
23
ref result,
25
- } => self . process_promise ( promise_id , result, & Value :: NONE ) ,
24
+ } => self . process_promise ( promise , result, & Value :: NONE ) ,
26
25
Message :: PromiseRejected {
27
- promise_id ,
26
+ promise ,
28
27
ref error,
29
- } => self . process_promise ( promise_id , & Value :: NONE , error) ,
28
+ } => self . process_promise ( promise , & Value :: NONE , error) ,
30
29
}
31
30
}
32
31
33
32
// promise
34
33
35
- pub fn register_promise ( & mut self , coroutine : * mut Coroutine ) -> PromiseId {
34
+ pub fn register_promise ( & mut self , coroutine : * mut Coroutine ) -> Promise {
36
35
crate :: logger:: debug!( event = "register_promise" , ?coroutine) ;
37
36
self . tasklet_system . register_promise ( coroutine)
38
37
}
39
38
40
- pub fn await_promise ( & mut self , promise_id : PromiseId , awaiting : PromiseId ) {
41
- crate :: logger:: debug!( event = "await_promise" , ?promise_id , ?awaiting) ;
42
- self . tasklet_system . await_promise ( promise_id , awaiting) ;
39
+ pub fn await_promise ( & mut self , promise : Promise , awaiting : Promise ) {
40
+ crate :: logger:: debug!( event = "await_promise" , ?promise , ?awaiting) ;
41
+ self . tasklet_system . await_promise ( promise , awaiting) ;
43
42
}
44
43
45
- pub fn process_promise ( & mut self , promise_id : PromiseId , result : & Value , error : & Value ) {
46
- crate :: logger:: debug!( event = "process_promise" , ?promise_id , ?result, ?error) ;
47
- let coroutine = self . tasklet_system . get_coroutine ( promise_id ) ;
48
- match Coroutine :: resume ( self . as_void_ptr ( ) , coroutine, promise_id , result, error) {
44
+ pub fn process_promise ( & mut self , promise : Promise , result : & Value , error : & Value ) {
45
+ crate :: logger:: debug!( event = "process_promise" , ?promise , ?result, ?error) ;
46
+ let coroutine = self . tasklet_system . get_coroutine ( promise ) ;
47
+ match Coroutine :: resume ( self . as_void_ptr ( ) , coroutine, promise , result, error) {
49
48
CoroutineStatus :: Done ( result) => {
50
- self . tasklet_system . resolve_promise ( promise_id , result)
49
+ self . tasklet_system . resolve_promise ( promise , result)
51
50
}
52
- CoroutineStatus :: Error ( error) => self . tasklet_system . reject_promise ( promise_id , error) ,
51
+ CoroutineStatus :: Error ( error) => self . tasklet_system . reject_promise ( promise , error) ,
53
52
CoroutineStatus :: Suspend => ( ) ,
54
53
}
55
54
}
56
55
57
- pub fn emit_promise_resolved ( & mut self , promise_id : PromiseId , result : Value ) {
56
+ pub fn emit_promise_resolved ( & mut self , promise : Promise , result : Value ) {
58
57
self . tasklet_system
59
- . emit_promise_resolved ( promise_id , result) ;
58
+ . emit_promise_resolved ( promise , result) ;
60
59
}
61
60
}
62
61
63
62
#[ derive( Clone , Copy , Debug , Eq , Hash , PartialEq ) ]
64
- pub struct PromiseId ( NonZeroU32 ) ;
63
+ pub struct Promise ( u32 ) ;
65
64
66
- impl From < u32 > for PromiseId {
65
+ impl From < u32 > for Promise {
67
66
fn from ( value : u32 ) -> Self {
68
- Self ( NonZeroU32 :: new ( value) . unwrap ( ) )
67
+ Self ( value)
69
68
}
70
69
}
71
70
72
- impl From < PromiseId > for u32 {
73
- fn from ( value : PromiseId ) -> Self {
74
- value. 0 . get ( )
71
+ impl From < Promise > for u32 {
72
+ fn from ( value : Promise ) -> Self {
73
+ value. 0
75
74
}
76
75
}
77
76
78
77
pub struct System {
79
78
messages : VecDeque < Message > ,
80
- promises : FxHashMap < PromiseId , Promise > ,
81
- next_promise_id : u32 ,
79
+ promises : FxHashMap < Promise , PromiseDriver > ,
80
+ next_promise : u32 ,
82
81
}
83
82
84
83
impl System {
85
84
pub fn new ( ) -> Self {
86
85
Self {
87
86
messages : Default :: default ( ) ,
88
87
promises : Default :: default ( ) ,
89
- next_promise_id : 1 ,
88
+ next_promise : 0 ,
90
89
}
91
90
}
92
91
93
92
// promises
94
93
95
- fn register_promise ( & mut self , coroutine : * mut Coroutine ) -> PromiseId {
96
- let promise_id = PromiseId ( NonZeroU32 :: new ( self . next_promise_id ) . unwrap ( ) ) ;
97
- self . promises . insert ( promise_id, Promise :: new ( coroutine) ) ;
98
- self . next_promise_id += 1 ;
99
- promise_id
94
+ fn register_promise ( & mut self , coroutine : * mut Coroutine ) -> Promise {
95
+ let promise = self . new_promise ( ) ;
96
+ self . promises . insert ( promise, PromiseDriver :: new ( coroutine) ) ;
97
+ promise
100
98
}
101
99
102
- fn await_promise ( & mut self , promise_id : PromiseId , awaiting : PromiseId ) {
103
- debug_assert ! ( self . promises. contains_key( & promise_id) ) ;
100
+ fn new_promise ( & mut self ) -> Promise {
101
+ assert ! ( self . promises. len( ) < u32 :: MAX as usize ) ;
102
+ loop {
103
+ let promise = Promise ( self . next_promise ) ;
104
+ if !self . promises . contains_key ( & promise) {
105
+ return promise;
106
+ }
107
+ self . next_promise = self . next_promise . wrapping_add ( 1 ) ;
108
+ }
109
+ // never reach here
110
+ }
111
+
112
+ fn await_promise ( & mut self , promise : Promise , awaiting : Promise ) {
113
+ debug_assert ! ( self . promises. contains_key( & promise) ) ;
104
114
debug_assert ! ( self . promises. contains_key( & awaiting) ) ;
105
- let promise = self . promises . get_mut ( & promise_id ) . unwrap ( ) ;
106
- debug_assert ! ( promise . awaiting. is_none( ) ) ;
107
- match promise . state {
108
- PromiseState :: Pending => promise . awaiting = Some ( awaiting) ,
115
+ let driver = self . promises . get_mut ( & promise ) . unwrap ( ) ;
116
+ debug_assert ! ( driver . awaiting. is_none( ) ) ;
117
+ match driver . state {
118
+ PromiseState :: Pending => driver . awaiting = Some ( awaiting) ,
109
119
PromiseState :: Resolved ( result) => {
110
120
self . emit_promise_resolved ( awaiting, result) ;
111
- self . promises . remove ( & promise_id ) ;
121
+ self . promises . remove ( & promise ) ;
112
122
}
113
123
PromiseState :: Rejected ( error) => {
114
124
self . emit_promise_rejected ( awaiting, error) ;
115
- self . promises . remove ( & promise_id ) ;
125
+ self . promises . remove ( & promise ) ;
116
126
}
117
127
}
118
128
}
119
129
120
- fn get_coroutine ( & self , promise_id : PromiseId ) -> * mut Coroutine {
121
- self . promises . get ( & promise_id ) . unwrap ( ) . coroutine
130
+ fn get_coroutine ( & self , promise : Promise ) -> * mut Coroutine {
131
+ self . promises . get ( & promise ) . unwrap ( ) . coroutine
122
132
}
123
133
124
- fn emit_promise_resolved ( & mut self , promise_id : PromiseId , result : Value ) {
125
- crate :: logger:: debug!( event = "emit_promise_resolved" , ?promise_id , ?result) ;
134
+ fn emit_promise_resolved ( & mut self , promise : Promise , result : Value ) {
135
+ crate :: logger:: debug!( event = "emit_promise_resolved" , ?promise , ?result) ;
126
136
self . messages
127
- . push_back ( Message :: PromiseResolved { promise_id , result } ) ;
137
+ . push_back ( Message :: PromiseResolved { promise , result } ) ;
128
138
}
129
139
130
- fn emit_promise_rejected ( & mut self , promise_id : PromiseId , error : Value ) {
131
- crate :: logger:: debug!( event = "emit_promise_rejected" , ?promise_id , ?error) ;
140
+ fn emit_promise_rejected ( & mut self , promise : Promise , error : Value ) {
141
+ crate :: logger:: debug!( event = "emit_promise_rejected" , ?promise , ?error) ;
132
142
self . messages
133
- . push_back ( Message :: PromiseRejected { promise_id , error } ) ;
143
+ . push_back ( Message :: PromiseRejected { promise , error } ) ;
134
144
}
135
145
136
146
fn next_msg ( & mut self ) -> Option < Message > {
137
147
self . messages . pop_front ( )
138
148
}
139
149
140
- fn resolve_promise ( & mut self , promise_id : PromiseId , result : Value ) {
141
- crate :: logger:: debug!( event = "resolve_promise" , ?promise_id , ?result) ;
142
- let promise = self . promises . get_mut ( & promise_id ) . unwrap ( ) ;
143
- debug_assert ! ( matches!( promise . state, PromiseState :: Pending ) ) ;
144
- if let Some ( awaiting) = promise . awaiting {
145
- self . promises . remove ( & promise_id ) ;
150
+ fn resolve_promise ( & mut self , promise : Promise , result : Value ) {
151
+ crate :: logger:: debug!( event = "resolve_promise" , ?promise , ?result) ;
152
+ let driver = self . promises . get_mut ( & promise ) . unwrap ( ) ;
153
+ debug_assert ! ( matches!( driver . state, PromiseState :: Pending ) ) ;
154
+ if let Some ( awaiting) = driver . awaiting {
155
+ self . promises . remove ( & promise ) ;
146
156
self . emit_promise_resolved ( awaiting, result) ;
147
157
} else {
148
- promise . state = PromiseState :: Resolved ( result) ;
158
+ driver . state = PromiseState :: Resolved ( result) ;
149
159
}
150
160
}
151
161
152
- fn reject_promise ( & mut self , promise_id : PromiseId , error : Value ) {
153
- crate :: logger:: debug!( event = "reject_promise" , ?promise_id , ?error) ;
154
- let promise = self . promises . get_mut ( & promise_id ) . unwrap ( ) ;
155
- debug_assert ! ( matches!( promise . state, PromiseState :: Pending ) ) ;
156
- if let Some ( awaiting) = promise . awaiting {
157
- self . promises . remove ( & promise_id ) ;
162
+ fn reject_promise ( & mut self , promise : Promise , error : Value ) {
163
+ crate :: logger:: debug!( event = "reject_promise" , ?promise , ?error) ;
164
+ let driver = self . promises . get_mut ( & promise ) . unwrap ( ) ;
165
+ debug_assert ! ( matches!( driver . state, PromiseState :: Pending ) ) ;
166
+ if let Some ( awaiting) = driver . awaiting {
167
+ self . promises . remove ( & promise ) ;
158
168
self . emit_promise_rejected ( awaiting, error) ;
159
169
} else {
160
- promise . state = PromiseState :: Rejected ( error) ;
170
+ driver . state = PromiseState :: Rejected ( error) ;
161
171
}
162
172
}
163
173
}
@@ -167,26 +177,26 @@ impl System {
167
177
#[ derive( Debug ) ]
168
178
enum Message {
169
179
PromiseResolved {
170
- promise_id : PromiseId ,
180
+ promise : Promise ,
171
181
result : Value ,
172
182
} ,
173
183
PromiseRejected {
174
- promise_id : PromiseId ,
184
+ promise : Promise ,
175
185
error : Value ,
176
186
} ,
177
187
}
178
188
179
189
// promise
180
190
181
191
// TODO: should the coroutine be separated from the promise?
182
- struct Promise {
192
+ struct PromiseDriver {
183
193
// TODO(issue#237): GcCellRef
184
194
coroutine : * mut Coroutine ,
185
- awaiting : Option < PromiseId > ,
195
+ awaiting : Option < Promise > ,
186
196
state : PromiseState ,
187
197
}
188
198
189
- impl Promise {
199
+ impl PromiseDriver {
190
200
fn new ( coroutine : * mut Coroutine ) -> Self {
191
201
Self {
192
202
coroutine,
0 commit comments