From da27927a3ffe890a0c131320b8ebed94320ba815 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 12 Jan 2012 09:57:34 -0800 Subject: [PATCH] Require a minimum number of buffers before old free'd buffers are reused, implement LRU strategy for reuse of buffers (oldest free'd buffer). --- libguac/include/client.h | 13 +++++++++++++ libguac/src/client.c | 17 +++++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/libguac/include/client.h b/libguac/include/client.h index c6d4e86b..c79c4bc3 100644 --- a/libguac/include/client.h +++ b/libguac/include/client.h @@ -123,6 +123,14 @@ typedef int guac_client_init_handler(guac_client* client, int argc, char** argv) */ #define GUAC_CLIENT_MOUSE_SCROLL_DOWN 0x10 +/** + * The minimum number of buffers to create before allowing free'd buffers to + * be reclaimed. In the case a protocol rapidly creates, uses, and destroys + * buffers, this can prevent unnecessary reuse of the same buffer (which + * would make draw operations unnecessarily synchronous). + */ +#define GUAC_BUFFER_POOL_INITIAL_SIZE 1024 + /** * Possible current states of the Guacamole client. Currently, the only * two states are GUAC_CLIENT_RUNNING and GUAC_CLIENT_STOPPING. @@ -206,6 +214,11 @@ struct guac_client { */ guac_layer* __available_buffers; + /** + * Pointer to the last buffer in the list of all available buffers. + */ + guac_layer* __last_available_buffer; + /** * The head pointer of the list of all allocated layers, regardless of use * status. diff --git a/libguac/src/client.c b/libguac/src/client.c index 8e777614..ac073535 100644 --- a/libguac/src/client.c +++ b/libguac/src/client.c @@ -78,10 +78,17 @@ guac_layer* guac_client_alloc_buffer(guac_client* client) { guac_layer* allocd_layer; /* If available layers, pop off first available buffer */ - if (client->__available_buffers != NULL) { + if (client->__next_buffer_index <= -GUAC_BUFFER_POOL_INITIAL_SIZE && + client->__available_buffers != NULL) { + allocd_layer = client->__available_buffers; client->__available_buffers = client->__available_buffers->__next_available; allocd_layer->__next_available = NULL; + + /* If last buffer, reset last available buffer pointer */ + if (allocd_layer == client->__last_available_buffer) + client->__last_available_buffer = NULL; + } /* If no available buffer, allocate new buffer, add to __all_layers list */ @@ -103,9 +110,11 @@ guac_layer* guac_client_alloc_buffer(guac_client* client) { void guac_client_free_buffer(guac_client* client, guac_layer* layer) { - /* Add layer to pool of available buffers */ - layer->__next_available = client->__available_buffers; - client->__available_buffers = layer; + /* Add layer to tail of pool of available buffers */ + if (client->__last_available_buffer != NULL) + client->__last_available_buffer->__next_available = layer; + + client->__last_available_buffer = layer; }