win32: cancellable serial port IO.

This commit is contained in:
Daniel Beer 2011-07-27 05:10:18 +12:00
parent 935cd1bdff
commit 45a731f4fd
1 changed files with 37 additions and 28 deletions

61
sport.c
View File

@ -21,6 +21,7 @@
#include <errno.h> #include <errno.h>
#include "sport.h" #include "sport.h"
#include "util.h"
#ifndef WIN32 #ifndef WIN32
@ -101,10 +102,10 @@ int sport_write(sport_t s, const uint8_t *data, int len)
sport_t sport_open(const char *device, int rate, int flags) sport_t sport_open(const char *device, int rate, int flags)
{ {
HANDLE hs = CreateFile(device, GENERIC_READ | GENERIC_WRITE, HANDLE hs = CreateFile(device, GENERIC_READ | GENERIC_WRITE,
0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0, 0, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
0); 0);
DCB params = {0}; DCB params = {0};
COMMTIMEOUTS timeouts = {0};
if (hs == INVALID_HANDLE_VALUE) if (hs == INVALID_HANDLE_VALUE)
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
@ -124,17 +125,6 @@ sport_t sport_open(const char *device, int rate, int flags)
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
timeouts.ReadIntervalTimeout = 5000;
timeouts.ReadTotalTimeoutConstant = 5000;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 5000;
timeouts.WriteTotalTimeoutMultiplier = 10;
if (!SetCommTimeouts(hs, &timeouts)) {
CloseHandle(hs);
return INVALID_HANDLE_VALUE;
}
return hs; return hs;
} }
@ -162,34 +152,53 @@ int sport_set_modem(sport_t s, int bits)
return 0; return 0;
} }
int sport_read(sport_t s, uint8_t *data, int len) static int xfer_wait(sport_t s, LPOVERLAPPED ovl)
{ {
DWORD result = 0; DWORD result = 0;
if (!ReadFile(s, (void *)data, len, &result, NULL)) while (!GetOverlappedResult(s, ovl, &result, FALSE)) {
DWORD r;
if (GetLastError() != ERROR_IO_INCOMPLETE)
return -1; return -1;
if (!result) { if (ctrlc_check()) {
SetLastError(WAIT_TIMEOUT); CancelIo(s);
SetLastError(ERROR_OPERATION_ABORTED);
return -1; return -1;
} }
r = WaitForSingleObject(ctrlc_win32_event(), 5000);
if (r == WAIT_TIMEOUT) {
CancelIo(s);
SetLastError(WAIT_TIMEOUT);
return -1;
}
}
return result; return result;
} }
int sport_read(sport_t s, uint8_t *data, int len)
{
OVERLAPPED ovl = {0};
ovl.hEvent = ctrlc_win32_event();
ctrlc_reset();
ReadFile(s, (void *)data, len, NULL, &ovl);
return xfer_wait(s, &ovl);
}
int sport_write(sport_t s, const uint8_t *data, int len) int sport_write(sport_t s, const uint8_t *data, int len)
{ {
DWORD result = 0; OVERLAPPED ovl = {0};
if (!WriteFile(s, (void *)data, len, &result, NULL)) ovl.hEvent = ctrlc_win32_event();
return -1; ctrlc_reset();
if (!result) { WriteFile(s, (void *)data, len, NULL, &ovl);
SetLastError(WAIT_TIMEOUT); return xfer_wait(s, &ovl);
return -1;
}
return result;
} }
#endif #endif