Make DOSVM_Wait work in protected mode.

Replace SHOULD_PEND macro with a function.
This commit is contained in:
Jukka Heinonen 2003-06-16 01:17:30 +00:00 committed by Alexandre Julliard
parent 6551965003
commit 0b79a6e7c3
1 changed files with 44 additions and 7 deletions

View File

@ -91,14 +91,33 @@ static struct _DOSEVENT *pending_event, *current_event;
static int sig_sent; static int sig_sent;
static HANDLE event_notifier; static HANDLE event_notifier;
#define SHOULD_PEND(x) \
(x && ((!current_event) || (x->priority < current_event->priority))) /***********************************************************************
* DOSVM_HasPendingEvents
*
* Return true if there are pending events that are not
* blocked by currently active event.
*/
static BOOL DOSVM_HasPendingEvents( void )
{
if (!pending_event)
return FALSE;
if (!current_event)
return TRUE;
if (pending_event->priority < current_event->priority)
return TRUE;
return FALSE;
}
static void DOSVM_SendQueuedEvent(CONTEXT86 *context) static void DOSVM_SendQueuedEvent(CONTEXT86 *context)
{ {
LPDOSEVENT event = pending_event; LPDOSEVENT event = pending_event;
if (SHOULD_PEND(event)) { if (DOSVM_HasPendingEvents()) {
/* remove from "pending" list */ /* remove from "pending" list */
pending_event = event->next; pending_event = event->next;
/* process event */ /* process event */
@ -118,7 +137,7 @@ static void DOSVM_SendQueuedEvent(CONTEXT86 *context)
free(event); free(event);
} }
} }
if (!SHOULD_PEND(pending_event)) { if (!DOSVM_HasPendingEvents()) {
TRACE("clearing Pending flag\n"); TRACE("clearing Pending flag\n");
CLR_PEND(context); CLR_PEND(context);
} }
@ -268,13 +287,31 @@ static void DOSVM_ProcessMessage(MSG *msg)
*/ */
void WINAPI DOSVM_Wait( CONTEXT86 *waitctx ) void WINAPI DOSVM_Wait( CONTEXT86 *waitctx )
{ {
if (SHOULD_PEND(pending_event)) if (DOSVM_HasPendingEvents())
{ {
/* /*
* FIXME: This does not work in protected mode DOS programs.
* FIXME: Critical section locking is broken. * FIXME: Critical section locking is broken.
*/ */
CONTEXT86 context = *waitctx; CONTEXT86 context = *waitctx;
/*
* If DOSVM_Wait is called from protected mode we emulate
* interrupt reflection and convert context into real mode context.
* This is actually the correct thing to do as long as DOSVM_Wait
* is only called from those interrupt functions that DPMI reflects
* to real mode.
*
* FIXME: Need to think about where to place real mode stack.
* FIXME: If DOSVM_Wait calls are nested stack gets corrupted.
* Can this really happen?
*/
if (!ISV86(&context))
{
context.EFlags |= 0x00020000;
context.SegSs = 0xffff;
context.Esp = 0;
}
IF_SET(&context); IF_SET(&context);
SET_PEND(&context); SET_PEND(&context);
context.SegCs = 0; context.SegCs = 0;
@ -473,7 +510,7 @@ void WINAPI DOSVM_PIC_ioport_out( WORD port, BYTE val)
(*event->relay)(NULL,event->data); (*event->relay)(NULL,event->data);
free(event); free(event);
if (pending_event) { if (DOSVM_HasPendingEvents()) {
/* another event is pending, which we should probably /* another event is pending, which we should probably
* be able to process now */ * be able to process now */
TRACE("another event pending, setting flag\n"); TRACE("another event pending, setting flag\n");