11import {
22 ThreadMessageHandler ,
33 type ThreadMessageHandlerOptions ,
4- type LoadPayload
4+ type LoadPayload ,
5+ type WorkerMessageEvent
56} from '@emnapi/wasi-threads'
67import type { NapiModule } from './emnapi/index'
78import type { InstantiatedSource } from './load'
@@ -21,7 +22,24 @@ export class MessageHandler extends ThreadMessageHandler {
2122 if ( typeof options . onLoad !== 'function' ) {
2223 throw new TypeError ( 'options.onLoad is not a function' )
2324 }
24- super ( options )
25+ const userOnError = options . onError
26+ super ( {
27+ ...options ,
28+ onError : ( err , type ) => {
29+ const emnapi_thread_crashed = this . instance ?. exports . emnapi_thread_crashed as ( ) => void
30+ if ( typeof emnapi_thread_crashed === 'function' ) {
31+ emnapi_thread_crashed ( )
32+ } /* else {
33+ tryWakeUpPthreadJoin(this.instance!)
34+ } */
35+
36+ if ( typeof userOnError === 'function' ) {
37+ userOnError ( err , type )
38+ } else {
39+ throw err
40+ }
41+ }
42+ } )
2543 this . napiModule = undefined
2644 }
2745
@@ -38,21 +56,39 @@ export class MessageHandler extends ThreadMessageHandler {
3856 return source
3957 }
4058
41- public override handle ( e : any ) : void {
59+ public override handle ( e : WorkerMessageEvent ) : void {
4260 super . handle ( e )
4361 if ( e ?. data ?. __emnapi__ ) {
4462 const type = e . data . __emnapi__ . type
4563 const payload = e . data . __emnapi__ . payload
46-
47- if ( type === 'async-worker-init' ) {
48- this . handleAfterLoad ( e , ( ) => {
49- this . napiModule ! . initWorker ( payload . arg )
50- } )
51- } else if ( type === 'async-work-execute' ) {
52- this . handleAfterLoad ( e , ( ) => {
53- this . napiModule ! . executeAsyncWork ( payload . work )
54- } )
64+ try {
65+ if ( type === 'async-worker-init' ) {
66+ this . handleAfterLoad ( e , ( ) => {
67+ this . napiModule ! . initWorker ( payload . arg )
68+ } )
69+ } else if ( type === 'async-work-execute' ) {
70+ this . handleAfterLoad ( e , ( ) => {
71+ this . napiModule ! . executeAsyncWork ( payload . work )
72+ } )
73+ }
74+ } catch ( err ) {
75+ this . onError ( err , type )
5576 }
5677 }
5778 }
5879}
80+
81+ // function tryWakeUpPthreadJoin (instance: WebAssembly.Instance): void {
82+ // // https://github.com/WebAssembly/wasi-libc/blob/574b88da481569b65a237cb80daf9a2d5aeaf82d/libc-top-half/musl/src/thread/pthread_join.c#L18-L21
83+ // const pthread_self = instance.exports.pthread_self as () => number
84+ // const memory = instance.exports.memory as WebAssembly.Memory
85+ // if (typeof pthread_self === 'function') {
86+ // const selfThread = pthread_self()
87+ // if (selfThread && memory) {
88+ // // https://github.com/WebAssembly/wasi-libc/blob/574b88da481569b65a237cb80daf9a2d5aeaf82d/libc-top-half/musl/src/internal/pthread_impl.h#L45
89+ // const detatchState = new Int32Array(memory.buffer, selfThread + 7 * 4 /** detach_state */, 1)
90+ // Atomics.store(detatchState, 0, 0)
91+ // Atomics.notify(detatchState, 0, Infinity)
92+ // }
93+ // }
94+ // }
0 commit comments