mirror of
https://github.com/NickHu/sway
synced 2024-12-28 22:23:30 +01:00
1d483c340d
When many surfaces are created, sway can run out of file descriptors, making wl_event_loop_add_timer (which creates a timerfd) fail and return NULL. This patch posts a "no memory" error when that is the case, and only removes the timer if it was created. (Why "no memory"? It is not easy to distinguish between failures due to running out of memory and failures due to running out of file descriptors. Also, using the newer `wl_client_post_implementation_error` function would lead to an increased version requirement for the libwayland-server dependency.)
46 lines
1.3 KiB
C
46 lines
1.3 KiB
C
#define _POSIX_C_SOURCE 200112L
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
#include <wlr/types/wlr_surface.h>
|
|
#include "sway/server.h"
|
|
#include "sway/surface.h"
|
|
|
|
void handle_destroy(struct wl_listener *listener, void *data) {
|
|
struct sway_surface *surface = wl_container_of(listener, surface, destroy);
|
|
|
|
surface->wlr_surface->data = NULL;
|
|
wl_list_remove(&surface->destroy.link);
|
|
|
|
if (surface->frame_done_timer) {
|
|
wl_event_source_remove(surface->frame_done_timer);
|
|
}
|
|
|
|
free(surface);
|
|
}
|
|
|
|
static int surface_frame_done_timer_handler(void *data) {
|
|
struct sway_surface *surface = data;
|
|
|
|
struct timespec now;
|
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
|
wlr_surface_send_frame_done(surface->wlr_surface, &now);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void handle_compositor_new_surface(struct wl_listener *listener, void *data) {
|
|
struct wlr_surface *wlr_surface = data;
|
|
|
|
struct sway_surface *surface = calloc(1, sizeof(struct sway_surface));
|
|
surface->wlr_surface = wlr_surface;
|
|
wlr_surface->data = surface;
|
|
|
|
surface->destroy.notify = handle_destroy;
|
|
wl_signal_add(&wlr_surface->events.destroy, &surface->destroy);
|
|
|
|
surface->frame_done_timer = wl_event_loop_add_timer(server.wl_event_loop,
|
|
surface_frame_done_timer_handler, surface);
|
|
if (!surface->frame_done_timer) {
|
|
wl_resource_post_no_memory(wlr_surface->resource);
|
|
}
|
|
}
|