Handle WAIT_IO_TIMEOUT in WaitAny call
authorGonzalo Paniagua Javier <gonzalo.mono@gmail.com>
Tue, 31 Aug 2010 23:56:47 +0000 (19:56 -0400)
committerGonzalo Paniagua Javier <gonzalo.mono@gmail.com>
Tue, 31 Aug 2010 23:59:27 +0000 (19:59 -0400)
WaitForMultipleObjectsEx might return WAIT_IO_COMPLETION if an APC is queued.
Fixes bug #549807.

mono/metadata/threads.c

index 9b5e2881a84d80c822af683fcf8f254ae25e027c..edbc22173be928392253ec9ece0e6c9570f8cd70 100644 (file)
@@ -1602,6 +1602,7 @@ gint32 ves_icall_System_Threading_WaitHandle_WaitAny_internal(MonoArray *mono_ha
        guint32 i;
        MonoObject *waitHandle;
        MonoInternalThread *thread = mono_thread_internal_current ();
+       guint32 start;
 
        /* Do this WaitSleepJoin check before creating objects */
        mono_thread_current_check_pending_interrupt ();
@@ -1619,8 +1620,21 @@ gint32 ves_icall_System_Threading_WaitHandle_WaitAny_internal(MonoArray *mono_ha
        }
 
        mono_thread_set_state (thread, ThreadState_WaitSleepJoin);
-       
-       ret=WaitForMultipleObjectsEx(numhandles, handles, FALSE, ms, TRUE);
+
+       start = (ms == -1) ? 0 : mono_msec_ticks ();
+       do {
+               ret = WaitForMultipleObjectsEx (numhandles, handles, FALSE, ms, TRUE);
+               if (ret != WAIT_IO_COMPLETION)
+                       break;
+               if (ms != -1) {
+                       guint32 diff;
+
+                       diff = mono_msec_ticks () - start;
+                       ms -= diff;
+                       if (ms <= 0)
+                               break;
+               }
+       } while (ms == -1 || ms > 0);
 
        mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);