uCBQN/build/src/fork.bqn
2024-09-15 20:02:04 +03:00

111 lines
3.2 KiB
BQN
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

sz"u64" ssz"i64" nfdssz
libc_fork @ •FFI "i32""fork"
libc_pipe @ •FFI "i32""pipe"">&i32"
libc_read @ •FFI ssz"read""i32""&i8"sz
libc_write @ •FFI ssz"write""i32""*i8"sz
libc_close @ •FFI "i32""close"">i32"
libc_poll @ •FFI "i32""poll""&i16"nfds"i32"
Pipe { 𝕊: readfdwritefd
c, readfdwritefd Libc_pipe 00
! c=0
Write {Libc_write writefd, 𝕩, 𝕩}
Read {nb Libc_read readfd, 𝕩0, 𝕩 !n0 nb}
}
BiDiFork { 𝕊:
p1 Pipe@
p2 Pipe@
pid Libc_fork
! pid0
parent pid=0
CloseWR {! ¬´ Libc_close¨ {𝕨.writefd𝕩.readfd}´ parent 𝕩}
CloseWR p1p2
rw parent p1p2
Readreadfd r
Writewritefd w
Close CloseWRp2p1
}
FFn { 𝕊 fn:
f BiDiFork@
{f.parent? Fn f f.Close@ •Exit 0; f}
}
WriteAll {p𝕊x: {𝕩-p.Write 𝕩-x}•_while_× x}
_readAll {p E _𝕣 n: (¬=) {vp.Read n-𝕩 0<v? 𝕩v; <E"eof"}•_while_(=n) 0}
WriteSz {
𝕨 WriteAll (328•bit._cast 𝕩)𝕩
}
_readSz { 𝔽_𝕣 s:
r s <𝔽 _readAll 4
{
=r? n 832•bit._cast r s !_readAll n;
r
}
}
SerializeDeserialize •Import "serialize.bqn"
c_make 1
c_request 2
c_take 3
c_one 4
control FFn {{ 𝕊 control:
pidsprocs ˜
{𝕊:
tycmd Deserialize •Exit _readSz control
ty !
{ 𝕊program: # c_make
p FFn {{ 𝕊 p:
f •file.Parent program, •file.Name program •BQN •FChars program
{𝕊: p WriteSz Serialize F Deserialize •Exit _readSz p}•_while_ 1@
}}
control WriteAll 328•bit._cast p.pid
pids <p.pid
procs <p
}
{ 𝕊piddata: # c_request
p (pidspid)procs
p WriteSz data
}
{ 𝕊pid: # c_take
p (pidspid)procs
control WriteSz !_readSz p
}
{ 𝕊limitsel: # c_one
ms limit×1e3
"poll time limit too large" ! (ms) ms<231
p (pidssel)procs
fds {𝕩.readfd}¨ p
retres Libc_poll 10˘ 3216•bit._cast ˘fds fds ¯1 ms
! ret0
control WriteSz Serialize {¯1¨((¬𝕩01)/)𝕩} ¯1˘4res
}
cmd
}•_while_ 1@
}}
AskControl {control WriteSz Serialize 𝕨𝕩}
Spawn {
c_make AskControl 𝕩
pid 832•bit._cast control !_readAll 4
{
pidpid
Request {c_request AskControl pidSerialize 𝕩}
Take {𝕊: c_take AskControl pid Deserialize !_readSz control}
}
}
# 𝕩: list of spawn results to wait on
# 𝕨: if present, maximum time to wait; 0 to return immediately
# result: boolean mask of which have finished (if 𝕨 isn't given, guaranteed to have at least one `1`)
WaitForOne {
c_one AskControl 𝕨 {𝕩.pid}¨ 𝕩
Deserialize !_readSz control
}