@@ -10,21 +10,27 @@ import {
10
10
import * as JSValue from "./js-value.js" ;
11
11
import { Memory } from "./memory.js" ;
12
12
13
+ type MainToWorkerMessage = {
14
+ type : "wake" ;
15
+ } ;
16
+
17
+ type WorkerToMainMessage = {
18
+ type : "job" ;
19
+ data : number ;
20
+ } ;
21
+
13
22
/**
14
23
* A thread channel is a set of functions that are used to communicate between
15
24
* 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.
17
26
*
18
27
* @example
19
28
* ```javascript
20
29
* // worker.js
21
30
* const runtime = new SwiftRuntime({
22
31
* 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) => {
28
34
* self.onmessage = (event) => {
29
35
* listener(event.data);
30
36
* };
@@ -36,10 +42,10 @@ import { Memory } from "./memory.js";
36
42
* const worker = new Worker("worker.js");
37
43
* const runtime = new SwiftRuntime({
38
44
* threadChannel: {
39
- * wakeUpWorkerThread : (tid, data) => {
45
+ * postMessageToWorkerThread : (tid, data) => {
40
46
* worker.postMessage(data);
41
47
* },
42
- * listenMainJobFromWorkerThread : (tid, listener) => {
48
+ * listenMessageFromWorkerThread : (tid, listener) => {
43
49
* worker.onmessage = (event) => {
44
50
listener(event.data);
45
51
* };
@@ -50,40 +56,42 @@ import { Memory } from "./memory.js";
50
56
*/
51
57
export type SwiftRuntimeThreadChannel =
52
58
| {
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 ;
59
65
/**
60
66
* 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.
63
69
*/
64
- listenWakeEventFromMainThread : ( listener : ( data : unknown ) => void ) => void ;
70
+ listenMessageFromMainThread : ( listener : ( message : MainToWorkerMessage ) => void ) => void ;
65
71
}
66
72
| {
67
73
/**
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.
73
78
*/
74
- wakeUpWorkerThread : ( tid : number , data : unknown ) => void ;
79
+ postMessageToWorkerThread : ( tid : number , message : MainToWorkerMessage ) => void ;
75
80
/**
76
81
* 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.
78
85
*/
79
- listenMainJobFromWorkerThread : (
86
+ listenMessageFromWorkerThread : (
80
87
tid : number ,
81
- listener : ( unownedJob : number ) => void
88
+ listener : ( message : WorkerToMainMessage ) => void
82
89
) => void ;
83
90
84
91
/**
85
92
* This function is expected to be set in the main thread and called
86
93
* when the worker thread is terminated.
94
+ * @param tid The thread ID of the worker thread.
87
95
*/
88
96
terminateWorkerThread ?: ( tid : number ) => void ;
89
97
} ;
@@ -578,60 +586,49 @@ export class SwiftRuntime {
578
586
swjs_unsafe_event_loop_yield : ( ) => {
579
587
throw new UnsafeEventLoopYield ( ) ;
580
588
} ,
581
- // This function is called by WebWorkerTaskExecutor on Web Worker thread.
582
589
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 } ) ;
591
591
} ,
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 : ( ) => {
596
593
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 ) ) {
605
595
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."
607
597
) ;
608
598
}
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
+ } ) ;
609
609
} ,
610
610
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" } ) ;
620
612
} ,
621
- swjs_listen_main_job_from_worker_thread : ( tid ) => {
613
+ swjs_listen_message_from_worker_thread : ( tid ) => {
622
614
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 ) ) {
631
616
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."
633
618
) ;
634
619
}
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
+ ) ;
635
632
} ,
636
633
swjs_terminate_worker_thread : ( tid ) => {
637
634
const threadChannel = this . options . threadChannel ;
@@ -645,6 +642,26 @@ export class SwiftRuntime {
645
642
} ,
646
643
} ;
647
644
}
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
+ }
648
665
}
649
666
650
667
/// This error is thrown when yielding event loop control from `swift_task_asyncMainDrainQueue`
0 commit comments