mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2025-11-01 22:58:38 -04: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
|
|
@ -64,7 +64,6 @@ struct wlr_wl_buffer {
|
|||
|
||||
bool has_drm_syncobj_waiter;
|
||||
struct wlr_drm_syncobj_timeline_waiter drm_syncobj_waiter;
|
||||
struct wl_listener drm_syncobj_ready;
|
||||
|
||||
struct wlr_drm_syncobj_timeline *fallback_signal_timeline;
|
||||
uint64_t fallback_signal_point;
|
||||
|
|
|
|||
|
|
@ -37,6 +37,11 @@ struct wlr_drm_syncobj_timeline {
|
|||
} WLR_PRIVATE;
|
||||
};
|
||||
|
||||
struct wlr_drm_syncobj_timeline_waiter;
|
||||
|
||||
typedef void (*wlr_drm_syncobj_timeline_ready_callback)(
|
||||
struct wlr_drm_syncobj_timeline_waiter *waiter);
|
||||
|
||||
struct wlr_drm_syncobj_timeline_waiter {
|
||||
struct {
|
||||
struct wl_signal ready;
|
||||
|
|
@ -45,6 +50,7 @@ struct wlr_drm_syncobj_timeline_waiter {
|
|||
struct {
|
||||
int ev_fd;
|
||||
struct wl_event_source *event_source;
|
||||
wlr_drm_syncobj_timeline_ready_callback callback;
|
||||
} WLR_PRIVATE;
|
||||
};
|
||||
|
||||
|
|
@ -92,10 +98,12 @@ bool wlr_drm_syncobj_timeline_check(struct wlr_drm_syncobj_timeline *timeline,
|
|||
* Asynchronously wait for a timeline point.
|
||||
*
|
||||
* See wlr_drm_syncobj_timeline_check() for a definition of flags.
|
||||
*
|
||||
* A callback must be provided that will be invoked when the waiter has finished.
|
||||
*/
|
||||
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);
|
||||
/**
|
||||
* Cancel a timeline waiter.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue