added ProcessScheduler>>processById:
attempting to correct signal handling behavior
This commit is contained in:
parent
071ebb7788
commit
42df4239a6
@ -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.
|
||||||
|
@ -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.
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
].
|
].
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 } },
|
||||||
|
@ -215,7 +215,7 @@ static moo_pfrc_t pf_get_llevent (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
|
|||||||
// TODO: CHECK if the receiver is an X11 object
|
// TODO: CHECK if the receiver is an X11 object
|
||||||
x11 = (oop_x11_t)MOO_STACK_GETRCV(moo, nargs);
|
x11 = (oop_x11_t)MOO_STACK_GETRCV(moo, nargs);
|
||||||
//MOO_ASSERT (moo, MOO_CLASSOF(moo,x11) == modctx->x11_class);
|
//MOO_ASSERT (moo, MOO_CLASSOF(moo,x11) == modctx->x11_class);
|
||||||
tr = moo_getobjtrailer (moo, (moo_oop_t)x11, MOO_NULL);
|
tr = moo_getobjtrailer(moo, (moo_oop_t)x11, MOO_NULL);
|
||||||
|
|
||||||
disp = MOO_OOP_TO_SMPTR(x11->display);
|
disp = MOO_OOP_TO_SMPTR(x11->display);
|
||||||
event = tr->event;
|
event = tr->event;
|
||||||
@ -254,12 +254,12 @@ static moo_pfrc_t pf_get_llevent (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
|
|||||||
rect.y = event->xexpose.y;
|
rect.y = event->xexpose.y;
|
||||||
rect.width = event->xexpose.width;
|
rect.width = event->xexpose.width;
|
||||||
rect.height = event->xexpose.height;
|
rect.height = event->xexpose.height;
|
||||||
if (XCheckWindowEvent (disp, event->xexpose.window, ExposureMask, event))
|
if (XCheckWindowEvent(disp, event->xexpose.window, ExposureMask, event))
|
||||||
{
|
{
|
||||||
Region reg;
|
Region reg;
|
||||||
|
|
||||||
/* merge all expose events in the event queue */
|
/* merge all expose events in the event queue */
|
||||||
reg = XCreateRegion ();
|
reg = XCreateRegion();
|
||||||
XUnionRectWithRegion (&rect, reg, reg);
|
XUnionRectWithRegion (&rect, reg, reg);
|
||||||
|
|
||||||
do
|
do
|
||||||
@ -270,7 +270,7 @@ static moo_pfrc_t pf_get_llevent (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
|
|||||||
rect.height = event->xexpose.height;
|
rect.height = event->xexpose.height;
|
||||||
XUnionRectWithRegion (&rect, reg, reg);
|
XUnionRectWithRegion (&rect, reg, reg);
|
||||||
}
|
}
|
||||||
while (XCheckWindowEvent (disp, event->xexpose.window, ExposureMask, event));
|
while (XCheckWindowEvent(disp, event->xexpose.window, ExposureMask, event));
|
||||||
|
|
||||||
XClipBox (reg, &rect);
|
XClipBox (reg, &rect);
|
||||||
XDestroyRegion (reg);
|
XDestroyRegion (reg);
|
||||||
|
Loading…
Reference in New Issue
Block a user