Commit bfaf0638 authored by Francis Beaudet's avatar Francis Beaudet Committed by Alexandre Julliard

Order of send message processing was not respected and the message

stacked last finished after the message stacked first.
parent dae09c99
......@@ -686,8 +686,31 @@ static LRESULT MSG_SendMessage( HQUEUE16 hDestQueue, HWND hwnd, UINT msg,
}
}
/*
* Warning: This one looks like a hack but it has a very good reason
* for existing. It will become obsolete once an input task/thread is
* implemented
*
* Normally, once a send message operation is complete, you want to
* clear the wake bit QS_SMRESULT for this queue. However, because of
* the way the 16 bit threads are scheduled, the EVENT_WaitNetEvent
* method might be sending messages using the same message queue as the
* one used for this send message. Since the recipient of that other
* send message is in another thread, it is totally possible that a
* send message operation that occured in time before this one
* has completed it's work before this one does.
* If we clear the wake bit without checking and that operation has
* completed, the send message operation waiting in the call stack
* of the current thread will wait forever.
*/
EnterCriticalSection(&queue->cSection);
if ( (smsg->nextProcessing==0) ||
(( smsg->nextProcessing->flags & SMSG_HAVE_RESULT) == 0 ) )
QUEUE_ClearWakeBit( queue, QS_SMRESULT );
LeaveCriticalSection(&queue->cSection);
/* remove the smsg from the processingg list of the source queue */
QUEUE_RemoveSMSG( queue, SM_PROCESSING_LIST, smsg );
......@@ -773,7 +796,7 @@ BOOL WINAPI ReplyMessage( LRESULT result )
goto ReplyMessageDone;
smsg->lResult = result;
smsg->flags |= SMSG_ALREADY_REPLIED | SMSG_HAVE_RESULT;
smsg->flags |= SMSG_ALREADY_REPLIED;
/* check if it's an early reply (called by the application) or
a regular reply (called by ReceiveMessage) */
......@@ -788,9 +811,15 @@ BOOL WINAPI ReplyMessage( LRESULT result )
if ( !(smsg->flags & SMSG_EARLY_REPLY) )
QUEUE_RemoveSMSG( queue, SM_WAITING_LIST, smsg );
EnterCriticalSection(&senderQ->cSection);
smsg->flags |= SMSG_HAVE_RESULT;
/* tell the sending task that its reply is ready */
QUEUE_SetWakeBit( senderQ, QS_SMRESULT );
LeaveCriticalSection(&senderQ->cSection);
/* switch directly to sending task (16 bit thread only) */
if (THREAD_IsWin16( THREAD_Current() ))
DirectedYield16( senderQ->thdb->teb.htask16 );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment