GUAC-654: Do NOT block indefinitely while waiting for socket to die.

This commit is contained in:
Michael Jumper 2014-05-07 15:19:53 -07:00
parent 6b33c8eeda
commit b87d99cc40
2 changed files with 33 additions and 4 deletions

View File

@ -90,15 +90,17 @@ int guac_telnet_client_free_handler(guac_client* client) {
if (guac_client_data->socket_fd != -1)
close(guac_client_data->socket_fd);
/* Kill terminal */
guac_terminal_free(guac_client_data->term);
/* Wait for and free telnet session, if connected */
if (guac_client_data->telnet != NULL) {
pthread_join(guac_client_data->client_thread, NULL);
telnet_free(guac_client_data->telnet);
}
guac_terminal_free(guac_client_data->term);
free(client->data);
return 0;
}

View File

@ -245,6 +245,22 @@ void guac_telnet_send_naws(telnet_t* telnet, uint16_t width, uint16_t height) {
telnet_finish_sb(telnet);
}
static int __guac_telnet_wait(int socket_fd) {
fd_set fds;
struct timeval timeout;
FD_ZERO(&fds);
FD_SET(socket_fd, &fds);
/* Wait for one second */
timeout.tv_sec = 1;
timeout.tv_usec = 0;
return select(socket_fd+1, &fds, NULL, NULL, &timeout);
}
void* guac_telnet_client_thread(void* data) {
guac_client* client = (guac_client*) data;
@ -252,7 +268,7 @@ void* guac_telnet_client_thread(void* data) {
pthread_t input_thread;
char buffer[8192];
int bytes_read;
int wait_result;
/* Open telnet session */
client_data->telnet = __guac_telnet_create_session(client);
@ -271,9 +287,20 @@ void* guac_telnet_client_thread(void* data) {
}
/* While data available, write to terminal */
while ((bytes_read = read(client_data->socket_fd, buffer, sizeof(buffer))) > 0)
while ((wait_result = __guac_telnet_wait(client_data->socket_fd)) >= 0) {
/* Resume waiting of no data available */
if (wait_result == 0)
continue;
int bytes_read = read(client_data->socket_fd, buffer, sizeof(buffer));
if (bytes_read <= 0)
break;
telnet_recv(client_data->telnet, buffer, bytes_read);
}
/* Kill client and Wait for input thread to die */
guac_client_stop(client);
pthread_join(input_thread, NULL);