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.
This commit is contained in:
Daniel Beer 2012-10-09 16:34:33 +12:00
parent 4649c7e662
commit 8334f55418
6 changed files with 28 additions and 11 deletions

View File

@ -16,6 +16,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include <unistd.h>
#include "ctrlc.h" #include "ctrlc.h"
#ifdef __Windows__ #ifdef __Windows__

View File

@ -19,6 +19,10 @@
#ifndef CTRLC_H_ #ifndef CTRLC_H_
#define CTRLC_H_ #define CTRLC_H_
#ifdef __Windows__
#include <windows.h>
#endif
/* The Ctrl+C subsystem provides a mechanism for interrupting IO /* The Ctrl+C subsystem provides a mechanism for interrupting IO
* operations in a controlled way. Relevant signals are captured (SIGINT * operations in a controlled way. Relevant signals are captured (SIGINT
* on Linux and console events on Windows) and the event is reported to * on Linux and console events on Windows) and the event is reported to

View File

@ -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) static void emit_ansi(const char *code, int len, int ansi_state, FILE *out)
{ {
#ifdef __Windows__ #ifdef __Windows__
fflush(out); if (is_embedded_mode) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), ansi_state); fwrite(code, 1, len, out);
} else {
fflush(out);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
ansi_state);
}
#else #else
fwrite(code, 1, len, out); fwrite(code, 1, len, out);
#endif #endif

View File

@ -22,6 +22,7 @@
#include "sockets.h" #include "sockets.h"
#include "util.h" #include "util.h"
#include "ctrlc.h"
#ifdef __Windows__ #ifdef __Windows__
#include <windows.h> #include <windows.h>
@ -35,7 +36,6 @@ static void sockets_begin(SOCKET s, DWORD event)
u_long mode = 1; u_long mode = 1;
ioctlsocket(s, FIONBIO, &mode); ioctlsocket(s, FIONBIO, &mode);
ctrlc_reset();
WSAEventSelect(s, ctrlc_win32_event(), event); WSAEventSelect(s, ctrlc_win32_event(), event);
} }

View File

@ -24,6 +24,7 @@
#include "sport.h" #include "sport.h"
#include "util.h" #include "util.h"
#include "output.h" #include "output.h"
#include "ctrlc.h"
#ifdef __linux__ #ifdef __linux__
#include <linux/serial.h> #include <linux/serial.h>
@ -280,7 +281,6 @@ int sport_read(sport_t s, uint8_t *data, int len)
OVERLAPPED ovl = {0}; OVERLAPPED ovl = {0};
ovl.hEvent = ctrlc_win32_event(); ovl.hEvent = ctrlc_win32_event();
ctrlc_reset();
ReadFile(s, (void *)data, len, NULL, &ovl); ReadFile(s, (void *)data, len, NULL, &ovl);
return xfer_wait(s, &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}; OVERLAPPED ovl = {0};
ovl.hEvent = ctrlc_win32_event(); ovl.hEvent = ctrlc_win32_event();
ctrlc_reset();
WriteFile(s, (void *)data, len, NULL, &ovl); WriteFile(s, (void *)data, len, NULL, &ovl);
return xfer_wait(s, &ovl); return xfer_wait(s, &ovl);

View File

@ -74,24 +74,32 @@ static inline void thread_lock_release(thread_lock_t *lock)
LeaveCriticalSection(lock); LeaveCriticalSection(lock);
} }
/* Windows condition variables. */ /* Windows condition variables. These are simulated using kernel event
typedef CONDITION_VARIABLE thread_cond_t; * 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) 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) 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) static inline void thread_cond_notify(thread_cond_t *c)
{ {
WakeConditionVariable(c); SetEvent(*c);
} }
#else /* __Windows__ */ #else /* __Windows__ */