forked from AuroraMiddleware/gtk
Bug 535573 – Deadlock in gdkeventloop-quartz.c:poll_func()
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. svn path=/trunk/; revision=21030
This commit is contained in:
parent
e7d1152a8e
commit
cc127bf0a9
@ -1,3 +1,11 @@
|
|||||||
|
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.
|
||||||
|
|
||||||
2008-08-07 Richard Hult <richard@imendio.com>
|
2008-08-07 Richard Hult <richard@imendio.com>
|
||||||
|
|
||||||
* gdk/quartz/gdkscreen-quartz.c: (gdk_screen_get_monitor_plug_name)
|
* gdk/quartz/gdkscreen-quartz.c: (gdk_screen_get_monitor_plug_name)
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#include "gdkprivate-quartz.h"
|
#include "gdkprivate-quartz.h"
|
||||||
|
|
||||||
static GPollFD event_poll_fd;
|
static GPollFD event_poll_fd;
|
||||||
static NSEvent *current_event;
|
static GQueue *current_events;
|
||||||
|
|
||||||
static GPollFunc old_poll_func;
|
static GPollFunc old_poll_func;
|
||||||
|
|
||||||
@ -19,7 +19,6 @@ static int wakeup_pipe[2];
|
|||||||
static pthread_mutex_t pollfd_mutex = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t pollfd_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
static pthread_cond_t ready_cond = PTHREAD_COND_INITIALIZER;
|
static pthread_cond_t ready_cond = PTHREAD_COND_INITIALIZER;
|
||||||
static GPollFD *pollfds;
|
static GPollFD *pollfds;
|
||||||
static GPollFD *pipe_pollfd;
|
|
||||||
static guint n_pollfds;
|
static guint n_pollfds;
|
||||||
static CFRunLoopSourceRef select_main_thread_source;
|
static CFRunLoopSourceRef select_main_thread_source;
|
||||||
static CFRunLoopRef main_thread_run_loop;
|
static CFRunLoopRef main_thread_run_loop;
|
||||||
@ -28,16 +27,16 @@ static NSAutoreleasePool *autorelease_pool;
|
|||||||
gboolean
|
gboolean
|
||||||
_gdk_quartz_event_loop_check_pending (void)
|
_gdk_quartz_event_loop_check_pending (void)
|
||||||
{
|
{
|
||||||
return current_event != NULL;
|
return current_events && current_events->head;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSEvent*
|
NSEvent*
|
||||||
_gdk_quartz_event_loop_get_pending (void)
|
_gdk_quartz_event_loop_get_pending (void)
|
||||||
{
|
{
|
||||||
NSEvent *event;
|
NSEvent *event = NULL;
|
||||||
|
|
||||||
event = current_event;
|
if (current_events)
|
||||||
current_event = NULL;
|
event = g_queue_pop_tail (current_events);
|
||||||
|
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
@ -65,6 +64,7 @@ gdk_event_prepare (GSource *source,
|
|||||||
dequeue: NO];
|
dequeue: NO];
|
||||||
|
|
||||||
retval = (_gdk_event_queue_find_first (_gdk_display) != NULL ||
|
retval = (_gdk_event_queue_find_first (_gdk_display) != NULL ||
|
||||||
|
(current_events && current_events->head) ||
|
||||||
event != NULL);
|
event != NULL);
|
||||||
|
|
||||||
GDK_THREADS_LEAVE ();
|
GDK_THREADS_LEAVE ();
|
||||||
@ -169,7 +169,7 @@ select_thread_func (void *arg)
|
|||||||
n_active_fds = old_poll_func (pollfds, n_pollfds, -1);
|
n_active_fds = old_poll_func (pollfds, n_pollfds, -1);
|
||||||
pthread_mutex_lock (&pollfd_mutex);
|
pthread_mutex_lock (&pollfd_mutex);
|
||||||
select_fd_waiting = FALSE;
|
select_fd_waiting = FALSE;
|
||||||
n = read (pipe_pollfd->fd, &c, 1);
|
n = read (wakeup_pipe[0], &c, 1);
|
||||||
if (n == 1)
|
if (n == 1)
|
||||||
{
|
{
|
||||||
g_assert (c == 'A');
|
g_assert (c == 'A');
|
||||||
@ -195,10 +195,11 @@ poll_func (GPollFD *ufds, guint nfds, gint timeout_)
|
|||||||
{
|
{
|
||||||
NSEvent *event;
|
NSEvent *event;
|
||||||
NSDate *limit_date;
|
NSDate *limit_date;
|
||||||
|
gboolean poll_event_fd = FALSE;
|
||||||
int n_active = 0;
|
int n_active = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (nfds > 1)
|
if (nfds > 1 || ufds[0].fd != -1)
|
||||||
{
|
{
|
||||||
if (!select_thread) {
|
if (!select_thread) {
|
||||||
/* Create source used for signalling the main thread */
|
/* Create source used for signalling the main thread */
|
||||||
@ -218,20 +219,31 @@ poll_func (GPollFD *ufds, guint nfds, gint timeout_)
|
|||||||
while (!ready_for_poll)
|
while (!ready_for_poll)
|
||||||
pthread_cond_wait (&ready_cond, &pollfd_mutex);
|
pthread_cond_wait (&ready_cond, &pollfd_mutex);
|
||||||
|
|
||||||
n_pollfds = nfds;
|
/* We cheat and use the fake fd (if it's polled) for our pipe */
|
||||||
g_free (pollfds);
|
|
||||||
pollfds = g_memdup (ufds, sizeof (GPollFD) * nfds);
|
|
||||||
|
|
||||||
/* We cheat and use the fake fd for our pipe */
|
|
||||||
for (i = 0; i < nfds; i++)
|
for (i = 0; i < nfds; i++)
|
||||||
|
if (ufds[i].fd == -1)
|
||||||
{
|
{
|
||||||
if (pollfds[i].fd == -1)
|
poll_event_fd = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (pollfds);
|
||||||
|
|
||||||
|
if (i == nfds)
|
||||||
{
|
{
|
||||||
pipe_pollfd = &pollfds[i];
|
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].fd = wakeup_pipe[0];
|
||||||
pollfds[i].events = G_IO_IN;
|
pollfds[i].events = G_IO_IN;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Start our thread */
|
/* Start our thread */
|
||||||
pthread_cond_signal (&ready_cond);
|
pthread_cond_signal (&ready_cond);
|
||||||
@ -258,7 +270,7 @@ poll_func (GPollFD *ufds, guint nfds, gint timeout_)
|
|||||||
{
|
{
|
||||||
pthread_mutex_lock (&pollfd_mutex);
|
pthread_mutex_lock (&pollfd_mutex);
|
||||||
|
|
||||||
for (i = 0; i < n_pollfds; i++)
|
for (i = 0; i < nfds; i++)
|
||||||
{
|
{
|
||||||
if (ufds[i].fd == -1)
|
if (ufds[i].fd == -1)
|
||||||
continue;
|
continue;
|
||||||
@ -275,11 +287,14 @@ poll_func (GPollFD *ufds, guint nfds, gint timeout_)
|
|||||||
|
|
||||||
pthread_mutex_unlock (&pollfd_mutex);
|
pthread_mutex_unlock (&pollfd_mutex);
|
||||||
|
|
||||||
|
/* Try to get a Cocoa event too, if requested */
|
||||||
|
if (poll_event_fd)
|
||||||
event = [NSApp nextEventMatchingMask: NSAnyEventMask
|
event = [NSApp nextEventMatchingMask: NSAnyEventMask
|
||||||
untilDate: [NSDate distantPast]
|
untilDate: [NSDate distantPast]
|
||||||
inMode: NSDefaultRunLoopMode
|
inMode: NSDefaultRunLoopMode
|
||||||
dequeue: YES];
|
dequeue: YES];
|
||||||
|
else
|
||||||
|
event = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,7 +319,9 @@ poll_func (GPollFD *ufds, guint nfds, gint timeout_)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
current_event = [event retain];
|
if (!current_events)
|
||||||
|
current_events = g_queue_new ();
|
||||||
|
g_queue_push_head (current_events, [event retain]);
|
||||||
|
|
||||||
n_active ++;
|
n_active ++;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user