GUACAMOLE-1115: Merge ensure RDP print process does not block itself from completing.

This commit is contained in:
Virtually Nick 2022-03-17 15:20:51 -04:00 committed by GitHub
commit c880f02fe8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 3 deletions

View File

@ -199,6 +199,14 @@ int guac_rdp_client_free_handler(guac_client* client) {
if (rdp_client->filesystem != NULL) if (rdp_client->filesystem != NULL)
guac_rdp_fs_free(rdp_client->filesystem); guac_rdp_fs_free(rdp_client->filesystem);
/* End active print job, if any */
guac_rdp_print_job* job = (guac_rdp_print_job*) rdp_client->active_job;
if (job != NULL) {
guac_rdp_print_job_kill(job);
guac_rdp_print_job_free(job);
rdp_client->active_job = NULL;
}
#ifdef ENABLE_COMMON_SSH #ifdef ENABLE_COMMON_SSH
/* Free SFTP filesystem, if loaded */ /* Free SFTP filesystem, if loaded */
if (rdp_client->sftp_filesystem) if (rdp_client->sftp_filesystem)

View File

@ -18,6 +18,7 @@
*/ */
#include "print-job.h" #include "print-job.h"
#include "rdp.h"
#include <guacamole/client.h> #include <guacamole/client.h>
#include <guacamole/protocol.h> #include <guacamole/protocol.h>
@ -27,6 +28,7 @@
#include <errno.h> #include <errno.h>
#include <pthread.h> #include <pthread.h>
#include <signal.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
@ -603,6 +605,9 @@ static void guac_rdp_print_job_read_filename(guac_rdp_print_job* job,
int guac_rdp_print_job_write(guac_rdp_print_job* job, int guac_rdp_print_job_write(guac_rdp_print_job* job,
void* buffer, int length) { void* buffer, int length) {
guac_client* client = job->client;
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
/* Create print job, if not yet created */ /* Create print job, if not yet created */
if (job->bytes_received == 0) { if (job->bytes_received == 0) {
@ -618,19 +623,40 @@ int guac_rdp_print_job_write(guac_rdp_print_job* job,
/* Update counter of bytes received */ /* Update counter of bytes received */
job->bytes_received += length; job->bytes_received += length;
/* Write data to filter process */ /* Write data to filter process, unblocking any threads waiting on the
return write(job->input_fd, buffer, length); * generic RDP message lock as this may be a lengthy operation that depends
* on other threads sending outstanding messages (resulting in deadlock if
* those messages are blocked) */
int unlock_status = pthread_mutex_unlock(&(rdp_client->message_lock));
int write_status = write(job->input_fd, buffer, length);
/* Restore RDP message lock state */
if (!unlock_status)
pthread_mutex_lock(&(rdp_client->message_lock));
return write_status;
} }
void guac_rdp_print_job_free(guac_rdp_print_job* job) { void guac_rdp_print_job_free(guac_rdp_print_job* job) {
guac_client* client = job->client;
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
/* No more input will be provided */ /* No more input will be provided */
close(job->input_fd); close(job->input_fd);
/* Wait for job to terminate */ /* Wait for job to terminate, unblocking any threads waiting on the generic
* RDP message lock as this may be a lengthy operation that depends on
* other threads sending outstanding messages (resulting in deadlock if
* those messages are blocked) */
int unlock_status = pthread_mutex_unlock(&(rdp_client->message_lock));
pthread_join(job->output_thread, NULL); pthread_join(job->output_thread, NULL);
/* Restore RDP message lock state */
if (!unlock_status)
pthread_mutex_lock(&(rdp_client->message_lock));
/* Destroy lock */ /* Destroy lock */
pthread_mutex_destroy(&(job->state_lock)); pthread_mutex_destroy(&(job->state_lock));
@ -641,6 +667,9 @@ void guac_rdp_print_job_free(guac_rdp_print_job* job) {
void guac_rdp_print_job_kill(guac_rdp_print_job* job) { void guac_rdp_print_job_kill(guac_rdp_print_job* job) {
/* Forcibly kill filter process, if running */
kill(job->filter_pid, SIGKILL);
/* Stop all handling of I/O */ /* Stop all handling of I/O */
close(job->input_fd); close(job->input_fd);
close(job->output_fd); close(job->output_fd);