diff options
author | Ori Bernstein <ori@eigenstate.org> | 2017-07-23 21:08:07 -0700 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2017-07-23 21:08:07 -0700 |
commit | feffe0d81fe8bc1d19f5f2305e09c08f70d4a620 (patch) | |
tree | bca96ba597d60b5d190df7fd3dc534596f289a80 | |
parent | 0de076266f9f82aed32303650b469cf287cb98f2 (diff) | |
download | mc-feffe0d81fe8bc1d19f5f2305e09c08f70d4a620.tar.gz |
Implement waitany() on 9front.
-rw-r--r-- | lib/std/wait+plan9.myr | 55 | ||||
-rwxr-xr-x | test/runtest.rc | 5 |
2 files changed, 41 insertions, 19 deletions
diff --git a/lib/std/wait+plan9.myr b/lib/std/wait+plan9.myr index 720b66b..44177db 100644 --- a/lib/std/wait+plan9.myr +++ b/lib/std/wait+plan9.myr @@ -15,6 +15,7 @@ use "syswrap" use "utf" use "sleq" use "fmt" +use "threadhooks" pkg std = type waitstatus = union @@ -25,53 +26,73 @@ pkg std = ;; const wait : (pid : pid -> waitstatus) + const waitany : (-> (pid, waitstatus)) ;; -var statusinit : bool = false var statusmap : htab(pid, waitstatus)# +const __init__ = { + statusmap = mkht(inthash, inteq) +} + +const waitany = { + var buf : byte[512] + var ret, it + + lock(envlck) + if htcount(statusmap) == 0 + unlock(envlck) + match sys.await(buf[:]) + | -1: -> (-1, `Waiterror) + | n: -> parsestatus(buf[:n]) + ;; + else + it = std.byhtkeyvals(statusmap) + __iternext__(&it, &ret) + unlock(envlck) + -> ret + ;; +} + const wait = {pid var buf : byte[512] var xpid, status - var n - if !statusinit - statusmap = mkht(inthash, inteq) - statusinit = true - ;; - + lock(envlck) match htget(statusmap, pid) + | `None: | `Some st: + unlock(envlck) htdel(statusmap, pid) -> st - | `None: /* nothing */ ;; + unlock(envlck) while true - n = sys.await(buf[:]) - if n < 0 - -> `Waiterror + match sys.await(buf[:]) + | -1: -> `Waiterror + | n: (xpid, status) = parsestatus(buf[:n]) ;; - - (status, xpid) = parsestatus(buf[:n]) if xpid == pid -> status else - htput(statusmap, pid, status) + lock(envlck) + htput(statusmap, xpid, status) + unlock(envlck) ;; ;; /* impossible */ -> `Waiterror } -const parsestatus = {status -> (waitstatus, pid) +const parsestatus = {status -> (pid, waitstatus) var st : waitstatus var spbuf : byte[:][5] var xpid, sp sp = bstrsplit(spbuf[:], status, " ") if sp.len == 0 - -> (`Wfailure, -1) + -> (-1, `Wfailure) ;; match intparse(sp[0]) @@ -90,7 +111,7 @@ const parsestatus = {status -> (waitstatus, pid) st = `Waiterror ;; - -> (st, xpid) + -> (xpid, st) } diff --git a/test/runtest.rc b/test/runtest.rc index cad4930..5e374fb 100755 --- a/test/runtest.rc +++ b/test/runtest.rc @@ -1,10 +1,11 @@ #!/bin/rc rfork e - +MYR_MC=../6/6.out +MYR_MUSE=../muse/6.out fn build { rm -f $1 $1^.6 $1^.use - ../mbld/mbld -b $1 -C../6/6.out -M../muse/6.out -I../lib/std -r../rt/_myrrt.6 $1^.myr + ../mbld/mbld -b $1 -I../lib/std -I../lib/sys -r../rt/_myrrt.6 $1^.myr } fn pass { |