From 00b46455a065d33cb01dc6345637b38c3309596d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 2 Nov 2019 00:33:37 +0100 Subject: [PATCH] shm: associate a 'cookie' with each buffer When re-using a buffer from cache, only re-use ones with a matching cookie. This prevents contention between multiple terminal windows. --- render.c | 12 ++++++++---- shm.c | 14 ++++++++++---- shm.h | 5 ++++- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/render.c b/render.c index 37d1aee1..0b0c6d5b 100644 --- a/render.c +++ b/render.c @@ -441,10 +441,13 @@ grid_render(struct terminal *term) assert(term->width > 0); assert(term->height > 0); - struct buffer *buf = shm_get_buffer(term->wl->shm, term->width, term->height); - wl_surface_attach(term->window->surface, buf->wl_buf, 0, 0); - pixman_image_t *pix = buf->pix; + unsigned long cookie = (uintptr_t)term; + struct buffer *buf = shm_get_buffer( + term->wl->shm, term->width, term->height, cookie); + wl_surface_attach(term->window->surface, buf->wl_buf, 0, 0); + + pixman_image_t *pix = buf->pix; bool all_clean = tll_length(term->grid->scroll_damage) == 0; /* If we resized the window, or is flashing, or just stopped flashing */ @@ -754,7 +757,8 @@ render_search_box(struct terminal *term) const int width = 2 * margin + max(20, term->search.len) * term->cell_width; const int height = 2 * margin + 1 * term->cell_height; - struct buffer *buf = shm_get_buffer(term->wl->shm, width, height); + unsigned long cookie = (uintptr_t)term; + struct buffer *buf = shm_get_buffer(term->wl->shm, width, height, cookie); /* Background - yellow on empty/match, red on mismatch */ pixman_color_t color = color_hex_to_pixman( diff --git a/shm.c b/shm.c index fd962698..7c649ac3 100644 --- a/shm.c +++ b/shm.c @@ -10,7 +10,7 @@ #include #define LOG_MODULE "shm" -#define LOG_ENABLE_DBG 1 +#define LOG_ENABLE_DBG 0 #include "log.h" #include "stride.h" #include "tllist.h" @@ -31,13 +31,18 @@ static const struct wl_buffer_listener buffer_listener = { }; struct buffer * -shm_get_buffer(struct wl_shm *shm, int width, int height) +shm_get_buffer(struct wl_shm *shm, int width, int height, unsigned long cookie) { tll_foreach(buffers, it) { - if (it->item.width != width || it->item.height != height) + if (it->item.width != width) + continue; + if (it->item.height != height) + continue; + if (it->item.cookie != cookie) continue; if (!it->item.busy) { + LOG_DBG("cookie=%lx: re-using buffer from cache", cookie); it->item.busy = true; return &it->item; } @@ -73,7 +78,7 @@ shm_get_buffer(struct wl_shm *shm, int width, int height) /* Total size */ size = stride * height; - LOG_DBG("allocating a %zu KB pool", size / 1024); + LOG_DBG("cookie=%lx: allocating new buffer: %zu KB", cookie, size / 1024); if (ftruncate(pool_fd, size) == -1) { LOG_ERRNO("failed to truncate SHM pool"); @@ -111,6 +116,7 @@ shm_get_buffer(struct wl_shm *shm, int width, int height) tll_push_back( buffers, ((struct buffer){ + .cookie = cookie, .width = width, .height = height, .stride = stride, diff --git a/shm.h b/shm.h index 312d45a9..555c5d51 100644 --- a/shm.h +++ b/shm.h @@ -7,6 +7,8 @@ #include struct buffer { + unsigned long cookie; + int width; int height; int stride; @@ -19,5 +21,6 @@ struct buffer { pixman_image_t *pix; }; -struct buffer *shm_get_buffer(struct wl_shm *shm, int width, int height); +struct buffer *shm_get_buffer( + struct wl_shm *shm, int width, int height, unsigned long cookie); void shm_fini(void);