trying to implement user-defined signal handling mechanism
This commit is contained in:
parent
d2f5446ee5
commit
a640650b67
@ -321,7 +321,7 @@ class(#pointer) CompiledMethod(Object)
|
||||
preamble_data_2,
|
||||
ntmprs,
|
||||
nargs,
|
||||
//code, <-- only if moo is built with MOO_USE_METHOD_TRAILER disable.
|
||||
//code, <-- only if moo is built with MOO_USE_METHOD_TRAILER disabled.
|
||||
dbi_file_offset,
|
||||
dbi_method_offset.
|
||||
|
||||
|
@ -2,10 +2,10 @@
|
||||
#include 'Context.moo'.
|
||||
#include 'Except.moo'.
|
||||
#include 'Class.moo'.
|
||||
#include 'System.moo'.
|
||||
#include 'Boolean.moo'.
|
||||
#include 'Magnitu.moo'.
|
||||
#include 'Collect.moo'.
|
||||
#include 'System.moo'.
|
||||
#include 'Process.moo'.
|
||||
#include 'Stream.moo'.
|
||||
|
||||
|
@ -13,7 +13,7 @@ class System(Apex)
|
||||
var(#class) asyncsg.
|
||||
var(#class) gcfin_sem.
|
||||
var(#class) gcfin_should_exit := false.
|
||||
var(#class) shr.
|
||||
var(#class) shr. // signal handler registry
|
||||
|
||||
pooldic Log
|
||||
{
|
||||
@ -31,12 +31,8 @@ class System(Apex)
|
||||
|
||||
method(#class) _initialize
|
||||
{
|
||||
self.shr := Dictionary new.
|
||||
}
|
||||
|
||||
method(#class) _cleanup
|
||||
{
|
||||
self.shr := nil.
|
||||
self.shr := Set new.
|
||||
self.asyncsg := SemaphoreGroup new.
|
||||
}
|
||||
|
||||
method(#class) addAsyncSemaphore: sem
|
||||
@ -54,11 +50,21 @@ class System(Apex)
|
||||
^self.asyncsg wait.
|
||||
}
|
||||
|
||||
method(#class) installSignalHandler: block
|
||||
{
|
||||
self.shr add: block.
|
||||
}
|
||||
|
||||
method(#class) uninstallSignalHandler: block
|
||||
{
|
||||
self.shr remove: block.
|
||||
}
|
||||
|
||||
method(#class) startup(class_name, method_name)
|
||||
{
|
||||
| class ret gcfin_proc ossig_proc |
|
||||
|
||||
self.asyncsg := SemaphoreGroup new.
|
||||
System gc.
|
||||
|
||||
class := self at: class_name. // System at: class_name.
|
||||
if (class isError)
|
||||
@ -150,7 +156,7 @@ class System(Apex)
|
||||
[
|
||||
while (true)
|
||||
{
|
||||
while ((tmp := self _getSig) notError)
|
||||
until ((tmp := self _getSig) isError)
|
||||
{
|
||||
// TODO: Do i have to protected this in an exception handler???
|
||||
//TODO: Execute Handler for tmp.
|
||||
@ -160,18 +166,14 @@ class System(Apex)
|
||||
// user-defined signal handler is not allowed for 16rFF
|
||||
if (tmp == 16rFF) { goto done }.
|
||||
|
||||
/*
|
||||
sh := self.sighandler at: tmp.
|
||||
if (sh isNil)
|
||||
{*/
|
||||
// the default action for sigint(2) is to terminate all processes.
|
||||
if (tmp == 2) { goto done }.
|
||||
/*}
|
||||
ifnot (self.shr isEmpty)
|
||||
{
|
||||
self.shr do: [ :handler | handler value ]
|
||||
}
|
||||
else
|
||||
{
|
||||
// invoke a user-defined signal handler if available.
|
||||
sh value: tmp.
|
||||
}*/
|
||||
if (tmp == 2) { goto done }.
|
||||
}.
|
||||
}.
|
||||
os_intr_sem wait.
|
||||
}.
|
||||
@ -218,7 +220,6 @@ class System(Apex)
|
||||
self.gcfin_sem signal. // wake the gcfin process.
|
||||
|
||||
self _halting. // inform VM that it should get ready for halting.
|
||||
self _cleanup.
|
||||
].
|
||||
}
|
||||
|
||||
@ -237,14 +238,6 @@ class System(Apex)
|
||||
method(#class,#primitive) return: object to: context.
|
||||
|
||||
// =======================================================================================
|
||||
method(#class) registerSignalHandler: block
|
||||
{
|
||||
self.shr add: block.
|
||||
}
|
||||
|
||||
method(#class) removeSignalHandler: block
|
||||
{
|
||||
}
|
||||
|
||||
method(#class) sleepForSecs: secs
|
||||
{
|
||||
|
@ -37,10 +37,11 @@ class X11(Object) [X11able,selfns.X11able3] from "x11"
|
||||
// =====================================================================
|
||||
|
||||
var shell_container := nil.
|
||||
var window_registrar. // all windows registered
|
||||
var window_registry. // all windows registered
|
||||
|
||||
var event_loop_sem, event_loop_proc.
|
||||
var llevent_blocks.
|
||||
var event_loop_exit_req := false.
|
||||
|
||||
|
||||
method(#dual) abc { ^nil }
|
||||
@ -119,7 +120,7 @@ TODO: TODO: compiler enhancement
|
||||
{
|
||||
| w |
|
||||
w := self _create_window(parent_window_handle, x, y, width, height, fgcolor, bgcolor).
|
||||
if (w notError) { self.window_registrar at: w put: owner }.
|
||||
if (w notError) { self.window_registry at: w put: owner }.
|
||||
^w
|
||||
}
|
||||
|
||||
@ -128,7 +129,7 @@ TODO: TODO: compiler enhancement
|
||||
| w |
|
||||
//#('DESTROY ' & window_handle asString) dump.
|
||||
w := self _destroy_window(window_handle).
|
||||
if (w notError) { self.window_registrar removeKey: window_handle }
|
||||
if (w notError) { self.window_registry removeKey: window_handle }
|
||||
}
|
||||
}
|
||||
|
||||
@ -598,7 +599,7 @@ extend X11
|
||||
super initialize.
|
||||
|
||||
self.shell_container := self.Composite new.
|
||||
self.window_registrar := System.Dictionary new: 100.
|
||||
self.window_registry := System.Dictionary new: 100.
|
||||
|
||||
/*
|
||||
|
||||
@ -654,6 +655,7 @@ extend X11
|
||||
{
|
||||
if (self.event_loop_sem isNil)
|
||||
{
|
||||
|
||||
self.event_loop_sem := Semaphore new.
|
||||
self.event_loop_sem signalOnInput: (self _get_fd).
|
||||
self.event_loop_proc := [
|
||||
@ -661,19 +663,23 @@ extend X11
|
||||
[
|
||||
| llevtbuf llevent ongoing |
|
||||
|
||||
self.event_loop_exit_req := false.
|
||||
llevtbuf := X11.LLEvent new.
|
||||
ongoing := true.
|
||||
while (self.shell_container childrenCount > 0)
|
||||
{
|
||||
'Waiting for X11 event...' dump.
|
||||
if (self.event_loop_exit_req) { break }.
|
||||
self.event_loop_sem wait.
|
||||
if (ongoing not) { break }.
|
||||
if (self.event_loop_exit_req) { break }.
|
||||
ifnot (ongoing) { break }.
|
||||
|
||||
while ((llevent := self _get_llevent(llevtbuf)) notNil)
|
||||
{
|
||||
if (llevent isError)
|
||||
{
|
||||
//System logNl: ('Error while getting a event from server ' & self.cid asString).
|
||||
self.event_loop_exit_req := true.
|
||||
ongoing := false.
|
||||
break.
|
||||
}
|
||||
@ -715,11 +721,17 @@ extend X11
|
||||
self.event_loop_sem signal.
|
||||
}
|
||||
|
||||
method requestToExit
|
||||
{
|
||||
self.event_loop_exit_req := true.
|
||||
self.event_loop_sem signal.
|
||||
}
|
||||
|
||||
method __dispatch_llevent: llevent
|
||||
{
|
||||
| widget mthname |
|
||||
|
||||
widget := self.window_registrar at: llevent window ifAbsent: [
|
||||
widget := self.window_registry at: llevent window ifAbsent: [
|
||||
System logNl: 'Event on unknown widget - ' & (llevent window asString).
|
||||
^nil
|
||||
].
|
||||
@ -793,6 +805,15 @@ class Fx(Object)
|
||||
class MyObject(Object)
|
||||
{
|
||||
var disp1, disp2, shell1, shell2, shell3.
|
||||
var on_sig.
|
||||
|
||||
method initialize
|
||||
{
|
||||
self.on_sig := [:sig |
|
||||
self.disp1 requestToExit.
|
||||
self.disp2 requestToExit.
|
||||
].
|
||||
}
|
||||
|
||||
method main1
|
||||
{
|
||||
@ -828,6 +849,8 @@ class MyObject(Object)
|
||||
self.shell2 realize.
|
||||
self.shell3 realize.
|
||||
|
||||
System installSignalHandler: self.on_sig.
|
||||
|
||||
self.disp1 enterEventLoop. // this is not a blocking call. it spawns another process.
|
||||
self.disp2 enterEventLoop.
|
||||
|
||||
@ -836,7 +859,6 @@ class MyObject(Object)
|
||||
comp1 := Fx new.
|
||||
Fx new.
|
||||
|
||||
|
||||
while (self.disp1 isConnected or self.disp2 isConnected) { System sleepForSecs: 1 }.
|
||||
}
|
||||
|
||||
|
@ -405,7 +405,7 @@ static kernel_class_info_t kernel_classes[] =
|
||||
{ 6,
|
||||
{ 'S','y','s','t','e','m' },
|
||||
0,
|
||||
3, /* asyncsg, gcfin_sem, gcfin_should_exit*/
|
||||
4, /* asyncsg, gcfin_sem, gcfin_should_exit, shr */
|
||||
0,
|
||||
0,
|
||||
MOO_OBJ_TYPE_OOP,
|
||||
@ -835,9 +835,8 @@ static moo_uint8_t* scan_heap_space (moo_t* moo, moo_uint8_t* ptr, moo_uint8_t**
|
||||
{
|
||||
moo_oow_t size;
|
||||
|
||||
/* TODO: is it better to use a flag bit in the header to
|
||||
* determine that it is an instance of process?
|
||||
* for example, if (MOO_OBJ_GET_FLAGS_PROC(oop))... */
|
||||
/* is it really better to use a flag bit in the header to
|
||||
* determine that it is an instance of process? */
|
||||
if (MOO_UNLIKELY(MOO_OBJ_GET_FLAGS_PROC(oop)))
|
||||
{
|
||||
/* the stack in a process object doesn't need to be
|
||||
|
Loading…
Reference in New Issue
Block a user