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