Alexandre Julliard : wineconsole: Don' t use a Win32 wait on a Unix file descriptor.
Alexandre Julliard
julliard at winehq.org
Wed May 7 13:28:09 CDT 2008
Module: wine
Branch: master
Commit: 267d38e1bc78541221d20cc72a759acc78908e8e
URL: http://source.winehq.org/git/wine.git/?a=commit;h=267d38e1bc78541221d20cc72a759acc78908e8e
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed May 7 17:30:00 2008 +0200
wineconsole: Don't use a Win32 wait on a Unix file descriptor.
---
programs/wineconsole/curses.c | 96 ++++++++++++++++++++++-------------------
1 files changed, 51 insertions(+), 45 deletions(-)
diff --git a/programs/wineconsole/curses.c b/programs/wineconsole/curses.c
index 2210cd9..549efb4 100644
--- a/programs/wineconsole/curses.c
+++ b/programs/wineconsole/curses.c
@@ -35,6 +35,9 @@
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
+#ifdef HAVE_POLL_H
+# include <poll.h>
+#endif
#ifdef HAVE_NCURSES_H
# include <ncurses.h>
#elif defined(HAVE_CURSES_H)
@@ -53,7 +56,6 @@
#include "winecon_private.h"
#include "wine/library.h"
-#include "wine/server.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(curses);
@@ -71,7 +73,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(curses);
struct inner_data_curse
{
unsigned long initial_mouse_mask;
- HANDLE hInput;
+ int sync_pipe[2];
+ HANDLE input_thread;
WINDOW* pad;
chtype* line;
int allow_scroll;
@@ -846,31 +849,43 @@ static unsigned WCCURSES_FillCode(struct inner_data* data, INPUT_RECORD* ir, int
}
/******************************************************************
- * WCCURSES_GetEvents
- *
- *
+ * input_thread
*/
-static void WCCURSES_GetEvents(struct inner_data* data)
+static DWORD CALLBACK input_thread( void *arg )
{
+ struct inner_data* data = arg;
int inchar;
INPUT_RECORD ir[8];
unsigned numEvent;
DWORD n;
-
- if ((inchar = wgetch(stdscr)) == ERR) {WINE_FIXME("Ooch. somebody beat us\n");return;}
-
- WINE_TRACE("Got o%o (0x%x)\n", inchar,inchar);
-
- if (inchar >= KEY_MIN && inchar <= KEY_MAX)
- {
- numEvent = WCCURSES_FillCode(data, ir, inchar);
- }
- else
+ struct pollfd pfd[2];
+
+ pfd[0].fd = 0;
+ pfd[0].events = POLLIN;
+ pfd[1].fd = PRIVATE(data)->sync_pipe[0];
+ pfd[1].events = POLLHUP;
+
+ for (;;)
{
- numEvent = WCCURSES_FillSimpleChar(ir, inchar);
+ pfd[0].revents = pfd[1].revents = 0;
+ if (poll( pfd, 2, -1 ) == -1) break;
+ if (pfd[0].revents & (POLLHUP|POLLERR)) break;
+ if (pfd[1].revents & (POLLHUP|POLLERR)) break;
+ if (!(pfd[0].revents & POLLIN)) continue;
+
+ if ((inchar = wgetch(stdscr)) == ERR) continue;
+
+ WINE_TRACE("Got o%o (0x%x)\n", inchar,inchar);
+
+ if (inchar >= KEY_MIN && inchar <= KEY_MAX)
+ numEvent = WCCURSES_FillCode(data, ir, inchar);
+ else
+ numEvent = WCCURSES_FillSimpleChar(ir, inchar);
+
+ if (numEvent) WriteConsoleInput(data->hConIn, ir, numEvent, &n);
}
- if (numEvent)
- WriteConsoleInput(data->hConIn, ir, numEvent, &n);
+ close( PRIVATE(data)->sync_pipe[0] );
+ return 0;
}
/******************************************************************
@@ -882,7 +897,12 @@ static void WCCURSES_DeleteBackend(struct inner_data* data)
{
if (!PRIVATE(data)) return;
- CloseHandle(PRIVATE(data)->hInput);
+ if (PRIVATE(data)->input_thread)
+ {
+ close( PRIVATE(data)->sync_pipe[1] );
+ WaitForSingleObject( PRIVATE(data)->input_thread, INFINITE );
+ CloseHandle( PRIVATE(data)->input_thread );
+ }
delwin(PRIVATE(data)->pad);
#ifdef HAVE_MOUSEMASK
@@ -905,28 +925,21 @@ static void WCCURSES_DeleteBackend(struct inner_data* data)
*/
static int WCCURSES_MainLoop(struct inner_data* data)
{
- HANDLE hin[2];
+ DWORD id;
- hin[0] = PRIVATE(data)->hInput;
- hin[1] = data->hSynchro;
+ if (pipe( PRIVATE(data)->sync_pipe ) == -1) return 0;
+ PRIVATE(data)->input_thread = CreateThread( NULL, 0, input_thread, data, 0, &id );
- for (;;)
+ while (WaitForSingleObject(data->hSynchro, INFINITE) == WAIT_OBJECT_0)
{
- unsigned ret = WaitForMultipleObjects(2, hin, FALSE, INFINITE);
- switch (ret)
- {
- case WAIT_OBJECT_0:
- WCCURSES_GetEvents(data);
- break;
- case WAIT_OBJECT_0+1:
- if (!WINECON_GrabChanges(data)) return 0;
- break;
- default:
- WINE_ERR("got pb\n");
- /* err */
- break;
- }
+ if (!WINECON_GrabChanges(data)) break;
}
+
+ close( PRIVATE(data)->sync_pipe[1] );
+ WaitForSingleObject( PRIVATE(data)->input_thread, INFINITE );
+ CloseHandle( PRIVATE(data)->input_thread );
+ PRIVATE(data)->input_thread = 0;
+ return 0;
}
/******************************************************************
@@ -955,13 +968,6 @@ enum init_return WCCURSES_InitBackend(struct inner_data* data)
data->fnDeleteBackend = WCCURSES_DeleteBackend;
data->hWnd = NULL;
- if (wine_server_fd_to_handle(0, GENERIC_READ|SYNCHRONIZE, 0,
- (obj_handle_t*)&PRIVATE(data)->hInput))
- {
- WINE_FIXME("Cannot open 0\n");
- return init_failed;
- }
-
/* FIXME: should find a good way to enable buffer scrolling
* For the time being, setting this to 1 will allow scrolling up/down
* on buffer with F11/F12.
More information about the wine-cvs
mailing list