+
+ events = g_new0 (gpointer, wait->num);
+ waitnum = 0;
+ /* Get the suspended events that we'll be waiting for */
+ for (i = 0; i < wait->num; ++i) {
+ MonoThread *thread = wait->threads [i];
+
+ if ((thread->tid == self) || mono_gc_is_finalizer_thread (thread)) {
+ //CloseHandle (wait->handles [i]);
+ wait->threads [i] = NULL; /* ignore this thread in next loop */
+ continue;
+ }
+
+ mono_monitor_enter (thread->synch_lock);
+
+ if ((thread->state & ThreadState_Suspended) != 0 ||
+ (thread->state & ThreadState_SuspendRequested) != 0 ||
+ (thread->state & ThreadState_StopRequested) != 0 ||
+ (thread->state & ThreadState_Stopped) != 0) {
+ mono_monitor_exit (thread->synch_lock);
+ CloseHandle (wait->handles [i]);
+ wait->threads [i] = NULL; /* ignore this thread in next loop */
+ continue;
+ }
+
+ /* Convert abort requests into suspend requests */
+ if ((thread->state & ThreadState_AbortRequested) != 0)
+ thread->state &= ~ThreadState_AbortRequested;
+
+ thread->state |= ThreadState_SuspendRequested;
+
+ if (thread->suspended_event == NULL)
+ thread->suspended_event = CreateEvent (NULL, TRUE, FALSE, NULL);
+
+ events [eventidx++] = thread->suspended_event;
+ mono_monitor_exit (thread->synch_lock);
+
+ /* Signal the thread to suspend */
+ signal_thread_state_change (thread);
+ }
+
+ WaitForMultipleObjectsEx (eventidx, events, TRUE, INFINITE, FALSE);
+ for (i = 0; i < wait->num; ++i) {
+ MonoThread *thread = wait->threads [i];
+
+ if (thread == NULL)
+ continue;
+
+ mono_monitor_enter (thread->synch_lock);
+ CloseHandle (thread->suspended_event);
+ thread->suspended_event = NULL;
+ mono_monitor_exit (thread->synch_lock);
+ }
+
+ g_free (events);
+ g_free (wait);