GUACAMOLE-180: Make common display threadsafe.
This commit is contained in:
parent
b7e0e080da
commit
5d1de67a0c
@ -26,6 +26,8 @@
|
||||
#include <guacamole/client.h>
|
||||
#include <guacamole/socket.h>
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
/**
|
||||
* A list element representing a pairing of a Guacamole layer with a
|
||||
* corresponding guac_common_surface which wraps that layer. Adjacent layers
|
||||
@ -97,6 +99,13 @@ typedef struct guac_common_display {
|
||||
*/
|
||||
guac_common_display_layer* buffers;
|
||||
|
||||
/**
|
||||
* Mutex which is locked internally when access to the display must be
|
||||
* synchronized. All public functions of guac_common_display should be
|
||||
* considered threadsafe.
|
||||
*/
|
||||
pthread_mutex_t _lock;
|
||||
|
||||
} guac_common_display;
|
||||
|
||||
/**
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <guacamole/client.h>
|
||||
#include <guacamole/socket.h>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -106,6 +107,8 @@ guac_common_display* guac_common_display_alloc(guac_client* client,
|
||||
if (display == NULL)
|
||||
return NULL;
|
||||
|
||||
pthread_mutex_init(&display->_lock, NULL);
|
||||
|
||||
/* Associate display with given client */
|
||||
display->client = client;
|
||||
|
||||
@ -135,6 +138,7 @@ void guac_common_display_free(guac_common_display* display) {
|
||||
guac_common_display_free_layers(display->buffers, display->client);
|
||||
guac_common_display_free_layers(display->layers, display->client);
|
||||
|
||||
pthread_mutex_destroy(&display->_lock);
|
||||
free(display);
|
||||
|
||||
}
|
||||
@ -142,6 +146,8 @@ void guac_common_display_free(guac_common_display* display) {
|
||||
void guac_common_display_dup(guac_common_display* display, guac_user* user,
|
||||
guac_socket* socket) {
|
||||
|
||||
pthread_mutex_lock(&display->_lock);
|
||||
|
||||
/* Sunchronize shared cursor */
|
||||
guac_common_cursor_dup(display->cursor, user, socket);
|
||||
|
||||
@ -152,10 +158,14 @@ void guac_common_display_dup(guac_common_display* display, guac_user* user,
|
||||
guac_common_display_dup_layers(display->layers, user, socket);
|
||||
guac_common_display_dup_layers(display->buffers, user, socket);
|
||||
|
||||
pthread_mutex_unlock(&display->_lock);
|
||||
|
||||
}
|
||||
|
||||
void guac_common_display_flush(guac_common_display* display) {
|
||||
|
||||
pthread_mutex_lock(&display->_lock);
|
||||
|
||||
guac_common_display_layer* current = display->layers;
|
||||
|
||||
/* Flush all surfaces */
|
||||
@ -166,6 +176,8 @@ void guac_common_display_flush(guac_common_display* display) {
|
||||
|
||||
guac_common_surface_flush(display->default_surface);
|
||||
|
||||
pthread_mutex_unlock(&display->_lock);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -246,42 +258,50 @@ static void guac_common_display_remove_layer(guac_common_display_layer** head,
|
||||
guac_common_display_layer* guac_common_display_alloc_layer(
|
||||
guac_common_display* display, int width, int height) {
|
||||
|
||||
guac_layer* layer;
|
||||
guac_common_surface* surface;
|
||||
pthread_mutex_lock(&display->_lock);
|
||||
|
||||
/* Allocate Guacamole layer */
|
||||
layer = guac_client_alloc_layer(display->client);
|
||||
guac_layer* layer = guac_client_alloc_layer(display->client);
|
||||
|
||||
/* Allocate corresponding surface */
|
||||
surface = guac_common_surface_alloc(display->client,
|
||||
guac_common_surface* surface = guac_common_surface_alloc(display->client,
|
||||
display->client->socket, layer, width, height);
|
||||
|
||||
/* Add layer and surface to list */
|
||||
return guac_common_display_add_layer(&display->layers, layer, surface);
|
||||
guac_common_display_layer* display_layer =
|
||||
guac_common_display_add_layer(&display->layers, layer, surface);
|
||||
|
||||
pthread_mutex_unlock(&display->_lock);
|
||||
return display_layer;
|
||||
|
||||
}
|
||||
|
||||
guac_common_display_layer* guac_common_display_alloc_buffer(
|
||||
guac_common_display* display, int width, int height) {
|
||||
|
||||
guac_layer* buffer;
|
||||
guac_common_surface* surface;
|
||||
pthread_mutex_lock(&display->_lock);
|
||||
|
||||
/* Allocate Guacamole buffer */
|
||||
buffer = guac_client_alloc_buffer(display->client);
|
||||
guac_layer* buffer = guac_client_alloc_buffer(display->client);
|
||||
|
||||
/* Allocate corresponding surface */
|
||||
surface = guac_common_surface_alloc(display->client,
|
||||
guac_common_surface* surface = guac_common_surface_alloc(display->client,
|
||||
display->client->socket, buffer, width, height);
|
||||
|
||||
/* Add buffer and surface to list */
|
||||
return guac_common_display_add_layer(&display->buffers, buffer, surface);
|
||||
guac_common_display_layer* display_layer =
|
||||
guac_common_display_add_layer(&display->buffers, buffer, surface);
|
||||
|
||||
pthread_mutex_unlock(&display->_lock);
|
||||
return display_layer;
|
||||
|
||||
}
|
||||
|
||||
void guac_common_display_free_layer(guac_common_display* display,
|
||||
guac_common_display_layer* display_layer) {
|
||||
|
||||
pthread_mutex_lock(&display->_lock);
|
||||
|
||||
/* Remove list element from list */
|
||||
guac_common_display_remove_layer(&display->layers, display_layer);
|
||||
|
||||
@ -292,11 +312,15 @@ void guac_common_display_free_layer(guac_common_display* display,
|
||||
/* Free list element */
|
||||
free(display_layer);
|
||||
|
||||
pthread_mutex_unlock(&display->_lock);
|
||||
|
||||
}
|
||||
|
||||
void guac_common_display_free_buffer(guac_common_display* display,
|
||||
guac_common_display_layer* display_buffer) {
|
||||
|
||||
pthread_mutex_lock(&display->_lock);
|
||||
|
||||
/* Remove list element from list */
|
||||
guac_common_display_remove_layer(&display->buffers, display_buffer);
|
||||
|
||||
@ -307,5 +331,7 @@ void guac_common_display_free_buffer(guac_common_display* display,
|
||||
/* Free list element */
|
||||
free(display_buffer);
|
||||
|
||||
pthread_mutex_unlock(&display->_lock);
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user