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.
|
||||
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).
|
||||
ctx := ctx sender.
|
||||
|
@ -43,8 +43,15 @@ class(#pointer,#final,#limited) Process(Object)
|
||||
// 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 (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 _terminate
|
||||
}
|
||||
@ -422,4 +429,7 @@ class(#final,#limited) ProcessScheduler(Object)
|
||||
|
||||
method activeProcess { ^self.active }
|
||||
method resume: aProcess { ^aProcess resume }
|
||||
|
||||
method(#primitive,#lenient) _processById: id.
|
||||
method(#primitive) processById: id.
|
||||
}
|
||||
|
@ -146,12 +146,33 @@ class System(Apex)
|
||||
nil.
|
||||
]
|
||||
ensure: [
|
||||
| pid proc |
|
||||
os_intr_sem unsignal.
|
||||
|
||||
System logNl: '>>>>Requesting to terminate the caller process ' & (caller id) asString.
|
||||
// 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.
|
||||
//(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.
|
||||
].
|
||||
|
@ -467,7 +467,7 @@ class X11.Composite(X11.Widget)
|
||||
| link |
|
||||
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.
|
||||
@ -573,6 +573,11 @@ extend X11
|
||||
self.display_base dump.
|
||||
}
|
||||
|
||||
method isConnected
|
||||
{
|
||||
^self.display_base notNil
|
||||
}
|
||||
|
||||
method dispose
|
||||
{
|
||||
if (self.shell_container notNil)
|
||||
@ -625,7 +630,6 @@ extend X11
|
||||
self.LLEventType.CLIENT_MESSAGE -> #__handle_client_message:on:,
|
||||
self.LLEventType.SHELL_CLOSE -> #__handle_shell_close:on:
|
||||
}.
|
||||
|
||||
}
|
||||
|
||||
method addShell: shell
|
||||
@ -653,39 +657,43 @@ extend X11
|
||||
self.event_loop_sem := Semaphore new.
|
||||
self.event_loop_sem signalOnInput: (self _get_fd).
|
||||
self.event_loop_proc := [
|
||||
| llevtbuf llevent ongoing |
|
||||
|
||||
llevtbuf := X11.LLEvent new.
|
||||
ongoing := true.
|
||||
while (self.shell_container childrenCount > 0)
|
||||
{
|
||||
'Waiting for X11 event...' dump.
|
||||
self.event_loop_sem wait.
|
||||
if (ongoing not) { break }.
|
||||
[
|
||||
| llevtbuf llevent ongoing |
|
||||
|
||||
while ((llevent := self _get_llevent(llevtbuf)) notNil)
|
||||
llevtbuf := X11.LLEvent new.
|
||||
ongoing := true.
|
||||
while (self.shell_container childrenCount > 0)
|
||||
{
|
||||
if (llevent isError)
|
||||
'Waiting for X11 event...' dump.
|
||||
self.event_loop_sem wait.
|
||||
if (ongoing not) { break }.
|
||||
|
||||
while ((llevent := self _get_llevent(llevtbuf)) notNil)
|
||||
{
|
||||
//System logNl: ('Error while getting a event from server ' & self.cid asString).
|
||||
ongoing := false.
|
||||
break.
|
||||
}
|
||||
else
|
||||
{
|
||||
self __dispatch_llevent: llevent.
|
||||
if (llevent isError)
|
||||
{
|
||||
//System logNl: ('Error while getting a event from server ' & self.cid asString).
|
||||
ongoing := false.
|
||||
break.
|
||||
}
|
||||
else
|
||||
{
|
||||
self __dispatch_llevent: llevent.
|
||||
}.
|
||||
}.
|
||||
}.
|
||||
}.
|
||||
] ensure: [
|
||||
|
||||
'CLOSING X11 EVENT LOOP' dump.
|
||||
|
||||
self.event_loop_sem unsignal.
|
||||
// TODO: LOOK HERE FOR RACE CONDITION
|
||||
self.event_loop_sem := nil.
|
||||
self.event_loop_proc := nil.
|
||||
|
||||
self dispose.
|
||||
self.event_loop_sem unsignal.
|
||||
// TODO: LOOK HERE FOR RACE CONDITION with exitEventLoop.
|
||||
self.event_loop_sem := nil.
|
||||
self.event_loop_proc := nil.
|
||||
|
||||
[ self dispose ] on: Exception do: [:ex | ("WARNING: dispose failure...." & ex messageText) dump ].
|
||||
]
|
||||
] fork.
|
||||
}
|
||||
}
|
||||
@ -826,10 +834,22 @@ class MyObject(Object)
|
||||
Fx new.
|
||||
comp1 := 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
|
||||
{
|
||||
// this method returns immediately while having forked two processes with X11 event loops.
|
||||
^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->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
|
||||
{
|
||||
@ -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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@ -4114,6 +4181,8 @@ static pf_t pftab[] =
|
||||
{ "MethodContext_findExceptionHandler:", { pf_context_find_exception_handler, 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_sp", { pf_process_sp, 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
|
||||
x11 = (oop_x11_t)MOO_STACK_GETRCV(moo, nargs);
|
||||
//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);
|
||||
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.width = event->xexpose.width;
|
||||
rect.height = event->xexpose.height;
|
||||
if (XCheckWindowEvent (disp, event->xexpose.window, ExposureMask, event))
|
||||
if (XCheckWindowEvent(disp, event->xexpose.window, ExposureMask, event))
|
||||
{
|
||||
Region reg;
|
||||
|
||||
/* merge all expose events in the event queue */
|
||||
reg = XCreateRegion ();
|
||||
reg = XCreateRegion();
|
||||
XUnionRectWithRegion (&rect, reg, reg);
|
||||
|
||||
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;
|
||||
XUnionRectWithRegion (&rect, reg, reg);
|
||||
}
|
||||
while (XCheckWindowEvent (disp, event->xexpose.window, ExposureMask, event));
|
||||
while (XCheckWindowEvent(disp, event->xexpose.window, ExposureMask, event));
|
||||
|
||||
XClipBox (reg, &rect);
|
||||
XDestroyRegion (reg);
|
||||
|
Loading…
Reference in New Issue
Block a user