11//! Server-side traits.
22
33use std:: cell:: Cell ;
4- use std:: marker :: PhantomData ;
4+ use std:: sync :: mpsc ;
55
66use super :: * ;
77
@@ -53,14 +53,9 @@ impl<S: Server> Decode<'_, '_, HandleStore<S>> for MarkedSpan<S> {
5353 }
5454}
5555
56- struct Dispatcher < S : Server > {
57- handle_store : HandleStore < S > ,
58- server : S ,
59- }
60-
6156macro_rules! define_server {
6257 (
63- $( fn $method: ident( $( $arg: ident: $arg_ty: ty) ,* $( , ) ?) $( -> $ret_ty: ty) * ; ) *
58+ $( fn $method: ident( $( $arg: ident: $arg_ty: ty) ,* $( , ) ?) $( -> $ret_ty: ty) ? ; ) *
6459 ) => {
6560 pub trait Server {
6661 type TokenStream : ' static + Clone + Default ;
@@ -81,16 +76,17 @@ macro_rules! define_server {
8176}
8277with_api ! ( define_server, Self :: TokenStream , Self :: Span , Self :: Symbol ) ;
8378
79+ // FIXME(eddyb) `pub` only for `ExecutionStrategy` below.
80+ pub struct Dispatcher < S : Server > {
81+ handle_store : HandleStore < S > ,
82+ server : S ,
83+ }
84+
8485macro_rules! define_dispatcher {
8586 (
86- $( fn $method: ident( $( $arg: ident: $arg_ty: ty) ,* $( , ) ?) $( -> $ret_ty: ty) * ; ) *
87+ $( fn $method: ident( $( $arg: ident: $arg_ty: ty) ,* $( , ) ?) $( -> $ret_ty: ty) ? ; ) *
8788 ) => {
88- // FIXME(eddyb) `pub` only for `ExecutionStrategy` below.
89- pub trait DispatcherTrait {
90- fn dispatch( & mut self , buf: Buffer ) -> Buffer ;
91- }
92-
93- impl <S : Server > DispatcherTrait for Dispatcher <S > {
89+ impl <S : Server > Dispatcher <S > {
9490 fn dispatch( & mut self , mut buf: Buffer ) -> Buffer {
9591 let Dispatcher { handle_store, server } = self ;
9692
@@ -100,9 +96,7 @@ macro_rules! define_dispatcher {
10096 let mut call_method = || {
10197 $( let $arg = <$arg_ty>:: decode( & mut reader, handle_store) . unmark( ) ; ) *
10298 let r = server. $method( $( $arg) ,* ) ;
103- $(
104- let r: $ret_ty = Mark :: mark( r) ;
105- ) *
99+ $( let r: $ret_ty = Mark :: mark( r) ; ) ?
106100 r
107101 } ;
108102 // HACK(eddyb) don't use `panic::catch_unwind` in a panic.
@@ -127,10 +121,13 @@ macro_rules! define_dispatcher {
127121}
128122with_api ! ( define_dispatcher, MarkedTokenStream <S >, MarkedSpan <S >, MarkedSymbol <S >) ;
129123
124+ // This trait is currently only implemented and used once, inside of this crate.
125+ // We keep it public to allow implementing more complex execution strategies in
126+ // the future, such as wasm proc-macros.
130127pub trait ExecutionStrategy {
131128 fn run_bridge_and_client (
132129 & self ,
133- dispatcher : & mut impl DispatcherTrait ,
130+ dispatcher : & mut Dispatcher < impl Server > ,
134131 input : Buffer ,
135132 run_client : extern "C" fn ( BridgeConfig < ' _ > ) -> Buffer ,
136133 force_show_panics : bool ,
@@ -169,110 +166,78 @@ impl Drop for RunningSameThreadGuard {
169166 }
170167}
171168
172- pub struct MaybeCrossThread < P > {
173- cross_thread : bool ,
174- marker : PhantomData < P > ,
169+ pub struct MaybeCrossThread {
170+ pub cross_thread : bool ,
175171}
176172
177- impl < P > MaybeCrossThread < P > {
178- pub const fn new ( cross_thread : bool ) -> Self {
179- MaybeCrossThread { cross_thread, marker : PhantomData }
180- }
181- }
173+ pub const SAME_THREAD : MaybeCrossThread = MaybeCrossThread { cross_thread : false } ;
174+ pub const CROSS_THREAD : MaybeCrossThread = MaybeCrossThread { cross_thread : true } ;
182175
183- impl < P > ExecutionStrategy for MaybeCrossThread < P >
184- where
185- P : MessagePipe < Buffer > + Send + ' static ,
186- {
176+ impl ExecutionStrategy for MaybeCrossThread {
187177 fn run_bridge_and_client (
188178 & self ,
189- dispatcher : & mut impl DispatcherTrait ,
179+ dispatcher : & mut Dispatcher < impl Server > ,
190180 input : Buffer ,
191181 run_client : extern "C" fn ( BridgeConfig < ' _ > ) -> Buffer ,
192182 force_show_panics : bool ,
193183 ) -> Buffer {
194184 if self . cross_thread || ALREADY_RUNNING_SAME_THREAD . get ( ) {
195- <CrossThread < P > >:: new ( ) . run_bridge_and_client (
196- dispatcher,
197- input,
198- run_client,
199- force_show_panics,
200- )
201- } else {
202- SameThread . run_bridge_and_client ( dispatcher, input, run_client, force_show_panics)
203- }
204- }
205- }
206-
207- pub struct SameThread ;
208-
209- impl ExecutionStrategy for SameThread {
210- fn run_bridge_and_client (
211- & self ,
212- dispatcher : & mut impl DispatcherTrait ,
213- input : Buffer ,
214- run_client : extern "C" fn ( BridgeConfig < ' _ > ) -> Buffer ,
215- force_show_panics : bool ,
216- ) -> Buffer {
217- let _guard = RunningSameThreadGuard :: new ( ) ;
218-
219- let mut dispatch = |buf| dispatcher. dispatch ( buf) ;
220-
221- run_client ( BridgeConfig { input, dispatch : ( & mut dispatch) . into ( ) , force_show_panics } )
222- }
223- }
224-
225- pub struct CrossThread < P > ( PhantomData < P > ) ;
226-
227- impl < P > CrossThread < P > {
228- pub const fn new ( ) -> Self {
229- CrossThread ( PhantomData )
230- }
231- }
185+ let ( mut server, mut client) = MessagePipe :: new ( ) ;
186+
187+ let join_handle = thread:: spawn ( move || {
188+ let mut dispatch = |b : Buffer | -> Buffer {
189+ client. send ( b) ;
190+ client. recv ( ) . expect ( "server died while client waiting for reply" )
191+ } ;
192+
193+ run_client ( BridgeConfig {
194+ input,
195+ dispatch : ( & mut dispatch) . into ( ) ,
196+ force_show_panics,
197+ } )
198+ } ) ;
199+
200+ while let Some ( b) = server. recv ( ) {
201+ server. send ( dispatcher. dispatch ( b) ) ;
202+ }
232203
233- impl < P > ExecutionStrategy for CrossThread < P >
234- where
235- P : MessagePipe < Buffer > + Send + ' static ,
236- {
237- fn run_bridge_and_client (
238- & self ,
239- dispatcher : & mut impl DispatcherTrait ,
240- input : Buffer ,
241- run_client : extern "C" fn ( BridgeConfig < ' _ > ) -> Buffer ,
242- force_show_panics : bool ,
243- ) -> Buffer {
244- let ( mut server, mut client) = P :: new ( ) ;
204+ join_handle. join ( ) . unwrap ( )
205+ } else {
206+ let _guard = RunningSameThreadGuard :: new ( ) ;
245207
246- let join_handle = thread:: spawn ( move || {
247- let mut dispatch = |b : Buffer | -> Buffer {
248- client. send ( b) ;
249- client. recv ( ) . expect ( "server died while client waiting for reply" )
250- } ;
208+ let mut dispatch = |buf| dispatcher. dispatch ( buf) ;
251209
252210 run_client ( BridgeConfig { input, dispatch : ( & mut dispatch) . into ( ) , force_show_panics } )
253- } ) ;
254-
255- while let Some ( b) = server. recv ( ) {
256- server. send ( dispatcher. dispatch ( b) ) ;
257211 }
258-
259- join_handle. join ( ) . unwrap ( )
260212 }
261213}
262214
263215/// A message pipe used for communicating between server and client threads.
264- pub trait MessagePipe < T > : Sized {
216+ struct MessagePipe < T > {
217+ tx : mpsc:: SyncSender < T > ,
218+ rx : mpsc:: Receiver < T > ,
219+ }
220+
221+ impl < T > MessagePipe < T > {
265222 /// Creates a new pair of endpoints for the message pipe.
266- fn new ( ) -> ( Self , Self ) ;
223+ fn new ( ) -> ( Self , Self ) {
224+ let ( tx1, rx1) = mpsc:: sync_channel ( 1 ) ;
225+ let ( tx2, rx2) = mpsc:: sync_channel ( 1 ) ;
226+ ( MessagePipe { tx : tx1, rx : rx2 } , MessagePipe { tx : tx2, rx : rx1 } )
227+ }
267228
268229 /// Send a message to the other endpoint of this pipe.
269- fn send ( & mut self , value : T ) ;
230+ fn send ( & mut self , value : T ) {
231+ self . tx . send ( value) . unwrap ( ) ;
232+ }
270233
271234 /// Receive a message from the other endpoint of this pipe.
272235 ///
273236 /// Returns `None` if the other end of the pipe has been destroyed, and no
274237 /// message was received.
275- fn recv ( & mut self ) -> Option < T > ;
238+ fn recv ( & mut self ) -> Option < T > {
239+ self . rx . recv ( ) . ok ( )
240+ }
276241}
277242
278243fn run_server <
0 commit comments