@@ -85,14 +85,16 @@ macro_rules! define_dispatcher_impl {
85
85
( $( $name: ident {
86
86
$( fn $method: ident( $( $arg: ident: $arg_ty: ty) ,* $( , ) ?) $( -> $ret_ty: ty) ?; ) *
87
87
} ) ,* $( , ) ?) => {
88
- // FIXME(eddyb) `pub` only for `ExecutionStrategy` below.
89
- pub trait DispatcherTrait {
90
- // HACK(eddyb) these are here to allow `Self::$name` to work below.
88
+ // HACK(eddyb) only a (private) trait because inherent impls can't have
89
+ // associated types (and `Self::AssocType` is used within `$arg_ty`).
90
+ // While `with_api!` allows customizing `Self`, it would have to be
91
+ // extended to allow `Self::` to become `<MarkedTypes<S> as Types>::`.
92
+ trait DispatcherPrivateHelperTrait {
91
93
$( type $name; ) *
92
94
fn dispatch( & mut self , b: Buffer <u8 >) -> Buffer <u8 >;
93
95
}
94
96
95
- impl <S : Server > DispatcherTrait for Dispatcher <MarkedTypes <S >> {
97
+ impl <S : Server > DispatcherPrivateHelperTrait for Dispatcher <MarkedTypes <S >> {
96
98
$( type $name = <MarkedTypes <S > as Types >:: $name; ) *
97
99
fn dispatch( & mut self , mut b: Buffer <u8 >) -> Buffer <u8 > {
98
100
let Dispatcher { handle_store, server } = self ;
@@ -133,60 +135,6 @@ with_api!(Self, self_, define_dispatcher_impl);
133
135
pub type DynDispatch < ' a > = & ' a mut dyn FnMut ( Buffer < u8 > ) -> Buffer < u8 > ;
134
136
135
137
pub trait ExecutionStrategy {
136
- fn run_bridge_and_client < D : Copy + Send + ' static > (
137
- & self ,
138
- dispatcher : & mut impl DispatcherTrait ,
139
- input : Buffer < u8 > ,
140
- run_client : extern "C" fn ( Bridge < ' _ > , D ) -> Buffer < u8 > ,
141
- client_data : D ,
142
- force_show_panics : bool ,
143
- ) -> Buffer < u8 > {
144
- enum OptionDynDispatchL { }
145
-
146
- impl < ' a > scoped_cell:: ApplyL < ' a > for OptionDynDispatchL {
147
- type Out = Option < DynDispatch < ' a > > ;
148
- }
149
-
150
- thread_local ! {
151
- /// Dispatch callback held in server TLS, and using server ABI, but
152
- /// on the client thread (which can differ from the server thread).
153
- //
154
- // FIXME(eddyb) how redundant is this with the (also) thread-local
155
- // client-side `BridgeState`? Some of that indirection can probably
156
- // be removed, as long as concerns around further isolation methods
157
- // (IPC and/or wasm) are considered.
158
- static CLIENT_THREAD_DISPATCH : scoped_cell:: ScopedCell <OptionDynDispatchL > =
159
- scoped_cell:: ScopedCell :: new( None ) ;
160
- }
161
-
162
- self . cross_thread_dispatch (
163
- |b| dispatcher. dispatch ( b) ,
164
- move |client_thread_dispatch| {
165
- CLIENT_THREAD_DISPATCH . with ( |dispatch_slot| {
166
- dispatch_slot. set ( Some ( client_thread_dispatch) , || {
167
- let mut dispatch = |b| {
168
- CLIENT_THREAD_DISPATCH . with ( |dispatch_slot| {
169
- dispatch_slot. replace ( None , |mut client_thread_dispatch| {
170
- client_thread_dispatch. as_mut ( ) . unwrap ( ) ( b)
171
- } )
172
- } )
173
- } ;
174
-
175
- run_client (
176
- Bridge {
177
- cached_buffer : input,
178
- dispatch : ( & mut dispatch) . into ( ) ,
179
- force_show_panics,
180
- _marker : marker:: PhantomData ,
181
- } ,
182
- client_data,
183
- )
184
- } )
185
- } )
186
- } ,
187
- )
188
- }
189
-
190
138
fn cross_thread_dispatch (
191
139
& self ,
192
140
server_thread_dispatch : impl FnMut ( Buffer < u8 > ) -> Buffer < u8 > ,
@@ -291,6 +239,57 @@ impl ExecutionStrategy for CrossThread2 {
291
239
}
292
240
}
293
241
242
+ fn run_bridge_and_client < D : Copy + Send + ' static > (
243
+ strategy : & impl ExecutionStrategy ,
244
+ server_thread_dispatch : impl FnMut ( Buffer < u8 > ) -> Buffer < u8 > ,
245
+ input : Buffer < u8 > ,
246
+ run_client : extern "C" fn ( Bridge < ' _ > , D ) -> Buffer < u8 > ,
247
+ client_data : D ,
248
+ force_show_panics : bool ,
249
+ ) -> Buffer < u8 > {
250
+ enum OptionDynDispatchL { }
251
+
252
+ impl < ' a > scoped_cell:: ApplyL < ' a > for OptionDynDispatchL {
253
+ type Out = Option < DynDispatch < ' a > > ;
254
+ }
255
+
256
+ thread_local ! {
257
+ /// Dispatch callback held in server TLS, and using server ABI, but
258
+ /// on the client thread (which can differ from the server thread).
259
+ //
260
+ // FIXME(eddyb) how redundant is this with the (also) thread-local
261
+ // client-side `BridgeState`? Some of that indirection can probably
262
+ // be removed, as long as concerns around further isolation methods
263
+ // (IPC and/or wasm) are considered.
264
+ static CLIENT_THREAD_DISPATCH : scoped_cell:: ScopedCell <OptionDynDispatchL > =
265
+ scoped_cell:: ScopedCell :: new( None ) ;
266
+ }
267
+
268
+ strategy. cross_thread_dispatch ( server_thread_dispatch, move |client_thread_dispatch| {
269
+ CLIENT_THREAD_DISPATCH . with ( |dispatch_slot| {
270
+ dispatch_slot. set ( Some ( client_thread_dispatch) , || {
271
+ let mut dispatch = |b| {
272
+ CLIENT_THREAD_DISPATCH . with ( |dispatch_slot| {
273
+ dispatch_slot. replace ( None , |mut client_thread_dispatch| {
274
+ client_thread_dispatch. as_mut ( ) . unwrap ( ) ( b)
275
+ } )
276
+ } )
277
+ } ;
278
+
279
+ run_client (
280
+ Bridge {
281
+ cached_buffer : input,
282
+ dispatch : ( & mut dispatch) . into ( ) ,
283
+ force_show_panics,
284
+ _marker : marker:: PhantomData ,
285
+ } ,
286
+ client_data,
287
+ )
288
+ } )
289
+ } )
290
+ } )
291
+ }
292
+
294
293
fn run_server <
295
294
S : Server ,
296
295
I : Encode < HandleStore < MarkedTypes < S > > > ,
@@ -311,8 +310,9 @@ fn run_server<
311
310
let mut b = Buffer :: new ( ) ;
312
311
input. encode ( & mut b, & mut dispatcher. handle_store ) ;
313
312
314
- b = strategy. run_bridge_and_client (
315
- & mut dispatcher,
313
+ b = run_bridge_and_client (
314
+ strategy,
315
+ |b| dispatcher. dispatch ( b) ,
316
316
b,
317
317
run_client,
318
318
client_data,
0 commit comments