Order of send message processing was not respected and the message
stacked last finished after the message stacked first.

diff --git a/windows/message.c b/windows/message.c
index 089b08c..1d4ba1d 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -686,8 +686,31 @@
         }
     }
 
+    /*
+     * 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 @@
         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 @@
     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 );