@@ -30,7 +30,7 @@ impl IpcBindingsServer {
3030 let binding_backends = binding_types
3131 . into_iter ( )
3232 . map ( |type_| {
33- let backend = Arc :: new ( binding_backend:: IpcBindingBackend :: new ( ) ) ;
33+ let backend = Arc :: new ( binding_backend:: IpcBindingBackend :: new ( type_ . clone ( ) ) ) ;
3434 binding_store. push_binding ( & type_, backend. clone ( ) ) ;
3535
3636 ( type_, backend)
@@ -73,6 +73,7 @@ pub mod binding_backend {
7373 use crate :: bindings:: { BindingBackend , BindingBackendTx , backend:: BindingClient } ;
7474
7575 pub struct IpcBindingBackend {
76+ type_ : String ,
7677 maybe_tx : (
7778 AtomicBool , // has data?
7879 AtomicUsize , // BindingBackendTx
@@ -86,8 +87,9 @@ pub mod binding_backend {
8687
8788 impl IpcBindingBackend {
8889 #[ inline( always) ]
89- pub const fn new ( ) -> Self {
90+ pub fn new ( type_ : String ) -> Self {
9091 Self {
92+ type_,
9193 maybe_tx : ( AtomicBool :: new ( false ) , AtomicUsize :: new ( 0 ) ) ,
9294 }
9395 }
@@ -137,7 +139,10 @@ pub mod binding_backend {
137139
138140 // SAFETY: we asserted BindingBackendTx is usize-sized;
139141 // the bool guard ensures this was previously set via set_tx.
140- Some ( unsafe { mem:: transmute :: < usize , BindingBackendTx > ( raw) } )
142+ Some ( unsafe {
143+ let tx = mem:: ManuallyDrop :: new ( mem:: transmute :: < usize , BindingBackendTx > ( raw) ) ;
144+ ( * tx) . clone ( )
145+ } )
141146 }
142147
143148 #[ inline( always) ]
@@ -175,8 +180,8 @@ pub mod binding_backend {
175180 }
176181
177182 #[ inline]
178- fn create_client ( & self , binding_name : & str ) -> Box < dyn BindingClient > {
179- Box :: new ( IpcBindingClient :: new ( binding_name . to_string ( ) ) )
183+ fn create_client ( & self ) -> Box < dyn BindingClient > {
184+ Box :: new ( IpcBindingClient :: new ( self . type_ . clone ( ) ) )
180185 }
181186 }
182187
@@ -204,13 +209,13 @@ mod binding_client {
204209 } ;
205210
206211 pub struct IpcBindingClient {
207- binding_name : String ,
212+ binding_type : String ,
208213 }
209214
210215 impl IpcBindingClient {
211216 #[ inline( always) ]
212- pub fn new ( binding_name : String ) -> Self {
213- Self { binding_name }
217+ pub fn new ( binding_type : String ) -> Self {
218+ Self { binding_type }
214219 }
215220 }
216221
@@ -232,7 +237,7 @@ mod binding_client {
232237 mut rv : v8:: ReturnValue | {
233238 let arr = args. data ( ) . cast :: < v8:: Array > ( ) ;
234239
235- let binding_name = arr
240+ let binding_type = arr
236241 . get_index ( scope, 0 )
237242 . unwrap ( )
238243 . cast :: < v8:: String > ( )
@@ -244,7 +249,7 @@ mod binding_client {
244249 to_rust_string_lossy ( scope) ;
245250
246251 let state = WorkerState :: get_from_isolate ( scope) ;
247- let tx = state. get_binding ( & binding_name ) . unwrap ( ) ;
252+ let tx = state. get_binding_tx ( & binding_type ) . unwrap ( ) ;
248253
249254 let args_len = args. length ( ) ;
250255 let arr = v8:: Array :: new ( scope, args_len) ;
@@ -331,7 +336,7 @@ mod binding_client {
331336 rv. set ( fnk. cast ( ) ) ;
332337 } ,
333338 )
334- . data ( v8:: String :: new ( scope, & self . binding_name ) ?. cast ( ) )
339+ . data ( v8:: String :: new ( scope, & self . binding_type ) ?. cast ( ) )
335340 . build ( scope) ?;
336341
337342 handler. set ( scope, v8:: String :: new ( scope, "get" ) ?. cast ( ) , get_fn. cast ( ) ) ;
@@ -348,7 +353,7 @@ mod binding_client {
348353mod task {
349354 use std:: {
350355 collections:: HashMap ,
351- io:: { self , IoSlice } ,
356+ io,
352357 string:: FromUtf8Error ,
353358 sync:: {
354359 Arc ,
@@ -432,6 +437,28 @@ mod task {
432437 let ( tx, mut rx) = binding_backend_channel ( ) ;
433438 backend. set_tx ( tx) ?;
434439
440+ // spawn dedicated reader so it's never cancelled
441+ let ( external_tx, mut external_rx) = tokio:: sync:: mpsc:: channel :: < Message > ( 32 ) ;
442+
443+ tokio:: spawn ( async move {
444+ loop {
445+ match recv. read_parse_message ( ) . await {
446+ Ok ( msg) => {
447+ if external_tx. send ( msg) . await . is_err ( ) {
448+ tracing:: error!( "errored on sending external tx" ) ;
449+ break ; // main task dropped, exit
450+ }
451+ }
452+ Err ( e) => {
453+ tracing:: error!(
454+ "failed to read & parse binding client message, breaking: {e:?}"
455+ ) ;
456+ break ;
457+ }
458+ }
459+ }
460+ } ) ;
461+
435462 let mut resolutions = HashMap :: new ( ) ;
436463 let mut roll_id = 0_u32 ;
437464
@@ -445,22 +472,20 @@ mod task {
445472 }
446473
447474 let event = tokio:: select! {
448- msg = rx. recv( ) => {
449- match msg {
450- Some ( t) => Event :: Internal ( t) ,
451- None => break ,
475+ msg = rx. recv( ) => match msg {
476+ Some ( t) => Event :: Internal ( t) ,
477+ None => {
478+ tracing:: error!( "internal channel closed: backend dropped?" ) ;
479+ break ;
452480 }
453481 } ,
454-
455- msg = recv. read_parse_message( ) => {
456- match msg {
457- Ok ( t) => Event :: External ( t) ,
458- Err ( e) => {
459- tracing:: error!( "failed to read & parse binding sclient message, breaking: {e:?}" ) ;
460- break ;
461- }
482+ msg = external_rx. recv( ) => match msg {
483+ Some ( t) => Event :: External ( t) ,
484+ None => {
485+ tracing:: error!( "reader task died" ) ;
486+ break ;
462487 }
463- }
488+ } ,
464489 } ;
465490
466491 match event {
@@ -480,6 +505,7 @@ mod task {
480505 }
481506
482507 Event :: External ( Message { id, payload } ) => {
508+ tracing:: debug!( "server finished reading payload for id={id}" ) ;
483509 if let Some ( replier) = resolutions. remove ( & id) {
484510 let _ = replier. send ( payload) ;
485511 }
@@ -536,6 +562,7 @@ mod task {
536562 // get this over with, and we're just reading from them
537563
538564 let len = self . read_u32_le ( ) . await ? as usize ;
565+
539566 let mut buf = Box :: < [ u8 ] > :: new_uninit_slice ( len) ;
540567
541568 let slice = unsafe { std:: slice:: from_raw_parts_mut ( buf. as_mut_ptr ( ) as * mut u8 , len) } ;
@@ -557,6 +584,7 @@ mod task {
557584
558585 // then we'll get the payload
559586 let raw_payload = self . read_parse_to_boxed_arr ( ) . await ?;
587+
560588 let payload = serde_json:: from_slice :: < ijson:: IValue > ( & raw_payload) ?;
561589
562590 // good. fuck you and eat it up
@@ -572,17 +600,15 @@ mod task {
572600 #[ async_trait]
573601 impl SendExt for SendHalf {
574602 async fn send_message ( & mut self , message : Message ) -> Result < ( ) , SingleTaskError > {
575- let id_raw = message. id . to_le_bytes ( ) ;
576-
577603 let payload_raw = serde_json:: to_vec ( & message. payload ) ?;
578- let len_raw = ( payload_raw . len ( ) as u32 ) . to_le_bytes ( ) ;
579-
580- let slices = [
581- IoSlice :: new ( & id_raw ) ,
582- IoSlice :: new ( & len_raw ) ,
583- IoSlice :: new ( & payload_raw) ,
584- ] ;
585- self . write_vectored ( & slices ) . await ?;
604+
605+ let mut buf = Vec :: with_capacity ( size_of :: < u32 > ( ) * 2 + payload_raw . len ( ) ) ;
606+
607+ buf . extend_from_slice ( & message . id . to_le_bytes ( ) ) ;
608+ buf . extend_from_slice ( & ( payload_raw . len ( ) as u32 ) . to_le_bytes ( ) ) ;
609+ buf . extend_from_slice ( & payload_raw) ;
610+
611+ self . write_all ( & buf ) . await ?;
586612
587613 // fah
588614 Ok ( ( ) )
0 commit comments