GUACAMOLE-171: Do not require knowledge of broadcast socket internals (do not acquire write lock around join/leave handlers).

This commit is contained in:
Michael Jumper 2016-10-07 13:09:59 -07:00
parent 98b92f0900
commit 7a65a63aa9
2 changed files with 8 additions and 26 deletions

View File

@ -273,12 +273,12 @@ int guac_client_add_user(guac_client* client, guac_user* user, int argc, char**
int retval = 0;
pthread_rwlock_wrlock(&(client->__users_lock));
/* Call handler, if defined */
if (client->join_handler)
retval = client->join_handler(user, argc, argv);
pthread_rwlock_wrlock(&(client->__users_lock));
/* Add to list if join was successful */
if (retval == 0) {
@ -307,12 +307,6 @@ void guac_client_remove_user(guac_client* client, guac_user* user) {
pthread_rwlock_wrlock(&(client->__users_lock));
/* Call handler, if defined */
if (user->leave_handler)
user->leave_handler(user);
else if (client->leave_handler)
client->leave_handler(user);
/* Update prev / head */
if (user->__prev != NULL)
user->__prev->__next = user->__next;
@ -331,6 +325,12 @@ void guac_client_remove_user(guac_client* client, guac_user* user) {
pthread_rwlock_unlock(&(client->__users_lock));
/* Call handler, if defined */
if (user->leave_handler)
user->leave_handler(user);
else if (client->leave_handler)
client->leave_handler(user);
}
void guac_client_foreach_user(guac_client* client, guac_user_callback* callback, void* data) {

View File

@ -53,10 +53,6 @@ struct guac_client {
* provide their own mechanism of I/O for their protocol. The guac_socket
* structure is used only to communicate conveniently with the Guacamole
* web-client.
*
* Because this socket broadcasts to all connected users, this socket MUST
* NOT be used within the same thread as a "leave" or "join" handler. Doing
* so results in undefined behavior, including possible segfaults.
*/
guac_socket* socket;
@ -437,10 +433,6 @@ void guac_client_remove_user(guac_client* client, guac_user* user);
* MAY invoke guac_client_foreach_user(), doing so should not be necessary, and
* may indicate poor design choices.
*
* Because this function loops through all connected users, this function MUST
* NOT be invoked within the same thread as a "leave" or "join" handler. Doing
* so results in undefined behavior, including possible segfaults.
*
* @param client
* The client whose users should be iterated.
*
@ -465,11 +457,6 @@ void guac_client_foreach_user(guac_client* client,
* This function is reentrant, but the user list MUST NOT be manipulated
* within the same thread as a callback to this function.
*
* Because this function depends on a consistent list of connected users, this
* function MUST NOT be invoked within the same thread as a "leave" or "join"
* handler. Doing so results in undefined behavior, including possible
* segfaults.
*
* @param client
* The client to retrieve the owner from.
*
@ -498,11 +485,6 @@ void* guac_client_for_owner(guac_client* client, guac_user_callback* callback,
* This function is reentrant, but the user list MUST NOT be manipulated
* within the same thread as a callback to this function.
*
* Because this function depends on a consistent list of connected users, this
* function MUST NOT be invoked within the same thread as a "leave" or "join"
* handler. Doing so results in undefined behavior, including possible
* segfaults.
*
* @param client
* The client that the given user is expected to be associated with.
*