summaryrefslogtreecommitdiff
path: root/docs/guide.md
diff options
context:
space:
mode:
authorBerke Güzel <wenekar1@gmail.com>2026-10-13 16:55:45 +0300
committerBerke Güzel <wenekar1@gmail.com>2026-10-13 16:55:45 +0300
commitefca84e8b5204c4d5ce28113474df0bf0b67dbf3 (patch)
tree8ab6ed74f1e29b3a9dd3f1b2cb031c81891a5902 /docs/guide.md
parent62717de20d2a0c8d3596a9223e56e734971e3ec5 (diff)
Wake and post to loops from any thread, and watch signals
wsap_term runs its own eventfds to wake the loop from its pty worker and accessibility threads, and its own signalfd or self-pipe per platform. yasl_loop_kick() is now documented as safe from any thread and from a signal handler. yasl_loop_post() queues a function to run on the owning thread during a later step. yasl_loop_watch_signals() installs a process-wide SA_RESTART handler per signal that records the signal and kicks the loop, so callbacks run on the loop thread on every platform without touching thread masks. Cocoa dispatch waited only for AppKit events, so kicks, posts, and fd watches could not end an indefinite wait, and yasl_post_event() did not wake yasl_run(). While waiting, Cocoa now mirrors the loop's descriptors in a kqueue whose run loop source posts a wake event. If kqueue rejects a descriptor, the wait is bounded to 10 ms. The Cocoa change is not built or run here; it needs a macOS check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'docs/guide.md')
-rw-r--r--docs/guide.md27
1 files changed, 23 insertions, 4 deletions
diff --git a/docs/guide.md b/docs/guide.md
index ab30c3d..888e4ab 100644
--- a/docs/guide.md
+++ b/docs/guide.md
@@ -334,10 +334,29 @@ The loop never closes application file descriptors: delete the watch before
closing its descriptor. Ready callbacks may add or remove watches. Do not call
`yasl_loop_step()` or `yasl_loop_run()` recursively.
-Cocoa dispatch waits for native events and checks the loop nonblockingly
-afterward. An application FD alone does not currently wake an indefinite Cocoa
-dispatch; use a bounded timeout when integrating such sources. `loop_kick()`
-signals the loop pipe but is not a portable cross-thread event-posting API.
+Every backend's dispatch wakes when a loop descriptor becomes ready. Cocoa
+waits for native events and mirrors the loop's descriptors in a kqueue while it
+waits. If kqueue rejects a descriptor, Cocoa bounds the wait to 10 ms instead.
+
+Two calls work from any thread. `yasl_loop_kick()` only wakes the loop, and it
+is also safe in a signal handler. `yasl_loop_post()` queues a function to run
+on the owning thread during a later step or dispatch. Use it to hand results
+from worker threads to the loop:
+
+```c
+static void results_ready(void *ud)
+{
+ worker_drain(ud); /* Runs on the loop thread. */
+}
+/* On the worker thread; false means allocation failed. */
+yasl_loop_post(loop, results_ready, worker);
+```
+
+`yasl_loop_watch_signals()` delivers POSIX signals to a callback on the loop
+thread. It installs a process-wide handler for each signal, with `SA_RESTART`,
+and restores the previous action on unwatch. YASL leaves thread signal masks
+alone: a watched signal must stay unblocked in at least one thread. Only one
+loop can watch a given signal at a time.
## Native interoperability