mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-14 08:22:25 -04:00
util/signal: Introduce wlr_signal_emit_final
wlr_signal_emit_final is conceptually similar to wl_signal_emit_mutable (i.e., our old wlr_signal_emit_safe), but instead of running all listeners that were added at the time the signal emit started, we run until the list is empty, removing entries as we go along. This ensures that newly added signals are run all the same.
This commit is contained in:
parent
156d47c866
commit
b222fe2a4a
4 changed files with 29 additions and 1 deletions
8
include/util/signal.h
Normal file
8
include/util/signal.h
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef UTIL_SIGNAL_H
|
||||
#define UTIL_SIGNAL_H
|
||||
|
||||
#include <wayland-server-core.h>
|
||||
|
||||
void wlr_signal_emit_final(struct wl_signal *signal, void *data);
|
||||
|
||||
#endif
|
||||
|
|
@ -11,6 +11,7 @@
|
|||
#include "types/wlr_output.h"
|
||||
#include "util/env.h"
|
||||
#include "util/global.h"
|
||||
#include "util/signal.h"
|
||||
|
||||
#define OUTPUT_VERSION 4
|
||||
|
||||
|
|
@ -377,7 +378,7 @@ void wlr_output_init(struct wlr_output *output, struct wlr_backend *backend,
|
|||
}
|
||||
|
||||
void wlr_output_finish(struct wlr_output *output) {
|
||||
wl_signal_emit_mutable(&output->events.destroy, output);
|
||||
wlr_signal_emit_final(&output->events.destroy, output);
|
||||
wlr_addon_set_finish(&output->addons);
|
||||
|
||||
assert(wl_list_empty(&output->events.frame.listener_list));
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ wlr_files += files(
|
|||
'region.c',
|
||||
'set.c',
|
||||
'shm.c',
|
||||
'signal.c',
|
||||
'time.c',
|
||||
'token.c',
|
||||
'transform.c',
|
||||
|
|
|
|||
18
util/signal.c
Normal file
18
util/signal.c
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#include "util/signal.h"
|
||||
|
||||
void wlr_signal_emit_final(struct wl_signal *signal, void *data) {
|
||||
|
||||
// We need to run all listeners one final time. To support all types of list mutations and to
|
||||
// ensure that all listeners including those added during this execution is run, we run until
|
||||
// the list is empty, removing listeners just before we run them. To not affect the behavior of
|
||||
// the listener, we re-initialize the listener's link element.
|
||||
while (signal->listener_list.next != &signal->listener_list) {
|
||||
struct wl_list *pos = signal->listener_list.next;
|
||||
struct wl_listener *l = wl_container_of(pos, l, link);
|
||||
|
||||
wl_list_remove(pos);
|
||||
wl_list_init(pos);
|
||||
|
||||
l->notify(l, data);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue