[gjs] context: add a private method to schedule a GC if needed



commit b9741e9e8ee3aa546584e559514c5020e7be27e0
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Thu Feb 27 14:03:53 2014 -0800

    context: add a private method to schedule a GC if needed
    
    There's a bit of a roundtrip between jsapi-util.cpp and context.cpp
    here, but we need to save the source ID on GjsContext.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=725099

 gjs/context-private.h |    3 +++
 gjs/context.cpp       |   28 ++++++++++++++++++++++++++++
 gjs/jsapi-private.h   |    3 ++-
 gjs/jsapi-util.cpp    |   16 ++++++++++++++++
 4 files changed, 49 insertions(+), 1 deletions(-)
---
diff --git a/gjs/context-private.h b/gjs/context-private.h
index 313daf9..1d4e6e0 100644
--- a/gjs/context-private.h
+++ b/gjs/context-private.h
@@ -25,11 +25,14 @@
 #define __GJS_CONTEXT_PRIVATE_H__
 
 #include "context.h"
+#include "compat.h"
 
 G_BEGIN_DECLS
 
 gboolean     _gjs_context_destroying                  (GjsContext *js_context);
 
+void         _gjs_context_schedule_gc_if_needed       (GjsContext *js_context);
+
 G_END_DECLS
 
 #endif  /* __GJS_CONTEXT_PRIVATE_H__ */
diff --git a/gjs/context.cpp b/gjs/context.cpp
index 64d651a..ae67489 100644
--- a/gjs/context.cpp
+++ b/gjs/context.cpp
@@ -27,6 +27,7 @@
 
 #include "context-private.h"
 #include "importer.h"
+#include "jsapi-private.h"
 #include "jsapi-util.h"
 #include "native.h"
 #include "byteArray.h"
@@ -68,6 +69,8 @@ struct _GjsContext {
 
     gboolean destroying;
 
+    guint    auto_gc_id;
+
     jsid const_strings[GJS_STRING_LAST];
 };
 
@@ -355,6 +358,11 @@ gjs_context_dispose(GObject *object)
          */
         gjs_object_prepare_shutdown(js_context->context);
 
+        if (js_context->auto_gc_id > 0) {
+            g_source_remove (js_context->auto_gc_id);
+            js_context->auto_gc_id = 0;
+        }
+
         /* Tear down JS */
         JS_DestroyContext(js_context->context);
         js_context->context = NULL;
@@ -525,6 +533,26 @@ _gjs_context_destroying (GjsContext *context)
     return context->destroying;
 }
 
+static gboolean
+trigger_gc_if_needed (gpointer user_data)
+{
+    GjsContext *js_context = GJS_CONTEXT(user_data);
+    js_context->auto_gc_id = 0;
+    gjs_gc_if_needed(js_context->context);
+    return FALSE;
+}
+
+void
+_gjs_context_schedule_gc_if_needed (GjsContext *js_context)
+{
+    if (js_context->auto_gc_id > 0)
+        return;
+
+    js_context->auto_gc_id = g_idle_add_full(G_PRIORITY_LOW,
+                                             trigger_gc_if_needed,
+                                             js_context, NULL);
+}
+
 /**
  * gjs_context_maybe_gc:
  * @context: a #GjsContext
diff --git a/gjs/jsapi-private.h b/gjs/jsapi-private.h
index ca99310..1a604ec 100644
--- a/gjs/jsapi-private.h
+++ b/gjs/jsapi-private.h
@@ -35,7 +35,8 @@
 
 G_BEGIN_DECLS
 
-void gjs_gc_if_needed      (JSContext *context);
+void gjs_schedule_gc_if_needed (JSContext *context);
+void gjs_gc_if_needed          (JSContext *context);
 
 G_END_DECLS
 
diff --git a/gjs/jsapi-util.cpp b/gjs/jsapi-util.cpp
index f4f6c65..53772a8 100644
--- a/gjs/jsapi-util.cpp
+++ b/gjs/jsapi-util.cpp
@@ -31,6 +31,7 @@
 
 #include "jsapi-util.h"
 #include "compat.h"
+#include "context-private.h"
 #include "jsapi-private.h"
 #include <gi/boxed.h>
 
@@ -1222,6 +1223,21 @@ gjs_maybe_gc (JSContext *context)
     gjs_gc_if_needed(context);
 }
 
+void
+gjs_schedule_gc_if_needed (JSContext *context)
+{
+    GjsContext *gjs_context;
+
+    /* We call JS_MaybeGC immediately, but defer a check for a full
+     * GC cycle to an idle handler.
+     */
+    JS_MaybeGC(context);
+
+    gjs_context = (GjsContext *) JS_GetContextPrivate(context);
+    if (gjs_context)
+        _gjs_context_schedule_gc_if_needed(gjs_context);
+}
+
 /**
  * gjs_strip_unix_shebang:
  *


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]