[gtk+/gtk-2-24] quartz: Bug 674108 - Hard crash due to wrong NSAutoreleasePool stacking
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/gtk-2-24] quartz: Bug 674108 - Hard crash due to wrong NSAutoreleasePool stacking
- Date: Fri, 14 Sep 2012 13:19:58 +0000 (UTC)
commit 79b3326eaab18b942bd7e03ae8d24544182cb3dd
Author: Michael Natterer <mitch gimp org>
Date: Fri Sep 14 15:18:33 2012 +0200
quartz: Bug 674108 - Hard crash due to wrong NSAutoreleasePool stacking
Apply patch from Kristian Rietveld which addresses two issues
in gdkeventloop-quartz.c:
This patch moves the autorelease pool drain and introduces protection against
the invalidated ufds. Basically, when we suspect ufds has been invalidated by a
recursive main loop instance, we refrain from calling the collect function.
gdk/quartz/gdkeventloop-quartz.c | 45 ++++++++++++++++++++++++-------------
1 files changed, 29 insertions(+), 16 deletions(-)
---
diff --git a/gdk/quartz/gdkeventloop-quartz.c b/gdk/quartz/gdkeventloop-quartz.c
index 97a7e39..224d84c 100644
--- a/gdk/quartz/gdkeventloop-quartz.c
+++ b/gdk/quartz/gdkeventloop-quartz.c
@@ -635,21 +635,6 @@ gdk_event_check (GSource *source)
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
- * (indicated by g_main_depth()). Messing with the autorelease pool at
- * any level of nesting can cause access to deallocated memory because
- * autorelease_pool is static and releasing a pool will cause all pools
- * allocated inside of it to be released as well.
- */
- if (current_loop_level == 0 && g_main_depth() == 0)
- {
- if (autorelease_pool)
- [autorelease_pool drain];
-
- autorelease_pool = [[NSAutoreleasePool alloc] init];
- }
-
retval = (_gdk_event_queue_find_first (_gdk_display) != NULL ||
_gdk_quartz_event_loop_check_pending ());
@@ -667,6 +652,21 @@ gdk_event_dispatch (GSource *source,
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
+ * (indicated by g_main_depth()). Messing with the autorelease pool at
+ * any level of nesting can cause access to deallocated memory because
+ * autorelease_pool is static and releasing a pool will cause all pools
+ * allocated inside of it to be released as well.
+ */
+ if (current_loop_level == 0 && g_main_depth() == 0)
+ {
+ if (autorelease_pool)
+ [autorelease_pool drain];
+
+ autorelease_pool = [[NSAutoreleasePool alloc] init];
+ }
+
_gdk_events_queue (_gdk_display);
event = _gdk_event_unqueue (_gdk_display);
@@ -704,6 +704,10 @@ poll_func (GPollFD *ufds,
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;
@@ -722,7 +726,16 @@ poll_func (GPollFD *ufds,
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 &&
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]