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.
This commit is contained in:
Daniel Eklöf 2019-11-02 00:33:37 +01:00
parent 8df82938b0
commit 00b46455a0
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
3 changed files with 22 additions and 9 deletions

View file

@ -441,10 +441,13 @@ grid_render(struct terminal *term)
assert(term->width > 0); assert(term->width > 0);
assert(term->height > 0); assert(term->height > 0);
struct buffer *buf = shm_get_buffer(term->wl->shm, term->width, term->height); unsigned long cookie = (uintptr_t)term;
wl_surface_attach(term->window->surface, buf->wl_buf, 0, 0); struct buffer *buf = shm_get_buffer(
pixman_image_t *pix = buf->pix; 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; bool all_clean = tll_length(term->grid->scroll_damage) == 0;
/* If we resized the window, or is flashing, or just stopped flashing */ /* 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 width = 2 * margin + max(20, term->search.len) * term->cell_width;
const int height = 2 * margin + 1 * term->cell_height; 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 */ /* Background - yellow on empty/match, red on mismatch */
pixman_color_t color = color_hex_to_pixman( pixman_color_t color = color_hex_to_pixman(

14
shm.c
View file

@ -10,7 +10,7 @@
#include <pixman.h> #include <pixman.h>
#define LOG_MODULE "shm" #define LOG_MODULE "shm"
#define LOG_ENABLE_DBG 1 #define LOG_ENABLE_DBG 0
#include "log.h" #include "log.h"
#include "stride.h" #include "stride.h"
#include "tllist.h" #include "tllist.h"
@ -31,13 +31,18 @@ static const struct wl_buffer_listener buffer_listener = {
}; };
struct buffer * 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) { 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; continue;
if (!it->item.busy) { if (!it->item.busy) {
LOG_DBG("cookie=%lx: re-using buffer from cache", cookie);
it->item.busy = true; it->item.busy = true;
return &it->item; return &it->item;
} }
@ -73,7 +78,7 @@ shm_get_buffer(struct wl_shm *shm, int width, int height)
/* Total size */ /* Total size */
size = stride * height; 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) { if (ftruncate(pool_fd, size) == -1) {
LOG_ERRNO("failed to truncate SHM pool"); 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( tll_push_back(
buffers, buffers,
((struct buffer){ ((struct buffer){
.cookie = cookie,
.width = width, .width = width,
.height = height, .height = height,
.stride = stride, .stride = stride,

5
shm.h
View file

@ -7,6 +7,8 @@
#include <wayland-client.h> #include <wayland-client.h>
struct buffer { struct buffer {
unsigned long cookie;
int width; int width;
int height; int height;
int stride; int stride;
@ -19,5 +21,6 @@ struct buffer {
pixman_image_t *pix; 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); void shm_fini(void);