@@ -10,21 +10,27 @@ import {
1010import * as JSValue from "./js-value.js" ;
1111import { Memory } from "./memory.js" ;
1212
13+ type MainToWorkerMessage = {
14+ type : "wake" ;
15+ } ;
16+
17+ type WorkerToMainMessage = {
18+ type : "job" ;
19+ data : number ;
20+ } ;
21+
1322/**
1423 * A thread channel is a set of functions that are used to communicate between
1524 * the main thread and the worker thread. The main thread and the worker thread
16- * can send jobs to each other using these functions.
25+ * can send messages to each other using these functions.
1726 *
1827 * @example
1928 * ```javascript
2029 * // worker.js
2130 * const runtime = new SwiftRuntime({
2231 * threadChannel: {
23- * wakeUpMainThread: (unownedJob) => {
24- * // Send the job to the main thread
25- * postMessage(unownedJob);
26- * },
27- * listenWakeEventFromMainThread: (listener) => {
32+ * postMessageToMainThread: postMessage,
33+ * listenMessageFromMainThread: (listener) => {
2834 * self.onmessage = (event) => {
2935 * listener(event.data);
3036 * };
@@ -36,10 +42,10 @@ import { Memory } from "./memory.js";
3642 * const worker = new Worker("worker.js");
3743 * const runtime = new SwiftRuntime({
3844 * threadChannel: {
39- * wakeUpWorkerThread : (tid, data) => {
45+ * postMessageToWorkerThread : (tid, data) => {
4046 * worker.postMessage(data);
4147 * },
42- * listenMainJobFromWorkerThread : (tid, listener) => {
48+ * listenMessageFromWorkerThread : (tid, listener) => {
4349 * worker.onmessage = (event) => {
4450 listener(event.data);
4551 * };
@@ -50,40 +56,42 @@ import { Memory } from "./memory.js";
5056 */
5157export type SwiftRuntimeThreadChannel =
5258 | {
53- /**
54- * This function is called when the Web Worker thread sends a job to the main thread.
55- * The unownedJob is the pointer to the unowned job object in the Web Worker thread .
56- * The job submitted by this function expected to be listened by `listenMainJobFromWorkerThread` .
57- */
58- wakeUpMainThread : ( unownedJob : number ) => void ;
59+ /**
60+ * This function is used to send messages from the worker thread to the main thread.
61+ * The message submitted by this function is expected to be listened by `listenMessageFromWorkerThread` .
62+ * @param message The message to be sent to the main thread .
63+ */
64+ postMessageToMainThread : ( message : WorkerToMainMessage ) => void ;
5965 /**
6066 * This function is expected to be set in the worker thread and should listen
61- * to the wake event from the main thread sent by `wakeUpWorkerThread `.
62- * The passed listener function awakes the Web Worker thread.
67+ * to messages from the main thread sent by `postMessageToWorkerThread `.
68+ * @param listener The listener function to be called when a message is received from the main thread.
6369 */
64- listenWakeEventFromMainThread : ( listener : ( data : unknown ) => void ) => void ;
70+ listenMessageFromMainThread : ( listener : ( message : MainToWorkerMessage ) => void ) => void ;
6571 }
6672 | {
6773 /**
68- * This function is expected to be set in the main thread and called
69- * when the main thread sends a wake event to the Web Worker thread.
70- * The `tid` is the thread ID of the worker thread to be woken up.
71- * The `data` is the data to be sent to the worker thread.
72- * The wake event is expected to be listened by `listenWakeEventFromMainThread`.
74+ * This function is expected to be set in the main thread.
75+ * The message submitted by this function is expected to be listened by `listenMessageFromMainThread`.
76+ * @param tid The thread ID of the worker thread.
77+ * @param message The message to be sent to the worker thread.
7378 */
74- wakeUpWorkerThread : ( tid : number , data : unknown ) => void ;
79+ postMessageToWorkerThread : ( tid : number , message : MainToWorkerMessage ) => void ;
7580 /**
7681 * This function is expected to be set in the main thread and shuold listen
77- * to the main job sent by `wakeUpMainThread` from the worker thread.
82+ * to messsages sent by `postMessageToMainThread` from the worker thread.
83+ * @param tid The thread ID of the worker thread.
84+ * @param listener The listener function to be called when a message is received from the worker thread.
7885 */
79- listenMainJobFromWorkerThread : (
86+ listenMessageFromWorkerThread : (
8087 tid : number ,
81- listener : ( unownedJob : number ) => void
88+ listener : ( message : WorkerToMainMessage ) => void
8289 ) => void ;
8390
8491 /**
8592 * This function is expected to be set in the main thread and called
8693 * when the worker thread is terminated.
94+ * @param tid The thread ID of the worker thread.
8795 */
8896 terminateWorkerThread ?: ( tid : number ) => void ;
8997 } ;
@@ -578,60 +586,49 @@ export class SwiftRuntime {
578586 swjs_unsafe_event_loop_yield : ( ) => {
579587 throw new UnsafeEventLoopYield ( ) ;
580588 } ,
581- // This function is called by WebWorkerTaskExecutor on Web Worker thread.
582589 swjs_send_job_to_main_thread : ( unowned_job ) => {
583- const threadChannel = this . options . threadChannel ;
584- if ( threadChannel && "wakeUpMainThread" in threadChannel ) {
585- threadChannel . wakeUpMainThread ( unowned_job ) ;
586- } else {
587- throw new Error (
588- "wakeUpMainThread is not set in options given to SwiftRuntime. Please set it to send jobs to the main thread."
589- ) ;
590- }
590+ this . postMessageToMainThread ( { type : "job" , data : unowned_job } ) ;
591591 } ,
592- swjs_listen_wake_event_from_main_thread : ( ) => {
593- // After the thread is started,
594- const swjs_wake_worker_thread =
595- this . exports . swjs_wake_worker_thread ;
592+ swjs_listen_message_from_main_thread : ( ) => {
596593 const threadChannel = this . options . threadChannel ;
597- if (
598- threadChannel &&
599- "listenWakeEventFromMainThread" in threadChannel
600- ) {
601- threadChannel . listenWakeEventFromMainThread ( ( ) => {
602- swjs_wake_worker_thread ( ) ;
603- } ) ;
604- } else {
594+ if ( ! ( threadChannel && "listenMessageFromMainThread" in threadChannel ) ) {
605595 throw new Error (
606- "listenWakeEventFromMainThread is not set in options given to SwiftRuntime. Please set it to listen to wake events from the main thread."
596+ "listenMessageFromMainThread is not set in options given to SwiftRuntime. Please set it to listen to wake events from the main thread."
607597 ) ;
608598 }
599+ threadChannel . listenMessageFromMainThread ( ( message ) => {
600+ switch ( message . type ) {
601+ case "wake" :
602+ this . exports . swjs_wake_worker_thread ( ) ;
603+ break ;
604+ default :
605+ const unknownMessage : never = message . type ;
606+ throw new Error ( `Unknown message type: ${ unknownMessage } ` ) ;
607+ }
608+ } ) ;
609609 } ,
610610 swjs_wake_up_worker_thread : ( tid ) => {
611- const threadChannel = this . options . threadChannel ;
612- if ( threadChannel && "wakeUpWorkerThread" in threadChannel ) {
613- // Currently, the data is not used, but it can be used in the future.
614- threadChannel . wakeUpWorkerThread ( tid , { } ) ;
615- } else {
616- throw new Error (
617- "wakeUpWorkerThread is not set in options given to SwiftRuntime. Please set it to wake up worker threads."
618- ) ;
619- }
611+ this . postMessageToWorkerThread ( tid , { type : "wake" } ) ;
620612 } ,
621- swjs_listen_main_job_from_worker_thread : ( tid ) => {
613+ swjs_listen_message_from_worker_thread : ( tid ) => {
622614 const threadChannel = this . options . threadChannel ;
623- if (
624- threadChannel &&
625- "listenMainJobFromWorkerThread" in threadChannel
626- ) {
627- threadChannel . listenMainJobFromWorkerThread (
628- tid , this . exports . swjs_enqueue_main_job_from_worker ,
629- ) ;
630- } else {
615+ if ( ! ( threadChannel && "listenMessageFromWorkerThread" in threadChannel ) ) {
631616 throw new Error (
632- "listenMainJobFromWorkerThread is not set in options given to SwiftRuntime. Please set it to listen to jobs from worker threads."
617+ "listenMessageFromWorkerThread is not set in options given to SwiftRuntime. Please set it to listen to jobs from worker threads."
633618 ) ;
634619 }
620+ threadChannel . listenMessageFromWorkerThread (
621+ tid , ( message ) => {
622+ switch ( message . type ) {
623+ case "job" :
624+ this . exports . swjs_enqueue_main_job_from_worker ( message . data ) ;
625+ break ;
626+ default :
627+ const unknownMessage : never = message . type ;
628+ throw new Error ( `Unknown message type: ${ unknownMessage } ` ) ;
629+ }
630+ } ,
631+ ) ;
635632 } ,
636633 swjs_terminate_worker_thread : ( tid ) => {
637634 const threadChannel = this . options . threadChannel ;
@@ -645,6 +642,26 @@ export class SwiftRuntime {
645642 } ,
646643 } ;
647644 }
645+
646+ private postMessageToMainThread ( message : WorkerToMainMessage ) {
647+ const threadChannel = this . options . threadChannel ;
648+ if ( ! ( threadChannel && "postMessageToMainThread" in threadChannel ) ) {
649+ throw new Error (
650+ "postMessageToMainThread is not set in options given to SwiftRuntime. Please set it to send messages to the main thread."
651+ ) ;
652+ }
653+ threadChannel . postMessageToMainThread ( message ) ;
654+ }
655+
656+ private postMessageToWorkerThread ( tid : number , message : MainToWorkerMessage ) {
657+ const threadChannel = this . options . threadChannel ;
658+ if ( ! ( threadChannel && "postMessageToWorkerThread" in threadChannel ) ) {
659+ throw new Error (
660+ "postMessageToWorkerThread is not set in options given to SwiftRuntime. Please set it to send messages to worker threads."
661+ ) ;
662+ }
663+ threadChannel . postMessageToWorkerThread ( tid , message ) ;
664+ }
648665}
649666
650667/// This error is thrown when yielding event loop control from `swift_task_asyncMainDrainQueue`
0 commit comments