Merge 1.5.2 changes back to master.
diff --git a/src/protocols/rdp/channels/audio-input/audio-buffer.c b/src/protocols/rdp/channels/audio-input/audio-buffer.c
index 617cb2c..c584b19 100644
--- a/src/protocols/rdp/channels/audio-input/audio-buffer.c
+++ b/src/protocols/rdp/channels/audio-input/audio-buffer.c
@@ -275,6 +275,34 @@
 }
 
 /**
+ * Parameters describing an "ack" instruction to be sent to the current user of
+ * an inbound audio stream (guac_rdp_audio_buffer).
+ */
+typedef struct guac_rdp_audio_buffer_ack_params {
+
+    /**
+     * The audio buffer associated with the guac_stream for which the "ack"
+     * instruction should be sent, if any. If there is no associated
+     * guac_stream, no "ack" will be sent.
+     */
+    guac_rdp_audio_buffer* audio_buffer;
+
+    /**
+     * An arbitrary human-readable message to send along with the "ack".
+     */
+    const char* message;
+
+    /**
+     * The Guacamole protocol status code to send with the "ack". This should
+     * be GUAC_PROTOCOL_STATUS_SUCCESS if the audio stream has been set up
+     * successfully or GUAC_PROTOCOL_STATUS_RESOURCE_CLOSED if the audio stream
+     * has been closed (but may usable again if reopened).
+     */
+    guac_protocol_status status;
+
+} guac_rdp_audio_buffer_ack_params;
+
+/**
  * Sends an "ack" instruction over the socket associated with the Guacamole
  * stream over which audio data is being received. The "ack" instruction will
  * only be sent if the Guacamole audio stream has been established (through
@@ -285,34 +313,32 @@
  * IMPORTANT: The guac_rdp_audio_buffer's lock MUST already be held when
  * invoking this function.
  *
- * @param audio_buffer
- *     The audio buffer associated with the guac_stream for which the "ack"
- *     instruction should be sent, if any. If there is no associated
- *     guac_stream, this function has no effect.
+ * @param user
+ *     The user that should receive the "ack".
  *
- * @param message
- *     An arbitrary human-readable message to send along with the "ack".
+ * @param data
+ *     An instance of guac_rdp_audio_buffer_ack_params describing the "ack"
+ *     instruction to be sent.
  *
- * @param status
- *     The Guacamole protocol status code to send with the "ack". This should
- *     be GUAC_PROTOCOL_STATUS_SUCCESS if the audio stream has been set up
- *     successfully or GUAC_PROTOCOL_STATUS_RESOURCE_CLOSED if the audio stream
- *     has been closed (but may usable again if reopened).
+ * @returns
+ *     Always NULL.
  */
-static void guac_rdp_audio_buffer_ack(guac_rdp_audio_buffer* audio_buffer,
-        const char* message, guac_protocol_status status) {
+static void* guac_rdp_audio_buffer_ack(guac_user* user, void* data) {
 
-    guac_user* user = audio_buffer->user;
+    guac_rdp_audio_buffer_ack_params* params = (guac_rdp_audio_buffer_ack_params*) data;
+    guac_rdp_audio_buffer* audio_buffer = params->audio_buffer;
     guac_stream* stream = audio_buffer->stream;
 
     /* Do not send ack unless both sides of the audio stream are ready */
     if (user == NULL || stream == NULL || audio_buffer->packet == NULL)
-        return;
+        return NULL;
 
     /* Send ack instruction */
-    guac_protocol_send_ack(user->socket, stream, message, status);
+    guac_protocol_send_ack(user->socket, stream, params->message, params->status);
     guac_socket_flush(user->socket);
 
+    return NULL;
+
 }
 
 void guac_rdp_audio_buffer_set_stream(guac_rdp_audio_buffer* audio_buffer,
@@ -328,8 +354,8 @@
     audio_buffer->in_format.bps = bps;
 
     /* Acknowledge stream creation (if buffer is ready to receive) */
-    guac_rdp_audio_buffer_ack(audio_buffer,
-            "OK", GUAC_PROTOCOL_STATUS_SUCCESS);
+    guac_rdp_audio_buffer_ack_params ack_params = { audio_buffer, "OK", GUAC_PROTOCOL_STATUS_SUCCESS };
+    guac_client_for_user(audio_buffer->client, user, guac_rdp_audio_buffer_ack, &ack_params);
 
     guac_user_log(user, GUAC_LOG_DEBUG, "User is requesting to provide audio "
             "input as %i-channel, %i Hz PCM audio at %i bytes/sample.",
@@ -393,8 +419,10 @@
     clock_gettime(CLOCK_REALTIME, &audio_buffer->next_flush);
 
     /* Acknowledge stream creation (if stream is ready to receive) */
-    guac_rdp_audio_buffer_ack(audio_buffer,
-            "OK", GUAC_PROTOCOL_STATUS_SUCCESS);
+    if (audio_buffer->user != NULL) {
+        guac_rdp_audio_buffer_ack_params ack_params = { audio_buffer, "OK", GUAC_PROTOCOL_STATUS_SUCCESS };
+        guac_client_for_user(audio_buffer->client, audio_buffer->user, guac_rdp_audio_buffer_ack, &ack_params);
+    }
 
     pthread_cond_broadcast(&(audio_buffer->modified));
     pthread_mutex_unlock(&(audio_buffer->lock));
@@ -561,8 +589,10 @@
     }
 
     /* The stream is now closed */
-    guac_rdp_audio_buffer_ack(audio_buffer,
-            "CLOSED", GUAC_PROTOCOL_STATUS_RESOURCE_CLOSED);
+    if (audio_buffer->user != NULL) {
+        guac_rdp_audio_buffer_ack_params ack_params = { audio_buffer, "CLOSED", GUAC_PROTOCOL_STATUS_RESOURCE_CLOSED };
+        guac_client_for_user(audio_buffer->client, audio_buffer->user, guac_rdp_audio_buffer_ack, &ack_params);
+    }
 
     /* Unset user and stream */
     audio_buffer->user = NULL;