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/client.h>
|
||||||
#include <guacamole/socket.h>
|
#include <guacamole/socket.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A list element representing a pairing of a Guacamole layer with a
|
* A list element representing a pairing of a Guacamole layer with a
|
||||||
* corresponding guac_common_surface which wraps that layer. Adjacent layers
|
* corresponding guac_common_surface which wraps that layer. Adjacent layers
|
||||||
@ -97,6 +99,13 @@ typedef struct guac_common_display {
|
|||||||
*/
|
*/
|
||||||
guac_common_display_layer* buffers;
|
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;
|
} guac_common_display;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <guacamole/client.h>
|
#include <guacamole/client.h>
|
||||||
#include <guacamole/socket.h>
|
#include <guacamole/socket.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -106,6 +107,8 @@ guac_common_display* guac_common_display_alloc(guac_client* client,
|
|||||||
if (display == NULL)
|
if (display == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
pthread_mutex_init(&display->_lock, NULL);
|
||||||
|
|
||||||
/* Associate display with given client */
|
/* Associate display with given client */
|
||||||
display->client = 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->buffers, display->client);
|
||||||
guac_common_display_free_layers(display->layers, display->client);
|
guac_common_display_free_layers(display->layers, display->client);
|
||||||
|
|
||||||
|
pthread_mutex_destroy(&display->_lock);
|
||||||
free(display);
|
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,
|
void guac_common_display_dup(guac_common_display* display, guac_user* user,
|
||||||
guac_socket* socket) {
|
guac_socket* socket) {
|
||||||
|
|
||||||
|
pthread_mutex_lock(&display->_lock);
|
||||||
|
|
||||||
/* Sunchronize shared cursor */
|
/* Sunchronize shared cursor */
|
||||||
guac_common_cursor_dup(display->cursor, user, socket);
|
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->layers, user, socket);
|
||||||
guac_common_display_dup_layers(display->buffers, 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) {
|
void guac_common_display_flush(guac_common_display* display) {
|
||||||
|
|
||||||
|
pthread_mutex_lock(&display->_lock);
|
||||||
|
|
||||||
guac_common_display_layer* current = display->layers;
|
guac_common_display_layer* current = display->layers;
|
||||||
|
|
||||||
/* Flush all surfaces */
|
/* Flush all surfaces */
|
||||||
@ -166,6 +176,8 @@ void guac_common_display_flush(guac_common_display* display) {
|
|||||||
|
|
||||||
guac_common_surface_flush(display->default_surface);
|
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_layer* guac_common_display_alloc_layer(
|
||||||
guac_common_display* display, int width, int height) {
|
guac_common_display* display, int width, int height) {
|
||||||
|
|
||||||
guac_layer* layer;
|
pthread_mutex_lock(&display->_lock);
|
||||||
guac_common_surface* surface;
|
|
||||||
|
|
||||||
/* Allocate Guacamole layer */
|
/* Allocate Guacamole layer */
|
||||||
layer = guac_client_alloc_layer(display->client);
|
guac_layer* layer = guac_client_alloc_layer(display->client);
|
||||||
|
|
||||||
/* Allocate corresponding surface */
|
/* 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);
|
display->client->socket, layer, width, height);
|
||||||
|
|
||||||
/* Add layer and surface to list */
|
/* 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_layer* guac_common_display_alloc_buffer(
|
||||||
guac_common_display* display, int width, int height) {
|
guac_common_display* display, int width, int height) {
|
||||||
|
|
||||||
guac_layer* buffer;
|
pthread_mutex_lock(&display->_lock);
|
||||||
guac_common_surface* surface;
|
|
||||||
|
|
||||||
/* Allocate Guacamole buffer */
|
/* Allocate Guacamole buffer */
|
||||||
buffer = guac_client_alloc_buffer(display->client);
|
guac_layer* buffer = guac_client_alloc_buffer(display->client);
|
||||||
|
|
||||||
/* Allocate corresponding surface */
|
/* 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);
|
display->client->socket, buffer, width, height);
|
||||||
|
|
||||||
/* Add buffer and surface to list */
|
/* 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,
|
void guac_common_display_free_layer(guac_common_display* display,
|
||||||
guac_common_display_layer* display_layer) {
|
guac_common_display_layer* display_layer) {
|
||||||
|
|
||||||
|
pthread_mutex_lock(&display->_lock);
|
||||||
|
|
||||||
/* Remove list element from list */
|
/* Remove list element from list */
|
||||||
guac_common_display_remove_layer(&display->layers, display_layer);
|
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 list element */
|
||||||
free(display_layer);
|
free(display_layer);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&display->_lock);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void guac_common_display_free_buffer(guac_common_display* display,
|
void guac_common_display_free_buffer(guac_common_display* display,
|
||||||
guac_common_display_layer* display_buffer) {
|
guac_common_display_layer* display_buffer) {
|
||||||
|
|
||||||
|
pthread_mutex_lock(&display->_lock);
|
||||||
|
|
||||||
/* Remove list element from list */
|
/* Remove list element from list */
|
||||||
guac_common_display_remove_layer(&display->buffers, display_buffer);
|
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 list element */
|
||||||
free(display_buffer);
|
free(display_buffer);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&display->_lock);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user