From 92563b7d22f08ce4328fc46447d1b1b0d6a069b1 Mon Sep 17 00:00:00 2001 From: Ronald Bultje Date: Sat, 28 Apr 2007 18:14:19 +0000 Subject: [PATCH] fix two more potential races that could happen when an application is 2007-04-28 Ronald Bultje * gdk/quartz/gdkeventloop-quartz.c: (select_thread_func), (poll_func): fix two more potential races that could happen when an application is polling in the mainloop and a separate thread tries to wake it up using g_idle_add(). Fixes #425271 comment 5. svn path=/trunk/; revision=17680 --- ChangeLog | 7 +++++++ gdk/quartz/gdkeventloop-quartz.c | 16 +++++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index c78af24354..6dbd9b6d30 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2007-04-28 Ronald Bultje + + * gdk/quartz/gdkeventloop-quartz.c: (select_thread_func), + (poll_func): fix two more potential races that could happen when + an application is polling in the mainloop and a separate thread + tries to wake it up using g_idle_add(). Fixes #425271 comment 5. + 2007-04-28 Matthias Clasen * gtk/gtkentry.c (gtk_entry_grab_focus): diff --git a/gdk/quartz/gdkeventloop-quartz.c b/gdk/quartz/gdkeventloop-quartz.c index eb52921b17..d9e9ad85e7 100644 --- a/gdk/quartz/gdkeventloop-quartz.c +++ b/gdk/quartz/gdkeventloop-quartz.c @@ -13,7 +13,7 @@ static NSEvent *current_event; static GPollFunc old_poll_func; -static gboolean select_fd_waiting = FALSE; +static gboolean select_fd_waiting = FALSE, ready_for_poll = FALSE; static pthread_t select_thread = 0; static int wakeup_pipe[2]; static pthread_mutex_t pollfd_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -118,20 +118,23 @@ select_thread_func (void *arg) int n_active_fds; pthread_mutex_lock (&pollfd_mutex); - pthread_cond_signal (&ready_cond); while (1) { char c; int n; + ready_for_poll = TRUE; + pthread_cond_signal (&ready_cond); pthread_cond_wait (&ready_cond, &pollfd_mutex); + ready_for_poll = FALSE; - pthread_mutex_unlock (&pollfd_mutex); select_fd_waiting = TRUE; + pthread_cond_signal (&ready_cond); + pthread_mutex_unlock (&pollfd_mutex); n_active_fds = old_poll_func (pollfds, n_pollfds, -1); - select_fd_waiting = FALSE; pthread_mutex_lock (&pollfd_mutex); + select_fd_waiting = FALSE; n = read (pipe_pollfd->fd, &c, 1); if (n == 1) { @@ -177,10 +180,12 @@ poll_func (GPollFD *ufds, guint nfds, gint timeout_) pthread_mutex_lock (&pollfd_mutex); pthread_create (&select_thread, NULL, select_thread_func, NULL); - pthread_cond_wait (&ready_cond, &pollfd_mutex); } else pthread_mutex_lock (&pollfd_mutex); + while (!ready_for_poll) + pthread_cond_wait (&ready_cond, &pollfd_mutex); + n_pollfds = nfds; g_free (pollfds); pollfds = g_memdup (ufds, sizeof (GPollFD) * nfds); @@ -198,6 +203,7 @@ poll_func (GPollFD *ufds, guint nfds, gint timeout_) /* Start our thread */ pthread_cond_signal (&ready_cond); + pthread_cond_wait (&ready_cond, &pollfd_mutex); pthread_mutex_unlock (&pollfd_mutex); }