diff --git a/guacamole/libguac/configure.in b/guacamole/libguac/configure.in index 535546f36..e96c739a3 100644 --- a/guacamole/libguac/configure.in +++ b/guacamole/libguac/configure.in @@ -13,7 +13,7 @@ AC_CHECK_LIB([png], [png_write_png]) AC_CHECK_LIB([uuid], [uuid_generate]) # Checks for header files. -AC_CHECK_HEADERS([fcntl.h stdlib.h string.h sys/socket.h sys/time.h syslog.h unistd.h]) +AC_CHECK_HEADERS([fcntl.h stdlib.h string.h sys/socket.h sys/time.h syslog.h unistd.h semaphore.h]) # Checks for typedefs, structures, and compiler characteristics. AC_TYPE_SIZE_T diff --git a/guacamole/libguac/include/client.h b/guacamole/libguac/include/client.h index dbd416b37..a997c7ff8 100644 --- a/guacamole/libguac/include/client.h +++ b/guacamole/libguac/include/client.h @@ -22,8 +22,9 @@ #include #include -#include "uuidtree.h" +#include +#include "uuidtree.h" #include "guacio.h" /** @@ -237,6 +238,11 @@ struct guac_client_registry { */ guac_uuid_tree_node* root; + /** + * Semaphore controlling access to UUID tree. + */ + sem_t tree_lock; + }; guac_client_registry* guac_create_client_registry(); diff --git a/guacamole/libguac/src/clientreg.c b/guacamole/libguac/src/clientreg.c index fb3e13b20..94766de9b 100644 --- a/guacamole/libguac/src/clientreg.c +++ b/guacamole/libguac/src/clientreg.c @@ -22,6 +22,7 @@ #include #include +#include #include "uuidtree.h" #include "client.h" @@ -31,13 +32,16 @@ guac_client_registry* guac_create_client_registry() { guac_client_registry* registry = malloc(sizeof(guac_client_registry)); registry->root = guac_create_uuid_tree(); + sem_init(&(registry->tree_lock), 0, 1); return registry; } void guac_register_client(guac_client_registry* registry, guac_client* client) { + sem_wait(&(registry->tree_lock)); guac_uuid_tree_put(registry->root, client->uuid, client); + sem_post(&(registry->tree_lock)); } guac_client* guac_find_client(guac_client_registry* registry, uuid_t uuid) { @@ -45,11 +49,15 @@ guac_client* guac_find_client(guac_client_registry* registry, uuid_t uuid) { } void guac_remove_client(guac_client_registry* registry, uuid_t uuid) { + sem_wait(&(registry->tree_lock)); guac_uuid_tree_remove(registry->root, uuid); + sem_post(&(registry->tree_lock)); } void guac_cleanup_registry(guac_client_registry* registry) { + sem_wait(&(registry->tree_lock)); guac_cleanup_uuid_tree(registry->root); + sem_destroy(&(registry->tree_lock)); } #endif