#include <unistd.h>
#include "gdkprivate-quartz.h"
+#include <gdk/gdkdisplayprivate.h>
/*
* This file implementations integration between the GLib main loop and
*/
if (!run_loop_polling_async)
CFRunLoopSourceSignal (select_main_thread_source);
-
- if (CFRunLoopIsWaiting (main_thread_run_loop))
- CFRunLoopWakeUp (main_thread_run_loop);
+
+ /* Don't check for CFRunLoopIsWaiting() here because it causes a
+ * race condition (the loop could go into waiting state right after
+ * we checked).
+ */
+ CFRunLoopWakeUp (main_thread_run_loop);
}
static void *
{
gboolean retval;
- GDK_THREADS_ENTER ();
+ gdk_threads_enter ();
*timeout = -1;
- retval = (_gdk_event_queue_find_first (_gdk_display) != NULL ||
- _gdk_quartz_event_loop_check_pending ());
+ if (_gdk_display->event_pause_count > 0)
+ retval = FALSE;
+ else
+ retval = (_gdk_event_queue_find_first (_gdk_display) != NULL ||
+ _gdk_quartz_event_loop_check_pending ());
- GDK_THREADS_LEAVE ();
+ gdk_threads_leave ();
return retval;
}
{
gboolean retval;
- GDK_THREADS_ENTER ();
+ gdk_threads_enter ();
+
+ if (_gdk_display->event_pause_count > 0)
+ retval = FALSE;
+ else
+ retval = (_gdk_event_queue_find_first (_gdk_display) != NULL ||
+ _gdk_quartz_event_loop_check_pending ());
+
+ gdk_threads_leave ();
+
+ return retval;
+}
+
+static gboolean
+gdk_event_dispatch (GSource *source,
+ GSourceFunc callback,
+ gpointer user_data)
+{
+ GdkEvent *event;
+
+ gdk_threads_enter ();
/* Refresh the autorelease pool if we're at the base CFRunLoop level
* (indicated by current_loop_level) and the base g_main_loop level
autorelease_pool = [[NSAutoreleasePool alloc] init];
}
- retval = (_gdk_event_queue_find_first (_gdk_display) != NULL ||
- _gdk_quartz_event_loop_check_pending ());
-
- GDK_THREADS_LEAVE ();
-
- return retval;
-}
-
-static gboolean
-gdk_event_dispatch (GSource *source,
- GSourceFunc callback,
- gpointer user_data)
-{
- GdkEvent *event;
-
- GDK_THREADS_ENTER ();
-
_gdk_quartz_display_queue_events (_gdk_display);
event = _gdk_event_unqueue (_gdk_display);
gdk_event_free (event);
}
- GDK_THREADS_LEAVE ();
+ gdk_threads_leave ();
return TRUE;
}
NSDate *limit_date;
gint n_ready;
+ static GPollFD *last_ufds;
+
+ last_ufds = ufds;
+
n_ready = select_thread_start_poll (ufds, nfds, timeout_);
if (n_ready > 0)
timeout_ = 0;
dequeue: YES];
getting_events--;
- if (n_ready < 0)
+ /* We check if last_ufds did not change since the time this function was
+ * called. It is possible that a recursive main loop (and thus recursive
+ * invocation of this poll function) is triggered while in
+ * nextEventMatchingMask:. If during that time new fds are added,
+ * the cached fds array might be replaced in g_main_context_iterate().
+ * So, we should avoid accessing the old fd array (still pointed at by
+ * ufds) here in that case, since it might have been freed. We avoid this
+ * by not calling the collect stage.
+ */
+ if (last_ufds == ufds && n_ready < 0)
n_ready = select_thread_collect_poll (ufds, nfds);
if (event &&