diff --git a/src/libguac/client.c b/src/libguac/client.c index 21906077e..43d61106e 100644 --- a/src/libguac/client.c +++ b/src/libguac/client.c @@ -186,8 +186,25 @@ static void guac_client_promote_pending_users(union sigval data) { guac_acquire_write_lock(&(client->__pending_users_lock)); /* Run the pending join handler, if one is defined */ - if (client->join_pending_handler) - client->join_pending_handler(client); + if (client->join_pending_handler) { + + /* If an error occurs in the pending handler */ + if(client->join_pending_handler(client)) { + + guac_release_lock(&(client->__pending_users_lock)); + + /* Mark the handler as not running */ + pthread_mutex_lock(&(client->__pending_users_timer_mutex)); + client->__pending_users_timer_state = GUAC_CLIENT_PENDING_TIMER_REGISTERED; + pthread_mutex_unlock(&(client->__pending_users_timer_mutex)); + + /* Log a warning and abort the promotion of the pending users */ + guac_client_log(client, GUAC_LOG_WARNING, + "join_pending_handler did not successfully complete;" + " any pending users have not been promoted.\n"); + return; + } + } /* The first pending user in the list, if any */ guac_user* first_user = client->__pending_users; diff --git a/src/libguac/guacamole/client-fntypes.h b/src/libguac/guacamole/client-fntypes.h index 26cddb6f8..367a6f1e2 100644 --- a/src/libguac/guacamole/client-fntypes.h +++ b/src/libguac/guacamole/client-fntypes.h @@ -57,8 +57,12 @@ typedef int guac_client_free_handler(guac_client* client); * * @param client * The client whose handler was invoked. + * + * @return + * Zero if the pending handler ran successfuly, or a non-zero value if an + * error occured. */ -typedef void guac_client_join_pending_handler(guac_client* client); +typedef int guac_client_join_pending_handler(guac_client* client); /** * Handler for logging messages related to a given guac_client instance. diff --git a/src/libguac/guacamole/client.h b/src/libguac/guacamole/client.h index c98c43b09..4bfdc0704 100644 --- a/src/libguac/guacamole/client.h +++ b/src/libguac/guacamole/client.h @@ -255,7 +255,7 @@ struct guac_client { * * Example: * @code - * void join_pending_handler(guac_client* client); + * int join_pending_handler(guac_client* client); * * int guac_client_init(guac_client* client) { * client->join_pending_handler = join_pending_handler; diff --git a/src/protocols/kubernetes/client.c b/src/protocols/kubernetes/client.c index b3a44e110..f90358fbc 100644 --- a/src/protocols/kubernetes/client.c +++ b/src/protocols/kubernetes/client.c @@ -85,8 +85,11 @@ static void guac_kubernetes_log(int level, const char* line) { * @param client * The client whose pending users are about to be promoted to full users, * and therefore need their connection state synchronized. + * + * @return + * Always zero. */ -static void guac_kubernetes_join_pending_handler(guac_client* client) { +static int guac_kubernetes_join_pending_handler(guac_client* client) { guac_kubernetes_client* kubernetes_client = (guac_kubernetes_client*) client->data; @@ -97,6 +100,8 @@ static void guac_kubernetes_join_pending_handler(guac_client* client) { guac_kubernetes_send_current_argv_batch(client, broadcast_socket); guac_socket_flush(broadcast_socket); + return 0; + } int guac_client_init(guac_client* client) { diff --git a/src/protocols/rdp/client.c b/src/protocols/rdp/client.c index 0228b7e39..5130f1944 100644 --- a/src/protocols/rdp/client.c +++ b/src/protocols/rdp/client.c @@ -107,8 +107,11 @@ static void* guac_rdp_sync_pending_user_audio(guac_user* user, void* data) { * * @param client * The client whose pending users are about to be promoted. + * + * @return + * Always zero. */ -static void guac_rdp_join_pending_handler(guac_client* client) { +static int guac_rdp_join_pending_handler(guac_client* client) { guac_rdp_client* rdp_client = (guac_rdp_client*) client->data; guac_socket* broadcast_socket = client->pending_socket; @@ -126,6 +129,8 @@ static void guac_rdp_join_pending_handler(guac_client* client) { guac_socket_flush(broadcast_socket); + return 0; + } int guac_client_init(guac_client* client, int argc, char** argv) { diff --git a/src/protocols/ssh/client.c b/src/protocols/ssh/client.c index c813808b8..74a62ba07 100644 --- a/src/protocols/ssh/client.c +++ b/src/protocols/ssh/client.c @@ -43,8 +43,11 @@ * * @param client * The client whose pending users are about to be promoted. + * + * @return + * Always zero. */ -static void guac_ssh_join_pending_handler(guac_client* client) { +static int guac_ssh_join_pending_handler(guac_client* client) { guac_ssh_client* ssh_client = (guac_ssh_client*) client->data; @@ -54,6 +57,8 @@ static void guac_ssh_join_pending_handler(guac_client* client) { guac_ssh_send_current_argv_batch(client, broadcast_socket); guac_socket_flush(broadcast_socket); + return 0; + } int guac_client_init(guac_client* client) { diff --git a/src/protocols/telnet/client.c b/src/protocols/telnet/client.c index 6f2546324..3b4184023 100644 --- a/src/protocols/telnet/client.c +++ b/src/protocols/telnet/client.c @@ -42,8 +42,11 @@ * * @param client * The client whose pending users are about to be promoted. + * + * @return + * Always zero. */ -static void guac_telnet_join_pending_handler(guac_client* client) { +static int guac_telnet_join_pending_handler(guac_client* client) { guac_telnet_client* telnet_client = (guac_telnet_client*) client->data; @@ -53,6 +56,8 @@ static void guac_telnet_join_pending_handler(guac_client* client) { guac_telnet_send_current_argv_batch(client, broadcast_socket); guac_socket_flush(broadcast_socket); + return 0; + } int guac_client_init(guac_client* client) { diff --git a/src/protocols/vnc/client.c b/src/protocols/vnc/client.c index 9d7aa099d..47cafa721 100644 --- a/src/protocols/vnc/client.c +++ b/src/protocols/vnc/client.c @@ -70,8 +70,11 @@ static void* guac_vnc_sync_pending_user_audio(guac_user* user, void* data) { * * @param client * The client whose pending users are about to be promoted. + * + * @return + * Always zero. */ -static void guac_vnc_join_pending_handler(guac_client* client) { +static int guac_vnc_join_pending_handler(guac_client* client) { guac_vnc_client* vnc_client = (guac_vnc_client*) client->data; guac_socket* broadcast_socket = client->pending_socket; @@ -87,6 +90,8 @@ static void guac_vnc_join_pending_handler(guac_client* client) { guac_common_display_dup(vnc_client->display, client, broadcast_socket); guac_socket_flush(broadcast_socket); + return 0; + } int guac_client_init(guac_client* client) {