@@ -326,8 +326,41 @@ fn wrap_create_workspace(cb: JsCreateWorkspaceCb) -> ExternalLinterCreateWorkspa
326326}
327327
328328/// Wrap `destroyWorkspace` JS callback as a normal Rust function.
329+ ///
330+ /// The JS-side `destroyWorkspace` function is synchronous, but it's wrapped in a `ThreadsafeFunction`,
331+ /// so cannot be called synchronously. Use an `mpsc::channel` to wait for the result from JS side,
332+ /// and block current thread until `destroyWorkspace` completes execution.
329333fn wrap_destroy_workspace ( cb : JsDestroyWorkspaceCb ) -> ExternalLinterDestroyWorkspaceCb {
330334 Arc :: new ( Box :: new ( move |workspace_uri| {
331- let _ = cb. call ( workspace_uri, ThreadsafeFunctionCallMode :: NonBlocking ) ;
335+ let ( tx, rx) = channel ( ) ;
336+
337+ // Send data to JS
338+ let status = cb. call_with_return_value (
339+ workspace_uri,
340+ ThreadsafeFunctionCallMode :: NonBlocking ,
341+ move |result, _env| {
342+ // This call cannot fail, because `rx.recv()` below blocks until it receives a message.
343+ // This closure is a `FnOnce`, so it can't be called more than once, so only 1 message can be sent.
344+ // Therefore, `rx` cannot be dropped before this call.
345+ let res = tx. send ( result) ;
346+ debug_assert ! ( res. is_ok( ) , "Failed to send result of `destroyWorkspace`" ) ;
347+ Ok ( ( ) )
348+ } ,
349+ ) ;
350+
351+ if status == Status :: Ok {
352+ match rx. recv ( ) {
353+ // Destroying workspace succeeded
354+ Ok ( Ok ( ( ) ) ) => Ok ( ( ) ) ,
355+ // `destroyWorkspace` threw an error
356+ Ok ( Err ( err) ) => Err ( format ! ( "`destroyWorkspace` threw an error: {err}" ) ) ,
357+ // Sender "hung up" - should be impossible because closure passed to `call_with_return_value`
358+ // takes ownership of the sender `tx`. Unless NAPI-RS drops the closure without calling it,
359+ // `tx.send()` always happens before `tx` is dropped.
360+ Err ( err) => Err ( format ! ( "`destroyWorkspace` did not respond: {err}" ) ) ,
361+ }
362+ } else {
363+ Err ( format ! ( "Failed to schedule `destroyWorkspace` callback: {status:?}" ) )
364+ }
332365 } ) )
333366}
0 commit comments