mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-02-05 04:06:11 -05:00
render/drm_syncobj: Add a callback when ready
The old approach of using a signal is fundamentally broken for a common usecase: When the waiter is ready, it's common to immediately finish and free any resources associated with it. Because of the semantics of wl_signal_emit_mutable() this is UB. wl_signal_emit_mutable() always excepts that the waiter hasn't been freed until the signal has finished being emitted. Instead of over engineering the solution, let's just add a callback required by wlr_drm_syncobj_timeline_waiter_init(). In this callback, the implementation is free to finish() or free() any resource it likes.
This commit is contained in:
parent
211eb9d60e
commit
82223e451a
5 changed files with 21 additions and 19 deletions
|
|
@ -193,12 +193,15 @@ static int handle_eventfd_ready(int ev_fd, uint32_t mask, void *data) {
|
|||
}
|
||||
|
||||
wl_signal_emit_mutable(&waiter->events.ready, NULL);
|
||||
waiter->callback(waiter);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool wlr_drm_syncobj_timeline_waiter_init(struct wlr_drm_syncobj_timeline_waiter *waiter,
|
||||
struct wlr_drm_syncobj_timeline *timeline, uint64_t point, uint32_t flags,
|
||||
struct wl_event_loop *loop) {
|
||||
struct wl_event_loop *loop, wlr_drm_syncobj_timeline_ready_callback callback) {
|
||||
assert(callback);
|
||||
|
||||
int ev_fd;
|
||||
#if HAVE_EVENTFD
|
||||
ev_fd = eventfd(0, EFD_CLOEXEC);
|
||||
|
|
@ -235,6 +238,7 @@ bool wlr_drm_syncobj_timeline_waiter_init(struct wlr_drm_syncobj_timeline_waiter
|
|||
*waiter = (struct wlr_drm_syncobj_timeline_waiter){
|
||||
.ev_fd = ev_fd,
|
||||
.event_source = source,
|
||||
.callback = callback,
|
||||
};
|
||||
wl_signal_init(&waiter->events.ready);
|
||||
return true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue