summaryrefslogtreecommitdiff
path: root/include/yasl/loop.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/yasl/loop.h')
-rw-r--r--include/yasl/loop.h117
1 files changed, 117 insertions, 0 deletions
diff --git a/include/yasl/loop.h b/include/yasl/loop.h
index a65fa12..9faa8f7 100644
--- a/include/yasl/loop.h
+++ b/include/yasl/loop.h
@@ -1,3 +1,14 @@
+/**
+ * @file
+ * Optional event loop, file watches, and timers.
+ *
+ * Use the loop's owning thread for all calls and callbacks, except
+ * yasl_loop_now_ns(). A display borrows a supplied loop. For window applications,
+ * drive yasl_display_dispatch(), drain input, then yasl_display_flush(); the
+ * standalone loop_run() function does not replace this cycle. Timer intervals are
+ * nanoseconds; timeout_ms arguments are milliseconds. Do not recursively step/run
+ * or destroy a loop from a callback.
+ */
#ifndef YASL_LOOP_H
#define YASL_LOOP_H
@@ -10,33 +21,139 @@ extern "C" {
/* Optional event loop. Use the display's loop when adding application timers.
* A step waits at most timeout_ms: zero polls, a negative value waits indefinitely.
* Calls and callbacks use the loop's owning thread. */
+/**
+ * Create an owned standalone file-descriptor and timer loop.
+ * @return A loop to destroy with yasl_loop_destroy(), or NULL on allocation failure.
+ * Use on one owning thread. Passing it to yasl_display_open() only lends it to
+ * the display; the caller retains ownership.
+ */
YASL_API struct yasl_loop *yasl_loop_create(void);
+/**
+ * Release a loop, its watches, and its timers.
+ * @param l Loop, or NULL for no action.
+ * Close displays borrowing this loop first. Must not run during a loop callback
+ * or an active step/run. Watched file descriptors are not closed.
+ */
YASL_API void yasl_loop_destroy(struct yasl_loop *l);
+/**
+ * Step a standalone loop until yasl_loop_quit() is called.
+ * @param l Loop.
+ * @return Zero after quit, or -1 on failure.
+ * For a window application, use a dispatch, input-poll, flush cycle instead;
+ * loop_run alone does not perform that full cycle on every backend.
+ */
YASL_API int yasl_loop_run(struct yasl_loop *l);
+/**
+ * Wait for file-descriptor readiness or a timer deadline and run callbacks.
+ * @param l Loop.
+ * @param timeout_ms Maximum wait: zero polls, negative waits indefinitely.
+ * @return Number of callbacks handled, or -1 on failure.
+ * Timer deadlines shorten the wait. Callbacks can add/delete sources, including
+ * themselves. Do not recursively step/run this loop.
+ */
YASL_API int yasl_loop_step(struct yasl_loop *l, int timeout_ms);
+/**
+ * Ask the currently running yasl_loop_run() to return after this step.
+ * @param l Loop, or NULL for no action.
+ * Call on the owning thread, usually from a callback.
+ */
YASL_API void yasl_loop_quit(struct yasl_loop *l);
+/**
+ * Signal the loop's wake pipe without dispatching callbacks.
+ * @param l Loop, or NULL for no action.
+ * Multiple signals may coalesce. This does not schedule a redraw or enqueue an
+ * event, and it does not provide a cross-thread application messaging contract.
+ */
YASL_API void yasl_loop_kick(struct yasl_loop *l);
+/**
+ * Read the monotonic clock used by YASL timers and timing results.
+ * @return Nanoseconds from CLOCK_MONOTONIC, unrelated to wall-clock time.
+ * May be called from any thread.
+ */
YASL_API uint64_t yasl_loop_now_ns(void);
+/**
+ * Get the loop used for a display's file watches and application timers.
+ * @param d Display, or NULL.
+ * @return Borrowed loop, or NULL. Do not destroy a display-owned loop yourself.
+ */
YASL_API struct yasl_loop *yasl_display_loop(struct yasl_display *d);
+/**
+ * Register a borrowed file descriptor for poll-style readiness.
+ * @param l Loop.
+ * @param fd Open file descriptor; it remains owned by the caller.
+ * @param events Bitmask from <poll.h>, for example POLLIN or POLLOUT.
+ * @param fn Callback receiving poll revents (including errors/hangup); return value is ignored.
+ * @param ud Borrowed userdata until watch removal or loop destruction.
+ * @return Positive watch ID, or -1 on failure.
+ * Delete the watch before closing fd. The callback must consume readiness or
+ * change/remove its watch to avoid repeated immediate wakeups.
+ */
YASL_API int yasl_loop_add_fd(struct yasl_loop *l, int fd, short events,
int (*fn)(int fd, short revents, void *ud), void *ud);
+/**
+ * Remove a file watch without closing its descriptor.
+ * @param l Loop.
+ * @param id Watch ID returned by yasl_loop_add_fd().
+ * @return Zero if removed, or -1 for an invalid/missing watch.
+ */
YASL_API int yasl_loop_del_fd(struct yasl_loop *l, int id);
+/**
+ * Replace a watch's poll event mask.
+ * @param l Loop.
+ * @param id Watch ID.
+ * @param events New <poll.h> mask; zero disables requested readiness (errors may still arrive).
+ * @return Zero if updated, or -1 for an invalid/missing watch.
+ */
YASL_API int yasl_loop_set_fd_events(struct yasl_loop *l, int id, short events);
/* Timers use nanoseconds. Return the next interval to repeat/reschedule, or zero
* to remove the timer. A zero ID indicates failure. Loop timers live until they
* stop, are deleted, or the loop is destroyed. Surface timers are also canceled
* when their surface is destroyed. */
+/** Timer identity scoped to its loop. Zero is invalid; do not reuse a retired ID. */
typedef uint32_t yasl_timer_id;
+/** Timer callback. interval_ns is the last scheduled delay; return the next delay or zero to stop. */
typedef uint64_t (*yasl_timer_cb)(void *ud, yasl_timer_id id, uint64_t interval_ns);
+/** Convert a nonnegative integer millisecond value to nanoseconds; avoid overflow. */
#define YASL_MS_TO_NS(ms) ((uint64_t)(ms) * 1000000ull)
+/**
+ * Schedule a timer on a loop.
+ * @param l Loop.
+ * @param interval_ns Nonzero delay in monotonic nanoseconds before first firing.
+ * @param cb Required callback; returns a new nonzero interval to repeat, or zero to stop.
+ * @param ud Borrowed userdata until the timer stops, is deleted, or the loop is destroyed.
+ * @return Nonzero timer ID, or zero for invalid arguments or allocation failure.
+ * Repeating timers coalesce missed deadlines; do not use them to count elapsed
+ * wall time. The callback receives the last scheduled interval, not elapsed time.
+ */
YASL_API yasl_timer_id yasl_loop_add_timer(struct yasl_loop *l, uint64_t interval_ns,
yasl_timer_cb cb, void *ud);
+/**
+ * Cancel a loop timer, including from its own callback.
+ * @param l Loop.
+ * @param id Timer ID.
+ * @return true if an armed timer was removed, false if invalid or already retired.
+ */
YASL_API bool yasl_loop_del_timer(struct yasl_loop *l, yasl_timer_id id);
+/**
+ * Schedule a timer canceled automatically on surface destruction.
+ * @param s Surface whose display loop will run the timer.
+ * @param interval_ns Nonzero initial delay in nanoseconds.
+ * @param cb Required timer callback, with the same rules as yasl_loop_add_timer().
+ * @param ud Borrowed userdata until the timer ends or the surface is destroyed.
+ * @return Nonzero timer ID, or zero on failure.
+ * The surface does not own userdata. Cancel with yasl_surface_del_timer().
+ */
YASL_API yasl_timer_id yasl_surface_add_timer(struct yasl_surface *s, uint64_t interval_ns,
yasl_timer_cb cb, void *ud);
+/**
+ * Cancel a timer registered through yasl_surface_add_timer().
+ * @param s Owning surface.
+ * @param id Timer ID.
+ * @return true if still armed and removed; false if unknown or already retired.
+ */
YASL_API bool yasl_surface_del_timer(struct yasl_surface *s, yasl_timer_id id);
#ifdef __cplusplus