vendor/agent/ is a package like any other - agent.flan declares three calls, flan_agent.c implements them, link asks for -lpthread. start listens on a unix socket, poll installs whatever arrived and says how many, wait does the same after waiting for something. The split between poll and the listener is the whole design. dlopen relocates a module and takes the loader lock, which is milliseconds and unbounded, so it happens on the listener thread. flan_reload_install is one store per function and must not land while a redefined function is on the stack, so it happens on the game thread at the top of the frame, when the program asks. A ring and two atomics connect them; the game thread never blocks on the loader. wait exists for tests. A test that races the frame rate fails on a loaded machine, so test/programs/agent.flan waits for the reload rather than sleeping past it. It also sends a junk path first: the daemon is a separate process and can send anything, and a bad path must be refused rather than take down the program it was sent to. Two things came out of running it. The reply goes out before the module is queued, because the other way round the game thread can install and the program can exit between the two, and the answer reaches the sender as a connection reset instead of as ok. And ok means queued, not installed - the sender does not get to know when the swap happened, since only the program knows when it is between frames. sand.flan now polls at the top of its loop, which is what this step was for. Under Xvfb, one line on the socket and 455 consecutive frames drew from a game-draw that did not exist when the process started. Building without --dev still works: there are no cells, so a module is refused on the listener thread and the loop never notices. flan reload builds one module the way the daemon will. --new names what the host was not built with, which is the one thing the command cannot work out for itself and exactly what the session will track.
18 lines
843 B
Plaintext
18 lines
843 B
Plaintext
(tests
|
|
(names test_flan test_acceptance test_reload test_agent)
|
|
(libraries flan unix)
|
|
; The acceptance programs are part of the test corpus: if the reader, the
|
|
; parser or the checker regresses on them we want to know here, not at the CLI.
|
|
(deps
|
|
(file %{workspace_root}/calc-me.flan)
|
|
(file %{workspace_root}/sand.flan)
|
|
; The sim package and the raylib bindings, because the headless sand case and
|
|
; the FFI case import them and an import reads the directory at build time.
|
|
(glob_files %{workspace_root}/sand-sim/*)
|
|
(glob_files %{workspace_root}/vendor/raylib/*)
|
|
; The dev agent package: its Flan declarations and the C that implements them.
|
|
(glob_files %{workspace_root}/vendor/agent/*)
|
|
(glob_files programs/*.flan)
|
|
; The reload primitive's host: a C main that dlopens what Build.shared made.
|
|
(file reload_host.c)))
|