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