@@ -110,38 +110,46 @@ export class Scheduler implements SchedulerInterface {
110110 this . __funloop . push ( t ) ;
111111 }
112112
113- /** Create a new thread `t` for the given function to be evaluated and schedule it. */
113+ /** Create a new thread `t` for the given function to be evaluated and schedule it.
114+ *
115+ * NOTE (20-10-2025; SS): A hypothesis about the Javascript event loop:
116+ *
117+ * It would be a more clean design to return the thread identifier of type `LVal`, as we
118+ * do right now, together with a `Promise<LVal>` of the final returned value. But, since
119+ * the Javascript event loop is a LIFO queue, i.e. a stack, this would bury resolving the
120+ * termination of each thread (especially the *main* thread) beneath everything else.
121+ */
114122 scheduleNewThread ( f : ( ) => any ,
115123 arg : any ,
116124 pc : Level ,
117125 block : Level ,
118- tType : ThreadType = ThreadType . Other )
126+ tType : ThreadType = ThreadType . Other ,
127+ cb : ( LVal ) => void = ( _ ) => { } )
119128 {
120129 // Create a new process ID at the given level.
121130 const pid = tType === ThreadType . System ? SYSTEM_PROCESS_STRING : uuidv4 ( ) ;
122- const pidObj = new ProcessID ( this . rt_uuid , pid , this . __node ) ;
123- const newPid = new LVal ( pidObj , pc ) ;
131+ const tid = new LVal ( new ProcessID ( this . rt_uuid , pid , this . __node ) , pc ) ;
132+
133+ const halt = ( ) => {
134+ this . __currentThread . raiseCurrentThreadPCToBlockingLev ( ) ;
135+ this . notifyMonitors ( ) ;
124136
125- // Epilogue for thread.
126- const halt = tType === ThreadType . Main ? ( ) => { this . haltMain ( ) }
127- : ( ) => { this . haltOther ( ) } ;
137+ const currT = this . __currentThread ;
138+ const retVal = new LVal ( currT . r0_val , lub ( currT . bl , currT . r0_lev ) , lub ( currT . bl , currT . r0_tlev ) ) ;
139+
140+ delete this . __alive [ this . __currentThread . tid . val . toString ( ) ] ;
141+
142+ cb ( retVal ) ;
143+ }
128144
129145 // New thread
130- const t = new Thread
131- ( newPid
132- , halt
133- , f
134- , arg
135- , pc
136- , block
137- , new SandboxStatus . NORMAL ( )
138- , this . rtObj
139- , this ) ;
140-
141-
142- this . __alive [ newPid . val . toString ( ) ] = t ;
146+ const sStatus = new SandboxStatus . NORMAL ( ) ;
147+ const t = new Thread ( tid , halt , f , arg , pc , block , sStatus , this . rtObj , this ) ;
148+
149+ this . __alive [ tid . val . toString ( ) ] = t ;
143150 this . scheduleThread ( t ) ;
144- return newPid ;
151+
152+ return tid as LVal ;
145153 }
146154
147155 /*************************************************************************************************\
@@ -210,32 +218,6 @@ export class Scheduler implements SchedulerInterface {
210218 }
211219 }
212220
213- /** Epilogue for `main` thread: notify monitors, print and persist the final value */
214- haltMain ( ) {
215- this . __currentThread . raiseCurrentThreadPCToBlockingLev ( )
216- let retVal = new LVal ( this . __currentThread . r0_val ,
217- lub ( this . __currentThread . bl , this . __currentThread . r0_lev ) ,
218- lub ( this . __currentThread . bl , this . __currentThread . r0_tlev ) )
219-
220- this . notifyMonitors ( ) ;
221-
222- delete this . __alive [ this . __currentThread . tid . val . toString ( ) ] ;
223- console . log ( ">>> Main thread finished with value:" , retVal . stringRep ( ) ) ;
224- const persist = argv [ TroupeCliArg . Persist ] ;
225- if ( persist ) {
226- this . rtObj . persist ( retVal , persist )
227- console . log ( "Saved the result value in file" , persist )
228- }
229- return null ;
230- }
231-
232- /** Epilogue for non-`main` threads: notify monitors */
233- haltOther ( ) {
234- this . notifyMonitors ( ) ;
235- // console.log (this.__currentThread.processDebuggingName, this.__currentThread.tid.val.toString(), "done")
236- delete this . __alive [ this . __currentThread . tid . val . toString ( ) ] ;
237- }
238-
239221 /** Kill thread `t` with the error message `s` sent to its monitors. */
240222 stopThreadWithErrorMessage ( t : Thread , errMsg : string ) {
241223 this . notifyMonitors ( TerminationStatus . ERR , errMsg ) ;
0 commit comments