diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/wayland-server.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/src/wayland-server.c b/src/wayland-server.c index 4778d85..6ae4689 100644 --- a/src/wayland-server.c +++ b/src/wayland-server.c @@ -40,6 +40,7 @@ #include <assert.h> #include <sys/time.h> #include <fcntl.h> +#include <sys/eventfd.h> #include <sys/file.h> #include <sys/stat.h> @@ -105,6 +106,9 @@ struct wl_display { wl_display_global_filter_func_t global_filter; void *global_filter_data; + + int terminate_efd; + struct wl_event_source *term_source; }; struct wl_global { @@ -1030,6 +1034,16 @@ bind_display(struct wl_client *client, struct wl_display *display) return 0; } +static int +handle_display_terminate(int fd, uint32_t mask, void *data) { + uint64_t term_event; + + if (read(fd, &term_event, sizeof(term_event)) < 0 && errno != EAGAIN) + return -1; + + return 0; +} + /** Create Wayland display object. * * \return The Wayland display object. Null if failed to create @@ -1058,6 +1072,19 @@ wl_display_create(void) return NULL; } + display->terminate_efd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK); + if (display->terminate_efd < 0) + goto err_eventfd; + + display->term_source = wl_event_loop_add_fd(display->loop, + display->terminate_efd, + WL_EVENT_READABLE, + handle_display_terminate, + NULL); + + if (display->term_source == NULL) + goto err_term_source; + wl_list_init(&display->global_list); wl_list_init(&display->socket_list); wl_list_init(&display->client_list); @@ -1076,6 +1103,13 @@ wl_display_create(void) wl_array_init(&display->additional_shm_formats); return display; + +err_term_source: + close(display->terminate_efd); +err_eventfd: + wl_event_loop_destroy(display->loop); + free(display); + return NULL; } static void @@ -1135,6 +1169,10 @@ wl_display_destroy(struct wl_display *display) wl_list_for_each_safe(s, next, &display->socket_list, link) { wl_socket_destroy(s); } + + close(display->terminate_efd); + wl_event_source_remove(display->term_source); + wl_event_loop_destroy(display->loop); wl_list_for_each_safe(global, gnext, &display->global_list, link) @@ -1351,7 +1389,13 @@ wl_display_get_event_loop(struct wl_display *display) WL_EXPORT void wl_display_terminate(struct wl_display *display) { + int ret; + uint64_t terminate = 1; + display->run = 0; + + ret = write(display->terminate_efd, &terminate, sizeof(terminate)); + assert (ret >= 0 || errno == EAGAIN); } WL_EXPORT void |
