added ProcessScheduler>>processById:

attempting to correct signal handling behavior
This commit is contained in:
hyunghwan.chung 2019-08-18 17:46:40 +00:00
parent 071ebb7788
commit 42df4239a6
6 changed files with 156 additions and 32 deletions

View File

@ -183,7 +183,11 @@ extend Context
ctx basicAt: pending_pos put: false. ctx basicAt: pending_pos put: false.
eb value. eb value.
}*/ }*/
if (ctx basicAt: pending_pos test: true put: false) { eb value }. if (ctx basicAt: pending_pos test: true put: false)
{
// TODO: what is the best way to handle an exception raised in an ensure block?
[ eb value ] on: Exception do: [:ex | System logNl: "WARNING: unhandled exception in ensure block - " & ex messageText ].
}.
}. }.
stop := (ctx == context). stop := (ctx == context).
ctx := ctx sender. ctx := ctx sender.

View File

@ -43,8 +43,15 @@ class(#pointer,#final,#limited) Process(Object)
// the process must not be scheduled. // the process must not be scheduled.
// ---------------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------------
// if the current active process(thisProcess) is not the process to terminate(self),
// suspend the target process so that no scheduling wakes the process until this
// termination is completed.
//if (Processor activeProcess ~~ self) { self suspend }. //if (Processor activeProcess ~~ self) { self suspend }.
if (thisProcess ~~ self) { self suspend }. if (thisProcess ~~ self) { self suspend }.
// TODO: what if there is another process that may resume this suspended process.
// should i mark it unresumable?
self.currentContext unwindTo: self.initialContext return: nil. self.currentContext unwindTo: self.initialContext return: nil.
^self _terminate ^self _terminate
} }
@ -422,4 +429,7 @@ class(#final,#limited) ProcessScheduler(Object)
method activeProcess { ^self.active } method activeProcess { ^self.active }
method resume: aProcess { ^aProcess resume } method resume: aProcess { ^aProcess resume }
method(#primitive,#lenient) _processById: id.
method(#primitive) processById: id.
} }

View File

@ -146,12 +146,33 @@ class System(Apex)
nil. nil.
] ]
ensure: [ ensure: [
| pid proc |
os_intr_sem unsignal. os_intr_sem unsignal.
System logNl: '>>>>Requesting to terminate the caller process ' & (caller id) asString. System logNl: '>>>>Requesting to terminate the caller process ' & (caller id) asString.
// the caller must request to terminate all its child processes.. // the caller must request to terminate all its child processes..
// TODO: to avoid this, this process must enumerate all proceses and terminate them. // TODO: to avoid this, this process must enumerate all proceses and terminate them except this and gcfin process
/* TODO: redo the following process termination loop.
need to write a proper process enumeration methods.
0 -> startup <--- this should also be stored in the 'caller' variable.
1 -> __gc_finalizer
2 -> __os_signal_handler
3 -> application main
the following loops starts from pid 3 up to 100. this is POC only. i need to write a proper enumeration methods and use them.
*/
pid := 3.
while (pid < 100)
{
//proc := Processor processById: pid.
proc := Processor _processById: pid.
if (proc notError) { System logNl: ("Requesting to terminate process of id - " & pid asString). proc terminate }.
pid := pid + 1.
}.
/* TODO: end redo */
caller terminate. caller terminate.
//(Processor _processById: 1) resume. <---- i shouldn't do ths. but, this system causes VM assertion failure. fix it....
System logNl: '>>>>End of OS signal handler process ' & (thisProcess id) asString. System logNl: '>>>>End of OS signal handler process ' & (thisProcess id) asString.
]. ].

View File

@ -467,7 +467,7 @@ class X11.Composite(X11.Widget)
| link | | link |
if (widget parent ~~ self) if (widget parent ~~ self)
{ {
selfns.Exception sinal: "Cannot remove an unknown widget" selfns.Exception signal: "Cannot remove an unknown widget"
}. }.
link := self.children findIdenticalLink: widget. link := self.children findIdenticalLink: widget.
@ -573,6 +573,11 @@ extend X11
self.display_base dump. self.display_base dump.
} }
method isConnected
{
^self.display_base notNil
}
method dispose method dispose
{ {
if (self.shell_container notNil) if (self.shell_container notNil)
@ -625,7 +630,6 @@ extend X11
self.LLEventType.CLIENT_MESSAGE -> #__handle_client_message:on:, self.LLEventType.CLIENT_MESSAGE -> #__handle_client_message:on:,
self.LLEventType.SHELL_CLOSE -> #__handle_shell_close:on: self.LLEventType.SHELL_CLOSE -> #__handle_shell_close:on:
}. }.
} }
method addShell: shell method addShell: shell
@ -653,6 +657,8 @@ extend X11
self.event_loop_sem := Semaphore new. self.event_loop_sem := Semaphore new.
self.event_loop_sem signalOnInput: (self _get_fd). self.event_loop_sem signalOnInput: (self _get_fd).
self.event_loop_proc := [ self.event_loop_proc := [
[
| llevtbuf llevent ongoing | | llevtbuf llevent ongoing |
llevtbuf := X11.LLEvent new. llevtbuf := X11.LLEvent new.
@ -677,15 +683,17 @@ extend X11
}. }.
}. }.
}. }.
] ensure: [
'CLOSING X11 EVENT LOOP' dump. 'CLOSING X11 EVENT LOOP' dump.
self.event_loop_sem unsignal. self.event_loop_sem unsignal.
// TODO: LOOK HERE FOR RACE CONDITION // TODO: LOOK HERE FOR RACE CONDITION with exitEventLoop.
self.event_loop_sem := nil. self.event_loop_sem := nil.
self.event_loop_proc := nil. self.event_loop_proc := nil.
self dispose. [ self dispose ] on: Exception do: [:ex | ("WARNING: dispose failure...." & ex messageText) dump ].
]
] fork. ] fork.
} }
} }
@ -826,10 +834,22 @@ class MyObject(Object)
Fx new. Fx new.
comp1 := Fx new. comp1 := Fx new.
Fx new. Fx new.
while (self.disp1 isConnected or self.disp2 isConnected) { System sleepForSecs: 1 }.
} }
/*
method exitEventLoops
{
if (self.disp2 notNil) { self.disp2 exitEventLoop }.
if (self.disp1 notNil) { self.disp1 exitEventLoop }.
}
*/
method(#class) main method(#class) main
{ {
// this method returns immediately while having forked two processes with X11 event loops.
^self new main1 ^self new main1
} }
} }

View File

@ -615,6 +615,32 @@ static void terminate_process (moo_t* moo, moo_oop_process_t proc)
MOO_OOP_TO_SMOOI(moo->processor->suspended.count), MOO_OOP_TO_SMOOI(moo->processor->suspended.count),
moo->sem_io_wait_count moo->sem_io_wait_count
); );
if (MOO_OOP_TO_SMOOI(moo->processor->runnable.count) > 0)
{
moo_oop_process_t p;
MOO_LOG0 (moo, MOO_LOG_IC | MOO_LOG_DEBUG, "Runnable: ");
p = moo->processor->runnable.first;
while (p)
{
MOO_LOG1 (moo, MOO_LOG_IC | MOO_LOG_DEBUG, " %O", p->id);
if (p == moo->processor->runnable.last) break;
p = p->ps.next;
}
MOO_LOG0 (moo, MOO_LOG_IC | MOO_LOG_DEBUG, "\n");
}
if (MOO_OOP_TO_SMOOI(moo->processor->suspended.count) > 0)
{
moo_oop_process_t p;
MOO_LOG0 (moo, MOO_LOG_IC | MOO_LOG_DEBUG, "Suspended: ");
p = moo->processor->suspended.first;
while (p)
{
MOO_LOG1 (moo, MOO_LOG_IC | MOO_LOG_DEBUG, " %O", p->id);
if (p == moo->processor->suspended.last) break;
p = p->ps.next;
}
MOO_LOG0 (moo, MOO_LOG_IC | MOO_LOG_DEBUG, "\n");
}
} }
else else
{ {
@ -2613,6 +2639,47 @@ static moo_pfrc_t pf_process_suspend (moo_t* moo, moo_mod_t* mod, moo_ooi_t narg
return MOO_PF_SUCCESS; return MOO_PF_SUCCESS;
} }
static moo_pfrc_t pf_process_scheduler_process_by_id (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
{
moo_oop_t rcv, id;
moo_oop_process_t proc;
rcv = MOO_STACK_GETRCV(moo, nargs);
id = MOO_STACK_GETARG(moo, nargs, 0);
MOO_PF_CHECK_RCV (moo, rcv == (moo_oop_t)moo->processor);
if (MOO_OOP_IS_SMOOI(id))
{
proc = moo->processor->runnable.first;
while (proc)
{
if (proc->id == id)
{
MOO_STACK_SETRET (moo, nargs, (moo_oop_t)proc);
return MOO_PF_SUCCESS;
}
if (proc == moo->processor->runnable.last) break;
proc = proc->ps.next;
}
proc = moo->processor->suspended.first;
while (proc)
{
if (proc->id == id)
{
MOO_STACK_SETRET (moo, nargs, (moo_oop_t)proc);
return MOO_PF_SUCCESS;
}
if (proc == moo->processor->suspended.last) break;
proc = proc->ps.next;
}
}
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_ENOENT);
return MOO_PF_FAILURE;
}
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
static moo_pfrc_t pf_semaphore_signal (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) static moo_pfrc_t pf_semaphore_signal (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
{ {
@ -4114,6 +4181,8 @@ static pf_t pftab[] =
{ "MethodContext_findExceptionHandler:", { pf_context_find_exception_handler, 1, 1 } }, { "MethodContext_findExceptionHandler:", { pf_context_find_exception_handler, 1, 1 } },
{ "MethodContext_goto:", { pf_context_goto, 1, 1 } }, { "MethodContext_goto:", { pf_context_goto, 1, 1 } },
{ "ProcessScheduler_processById:", { pf_process_scheduler_process_by_id, 1, 1 } },
{ "Process_resume", { pf_process_resume, 0, 0 } }, { "Process_resume", { pf_process_resume, 0, 0 } },
{ "Process_sp", { pf_process_sp, 0, 0 } }, { "Process_sp", { pf_process_sp, 0, 0 } },
{ "Process_suspend", { pf_process_suspend, 0, 0 } }, { "Process_suspend", { pf_process_suspend, 0, 0 } },