diff --git a/channels/serial/client/serial_main.c b/channels/serial/client/serial_main.c index bbcdbeba7..8cdd64b79 100644 --- a/channels/serial/client/serial_main.c +++ b/channels/serial/client/serial_main.c @@ -44,10 +44,13 @@ #include "serial_constants.h" #include <winpr/crt.h> +#include <winpr/synch.h> +#include <winpr/thread.h> +#include <winpr/collections.h> #include <freerdp/freerdp.h> +#include <freerdp/utils/list.h> #include <freerdp/utils/stream.h> -#include <freerdp/utils/thread.h> #include <freerdp/channels/rdpdr.h> typedef struct _SERIAL_DEVICE SERIAL_DEVICE; @@ -59,9 +62,11 @@ struct _SERIAL_DEVICE char* path; SERIAL_TTY* tty; - LIST* irp_list; + HANDLE thread; + HANDLE stopEvent; + + wQueue* queue; LIST* pending_irps; - freerdp_thread* thread; HANDLE in_event; fd_set read_fds; @@ -253,7 +258,7 @@ static void serial_process_irp_device_control(SERIAL_DEVICE* serial, IRP* irp) tty = serial->tty; - if (tty == NULL) + if (!tty) { irp->IoStatus = STATUS_UNSUCCESSFUL; OutputBufferLength = 0; @@ -314,34 +319,18 @@ static void serial_process_irp(SERIAL_DEVICE* serial, IRP* irp) serial_check_for_events(serial); } -static void serial_process_irp_list(SERIAL_DEVICE* serial) -{ - IRP* irp; - - while (1) - { - if (freerdp_thread_is_stopped(serial->thread)) - break; - - freerdp_thread_lock(serial->thread); - irp = (IRP*) list_dequeue(serial->irp_list); - freerdp_thread_unlock(serial->thread); - - if (irp == NULL) - break; - - serial_process_irp(serial, irp); - } -} - static void* serial_thread_func(void* arg) { + IRP* irp; DWORD status; SERIAL_DEVICE* serial = (SERIAL_DEVICE*)arg; while (1) { - if (freerdp_thread_wait_timeout(serial->thread, 500) < 0) + if (WaitForSingleObject(serial->stopEvent, 0) == WAIT_OBJECT_0) + break; + + if (WaitForSingleObject(Queue_Event(serial->queue), 10) == WAIT_OBJECT_0) break; serial->nfds = 1; @@ -352,23 +341,20 @@ static void* serial_thread_func(void* arg) serial->tv.tv_usec = 0; serial->select_timeout = 0; - if (freerdp_thread_is_stopped(serial->thread)) - break; + irp = (IRP*) Queue_Dequeue(serial->queue); - freerdp_thread_reset(serial->thread); - serial_process_irp_list(serial); + if (irp) + serial_process_irp(serial, irp); status = WaitForSingleObject(serial->in_event, 0); if ((status == WAIT_OBJECT_0) || (status == WAIT_TIMEOUT)) { - if (serial_check_fds(serial)) - ResetEvent(serial->in_event); + if (serial_check_fds(serial)) + ResetEvent(serial->in_event); } } - freerdp_thread_quit(serial->thread); - return NULL; } @@ -376,40 +362,26 @@ static void serial_irp_request(DEVICE* device, IRP* irp) { SERIAL_DEVICE* serial = (SERIAL_DEVICE*) device; - freerdp_thread_lock(serial->thread); - list_enqueue(serial->irp_list, irp); - freerdp_thread_unlock(serial->thread); - - freerdp_thread_signal(serial->thread); + Queue_Enqueue(serial->queue, irp); } static void serial_free(DEVICE* device) { - IRP* irp; SERIAL_DEVICE* serial = (SERIAL_DEVICE*) device; DEBUG_SVC("freeing device"); - freerdp_thread_stop(serial->thread); - freerdp_thread_free(serial->thread); + SetEvent(serial->stopEvent); - while ((irp = (IRP*) list_dequeue(serial->irp_list)) != NULL) - irp->Discard(irp); - - list_free(serial->irp_list); - - while ((irp = (IRP*) list_dequeue(serial->pending_irps)) != NULL) - irp->Discard(irp); - - list_free(serial->pending_irps); + /* TODO: free lists */ free(serial); } static void serial_abort_single_io(SERIAL_DEVICE* serial, UINT32 file_id, UINT32 abort_io, UINT32 io_status) { - IRP* irp = NULL; UINT32 major; + IRP* irp = NULL; SERIAL_TTY* tty; DEBUG_SVC("[in] pending size %d", list_size(serial->pending_irps)); @@ -626,7 +598,7 @@ static void __serial_check_fds(SERIAL_DEVICE* serial) prev = irp; irp = (IRP*) list_next(serial->pending_irps, irp); - if (irp_completed || prev->IoStatus == STATUS_SUCCESS) + if (irp_completed || (prev->IoStatus == STATUS_SUCCESS)) { list_remove(serial->pending_irps, prev); SetEvent(serial->in_event); @@ -737,14 +709,15 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) stream_write_BYTE(serial->device.data, name[i] < 0 ? '_' : name[i]); serial->path = path; - serial->irp_list = list_new(); + serial->queue = Queue_New(TRUE, -1, -1); serial->pending_irps = list_new(); - serial->thread = freerdp_thread_new(); serial->in_event = CreateEvent(NULL, TRUE, FALSE, NULL); + serial->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) serial); - freerdp_thread_start(serial->thread, serial_thread_func, serial); + serial->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) serial_thread_func, (void*) serial, 0, NULL); } return 0; diff --git a/channels/serial/client/serial_tty.c b/channels/serial/client/serial_tty.c index 0ba907b09..24dce6eac 100644 --- a/channels/serial/client/serial_tty.c +++ b/channels/serial/client/serial_tty.c @@ -372,9 +372,9 @@ UINT32 serial_tty_control(SERIAL_TTY* tty, UINT32 IoControlCode, STREAM* input, BOOL serial_tty_read(SERIAL_TTY* tty, BYTE* buffer, UINT32* Length) { - ssize_t r; + ssize_t status; long timeout = 90; - struct termios *ptermios; + struct termios* ptermios; DEBUG_SVC("in"); ptermios = tty->ptermios; @@ -410,13 +410,13 @@ BOOL serial_tty_read(SERIAL_TTY* tty, BYTE* buffer, UINT32* Length) ZeroMemory(buffer, *Length); - r = read(tty->fd, buffer, *Length); + status = read(tty->fd, buffer, *Length); - if (r < 0) + if (status < 0) return FALSE; - tty->event_txempty = r; - *Length = r; + tty->event_txempty = status; + *Length = status; return TRUE; } @@ -550,7 +550,7 @@ SERIAL_TTY* serial_tty_new(const char* path, UINT32 id) BOOL serial_tty_get_event(SERIAL_TTY* tty, UINT32* result) { int bytes; - BOOL ret = FALSE; + BOOL status = FALSE; DEBUG_SVC("in"); @@ -579,7 +579,7 @@ BOOL serial_tty_get_event(SERIAL_TTY* tty, UINT32* result) { DEBUG_SVC("SERIAL_EV_RLSD"); *result |= SERIAL_EV_RLSD; - ret = TRUE; + status = TRUE; } } @@ -588,14 +588,14 @@ BOOL serial_tty_get_event(SERIAL_TTY* tty, UINT32* result) { DEBUG_SVC("SERIAL_EV_RXFLAG bytes %d", bytes); *result |= SERIAL_EV_RXFLAG; - ret = TRUE; + status = TRUE; } if ((tty->wait_mask & SERIAL_EV_RXCHAR)) { DEBUG_SVC("SERIAL_EV_RXCHAR bytes %d", bytes); *result |= SERIAL_EV_RXCHAR; - ret = TRUE; + status = TRUE; } } @@ -611,7 +611,7 @@ BOOL serial_tty_get_event(SERIAL_TTY* tty, UINT32* result) { DEBUG_SVC("SERIAL_EV_TXEMPTY"); *result |= SERIAL_EV_TXEMPTY; - ret = TRUE; + status = TRUE; } tty->event_txempty = bytes; #endif @@ -624,7 +624,7 @@ BOOL serial_tty_get_event(SERIAL_TTY* tty, UINT32* result) { DEBUG_SVC("SERIAL_EV_DSR %s", (bytes & TIOCM_DSR) ? "ON" : "OFF"); *result |= SERIAL_EV_DSR; - ret = TRUE; + status = TRUE; } } @@ -635,14 +635,14 @@ BOOL serial_tty_get_event(SERIAL_TTY* tty, UINT32* result) { DEBUG_SVC("SERIAL_EV_CTS %s", (bytes & TIOCM_CTS) ? "ON" : "OFF"); *result |= SERIAL_EV_CTS; - ret = TRUE; + status = TRUE; } } - if (ret) + if (status) tty->event_pending = 0; - return ret; + return status; } static BOOL tty_get_termios(SERIAL_TTY* tty)