From 8334f55418639807f511d68cd77d8bf194693637 Mon Sep 17 00:00:00 2001 From: Daniel Beer Date: Tue, 9 Oct 2012 16:34:33 +1200 Subject: [PATCH] Win32 fix-ups. Fixed missing includes in low-level IO functions. Changed implementation of condition variables to use kernel event objects, in order to preserve compatibility with NT 5.1. --- util/ctrlc.c | 1 + util/ctrlc.h | 4 ++++ util/output.c | 9 +++++++-- util/sockets.c | 2 +- util/sport.c | 3 +-- util/thread.h | 20 ++++++++++++++------ 6 files changed, 28 insertions(+), 11 deletions(-) diff --git a/util/ctrlc.c b/util/ctrlc.c index d28e4e7..238d147 100644 --- a/util/ctrlc.c +++ b/util/ctrlc.c @@ -16,6 +16,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include "ctrlc.h" #ifdef __Windows__ diff --git a/util/ctrlc.h b/util/ctrlc.h index 24b1c65..2fbda20 100644 --- a/util/ctrlc.h +++ b/util/ctrlc.h @@ -19,6 +19,10 @@ #ifndef CTRLC_H_ #define CTRLC_H_ +#ifdef __Windows__ +#include +#endif + /* The Ctrl+C subsystem provides a mechanism for interrupting IO * operations in a controlled way. Relevant signals are captured (SIGINT * on Linux and console events on Windows) and the event is reported to diff --git a/util/output.c b/util/output.c index 5dade7d..5fa4644 100644 --- a/util/output.c +++ b/util/output.c @@ -123,8 +123,13 @@ static int parse_text(const char *text) static void emit_ansi(const char *code, int len, int ansi_state, FILE *out) { #ifdef __Windows__ - fflush(out); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), ansi_state); + if (is_embedded_mode) { + fwrite(code, 1, len, out); + } else { + fflush(out); + SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), + ansi_state); + } #else fwrite(code, 1, len, out); #endif diff --git a/util/sockets.c b/util/sockets.c index 560829e..0b498be 100644 --- a/util/sockets.c +++ b/util/sockets.c @@ -22,6 +22,7 @@ #include "sockets.h" #include "util.h" +#include "ctrlc.h" #ifdef __Windows__ #include @@ -35,7 +36,6 @@ static void sockets_begin(SOCKET s, DWORD event) u_long mode = 1; ioctlsocket(s, FIONBIO, &mode); - ctrlc_reset(); WSAEventSelect(s, ctrlc_win32_event(), event); } diff --git a/util/sport.c b/util/sport.c index 6b5649f..309f71e 100644 --- a/util/sport.c +++ b/util/sport.c @@ -24,6 +24,7 @@ #include "sport.h" #include "util.h" #include "output.h" +#include "ctrlc.h" #ifdef __linux__ #include @@ -280,7 +281,6 @@ 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); @@ -291,7 +291,6 @@ int sport_write(sport_t s, const uint8_t *data, int len) OVERLAPPED ovl = {0}; ovl.hEvent = ctrlc_win32_event(); - ctrlc_reset(); WriteFile(s, (void *)data, len, NULL, &ovl); return xfer_wait(s, &ovl); diff --git a/util/thread.h b/util/thread.h index d56c119..1356f9e 100644 --- a/util/thread.h +++ b/util/thread.h @@ -74,24 +74,32 @@ static inline void thread_lock_release(thread_lock_t *lock) LeaveCriticalSection(lock); } -/* Windows condition variables. */ -typedef CONDITION_VARIABLE thread_cond_t; +/* Windows condition variables. These are simulated using kernel event + * objects. Note that this implementation is correct _only_ for the + * case of a single waiter. + */ +typedef HANDLE thread_cond_t; static inline void thread_cond_init(thread_cond_t *c) { - InitializeConditionVariable(c); + *c = CreateEvent(0, TRUE, FALSE, NULL); } -static inline void thread_cond_destroy(thread_cond_t *c) { } +static inline void thread_cond_destroy(thread_cond_t *c) { + CloseHandle(*c); +} static inline void thread_cond_wait(thread_cond_t *c, thread_lock_t *m) { - SleepConditionVariableCS(c, m, INFINITE); + thread_lock_release(m); + WaitForSingleObject(*c, INFINITE); + thread_lock_acquire(m); + ResetEvent(*c); } static inline void thread_cond_notify(thread_cond_t *c) { - WakeConditionVariable(c); + SetEvent(*c); } #else /* __Windows__ */