summaryrefslogtreecommitdiff
path: root/src/platform
diff options
context:
space:
mode:
Diffstat (limited to 'src/platform')
-rw-r--r--src/platform/posix/loop.c13
-rw-r--r--src/platform/wayland/backend.c4
2 files changed, 11 insertions, 6 deletions
diff --git a/src/platform/posix/loop.c b/src/platform/posix/loop.c
index 6624575..38f504d 100644
--- a/src/platform/posix/loop.c
+++ b/src/platform/posix/loop.c
@@ -122,15 +122,13 @@ static void run_signals(struct yasl_loop *l)
}
}
+/* Only wakes the wait; the step runs posts and signals last. */
static void loop_wake_cb(void *ud, int fd, short revents)
{
- (void)revents;
+ (void)ud; (void)revents;
char buf[128];
ssize_t n;
while ((n = read(fd, buf, sizeof(buf))) > 0 || (n < 0 && errno == EINTR)) {}
- struct yasl_loop *l = ud;
- run_posts(l);
- run_signals(l);
}
static bool open_wake_pipe(int p[2])
@@ -575,7 +573,12 @@ static int step(struct yasl_loop *l, int timeout_ms)
if (d && d->deliver) d->deliver(d->ud);
int fds = dispatch_fds(l);
if (fds < 0) return fds;
- return fds + fire_timers(l);
+ int timers = fire_timers(l);
+ /* Last, so a signal sees what came with it: a child's final output is
+ * read before its exit is handled. */
+ run_posts(l);
+ run_signals(l);
+ return fds + timers;
}
int yasl_loop_step(yasl_loop *l, int timeout_ms)
diff --git a/src/platform/wayland/backend.c b/src/platform/wayland/backend.c
index f6207ed..26d88f6 100644
--- a/src/platform/wayland/backend.c
+++ b/src/platform/wayland/backend.c
@@ -30,7 +30,9 @@ static void impl_display_check(struct yasl_private_display *d)
static bool impl_surface_frame_in_flight(const struct yasl_surface *s)
{
- return ((const struct wayland_surface *)s)->frame_cb != NULL;
+ struct wayland_surface *w = (struct wayland_surface *)s;
+ /* A swap on a rendering thread is in flight before the owner arms its callback. */
+ return w->frame_cb != NULL || atomic_load(&w->frame_deferred);
}
static void impl_display_flush(struct yasl_private_display *d)