trying to implement user-defined signal handling mechanism

This commit is contained in:
hyunghwan.chung 2019-09-15 15:41:24 +00:00
parent d2f5446ee5
commit a640650b67
5 changed files with 55 additions and 41 deletions

View File

@ -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.

View File

@ -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'.

View File

@ -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
{ {

View File

@ -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 }.
} }

View File

@ -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