gtk+ r21030 - in trunk: . gdk/quartz
- From: rhult svn gnome org
- To: svn-commits-list gnome org
- Subject: gtk+ r21030 - in trunk: . gdk/quartz
- Date: Thu, 7 Aug 2008 08:18:32 +0000 (UTC)
Author: rhult
Date: Thu Aug 7 08:18:32 2008
New Revision: 21030
URL: http://svn.gnome.org/viewvc/gtk+?rev=21030&view=rev
Log:
2008-08-07 Richard Hult <richard imendio com>
Bug 535573 â Deadlock in gdkeventloop-quartz.c:poll_func()
* gdk/quartz/gdkeventloop-quartz.c: (gdk_event_prepare),
(select_thread_func), (poll_func): Patch by Yevgen Muntyan, fixes
deadlock and missing events.
Modified:
trunk/ChangeLog
trunk/gdk/quartz/gdkeventloop-quartz.c
Modified: trunk/gdk/quartz/gdkeventloop-quartz.c
==============================================================================
--- trunk/gdk/quartz/gdkeventloop-quartz.c (original)
+++ trunk/gdk/quartz/gdkeventloop-quartz.c Thu Aug 7 08:18:32 2008
@@ -9,7 +9,7 @@
#include "gdkprivate-quartz.h"
static GPollFD event_poll_fd;
-static NSEvent *current_event;
+static GQueue *current_events;
static GPollFunc old_poll_func;
@@ -19,7 +19,6 @@
static pthread_mutex_t pollfd_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t ready_cond = PTHREAD_COND_INITIALIZER;
static GPollFD *pollfds;
-static GPollFD *pipe_pollfd;
static guint n_pollfds;
static CFRunLoopSourceRef select_main_thread_source;
static CFRunLoopRef main_thread_run_loop;
@@ -28,16 +27,16 @@
gboolean
_gdk_quartz_event_loop_check_pending (void)
{
- return current_event != NULL;
+ return current_events && current_events->head;
}
NSEvent*
_gdk_quartz_event_loop_get_pending (void)
{
- NSEvent *event;
+ NSEvent *event = NULL;
- event = current_event;
- current_event = NULL;
+ if (current_events)
+ event = g_queue_pop_tail (current_events);
return event;
}
@@ -65,7 +64,8 @@
dequeue: NO];
retval = (_gdk_event_queue_find_first (_gdk_display) != NULL ||
- event != NULL);
+ (current_events && current_events->head) ||
+ event != NULL);
GDK_THREADS_LEAVE ();
@@ -169,7 +169,7 @@
n_active_fds = old_poll_func (pollfds, n_pollfds, -1);
pthread_mutex_lock (&pollfd_mutex);
select_fd_waiting = FALSE;
- n = read (pipe_pollfd->fd, &c, 1);
+ n = read (wakeup_pipe[0], &c, 1);
if (n == 1)
{
g_assert (c == 'A');
@@ -195,10 +195,11 @@
{
NSEvent *event;
NSDate *limit_date;
+ gboolean poll_event_fd = FALSE;
int n_active = 0;
int i;
- if (nfds > 1)
+ if (nfds > 1 || ufds[0].fd != -1)
{
if (!select_thread) {
/* Create source used for signalling the main thread */
@@ -218,21 +219,32 @@
while (!ready_for_poll)
pthread_cond_wait (&ready_cond, &pollfd_mutex);
- n_pollfds = nfds;
- g_free (pollfds);
- pollfds = g_memdup (ufds, sizeof (GPollFD) * nfds);
+ /* We cheat and use the fake fd (if it's polled) for our pipe */
- /* We cheat and use the fake fd for our pipe */
for (i = 0; i < nfds; i++)
+ if (ufds[i].fd == -1)
+ {
+ poll_event_fd = TRUE;
+ break;
+ }
+
+ g_free (pollfds);
+
+ if (i == nfds)
{
- if (pollfds[i].fd == -1)
- {
- pipe_pollfd = &pollfds[i];
- pollfds[i].fd = wakeup_pipe[0];
- pollfds[i].events = G_IO_IN;
- }
+ n_pollfds = nfds + 1;
+ pollfds = g_new (GPollFD, nfds + 1);
+ memcpy (pollfds, ufds, nfds * sizeof (GPollFD));
+ }
+ else
+ {
+ pollfds = g_memdup (ufds, nfds * sizeof (GPollFD));
+ n_pollfds = nfds;
}
+ pollfds[i].fd = wakeup_pipe[0];
+ pollfds[i].events = G_IO_IN;
+
/* Start our thread */
pthread_cond_signal (&ready_cond);
pthread_cond_wait (&ready_cond, &pollfd_mutex);
@@ -258,7 +270,7 @@
{
pthread_mutex_lock (&pollfd_mutex);
- for (i = 0; i < n_pollfds; i++)
+ for (i = 0; i < nfds; i++)
{
if (ufds[i].fd == -1)
continue;
@@ -275,11 +287,14 @@
pthread_mutex_unlock (&pollfd_mutex);
- event = [NSApp nextEventMatchingMask: NSAnyEventMask
- untilDate: [NSDate distantPast]
- inMode: NSDefaultRunLoopMode
- dequeue: YES];
-
+ /* Try to get a Cocoa event too, if requested */
+ if (poll_event_fd)
+ event = [NSApp nextEventMatchingMask: NSAnyEventMask
+ untilDate: [NSDate distantPast]
+ inMode: NSDefaultRunLoopMode
+ dequeue: YES];
+ else
+ event = NULL;
}
}
@@ -304,7 +319,9 @@
}
}
- current_event = [event retain];
+ if (!current_events)
+ current_events = g_queue_new ();
+ g_queue_push_head (current_events, [event retain]);
n_active ++;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]