// calogTask.h -- calog task library: launch and manage other calog script contexts. // // Registers inline natives that let a script of any engine spawn and manage other scripts: // taskSpawn(engine, code) -> handle run a code string on a named engine (fire-and-forget) // taskLoad(baseName) -> handle launch a script FILE (engine chosen by extension) // taskEval(handle, code) feed more code into a running task (runs on its thread) // taskClose(handle) stop a task (cooperative shutdown; see below) // taskSelf() -> id the calling script's own context id // taskCount() -> n number of tasks this library currently holds open // // Tasks are FIRE-AND-FORGET: a spawned context runs on its own thread and returns nothing to // the caller; results come back through host natives you register (calog's usual pattern). A // task is a persistent interpreter -- taskEval feeds it more code over time until taskClose. // // OWNERSHIP: a task is owned by the context that spawned/loaded it, and ONLY that owner may // taskEval or taskClose it (others get an error). This is enforced, not just documented: it // makes taskClose -- which blocks joining the task's thread -- unable to self-join (a task // cannot hold its own handle) or dead-lock a mutual close. A task whose owner is torn down // without closing it becomes an orphan, reclaimed when the runtime is destroyed. // // taskClose is COOPERATIVE (it is the "kill"): it queues a shutdown and waits for the task's // thread to exit. A task blocked calling back into the host (a host-thread native) has that // call interrupted; a task busy in a pure computation is not force-cancelled (that would // corrupt interpreter state), so a task spinning in an infinite loop cannot be force-killed. // (A task that, during its shutdown, synchronously invokes a callable owned by the closing // context can still dead-lock, since the closer is blocked in the join -- avoid that.) // Engines are addressed by name for // those compiled in (CALOG_WITH_LUA / _JS / _SQUIRREL / _MYBASIC / _BERRY / _S7 / _WREN); // taskLoad additionally needs the engines registered with calogRegisterEngine at setup. #ifndef CALOG_TASK_H #define CALOG_TASK_H #include "calog.h" // Register the task natives on a runtime. Idempotent across runtimes (they share a // process-wide task registry; each spawn goes into the caller's own runtime). Returns // calogOkE or an error. int32_t calogTaskRegister(CalogT *calog); // Free the process-wide task registry. Call it AFTER the runtime is torn down // (calogDestroy), which is what actually closes any still-open task contexts. void calogTaskShutdown(void); #endif