[gjs] context: Private method to get owner thread



commit c0fdda01d726a1031175c4a562ee645ea9887e70
Author: Philip Chimento <philip endlessm com>
Date:   Tue Mar 7 14:47:33 2017 -0800

    context: Private method to get owner thread
    
    Each JSRuntime has an associated thread, an "owner thread" in
    SpiderMonkey terminology. Most entry points into the JS engine will check
    if the calling thread is the owner thread. Since we need to check if we
    are on the owner thread in order to decide whether to handle toggle refs
    on objects immediately or to defer them to an idle function, we record
    the owner thread when constructing the GjsContext and provide an internal
    method to retrieve it.
    
    This makes it unnecessary to maintain a static pointer to the owner
    thread in object.cpp, which was causing problems because it would not get
    initialized if no custom classes were created.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=779693

 gi/object.cpp         |    5 +----
 gjs/context-private.h |    2 ++
 gjs/context.cpp       |   10 ++++++++++
 3 files changed, 13 insertions(+), 4 deletions(-)
---
diff --git a/gi/object.cpp b/gi/object.cpp
index bd7db75..3ca662b 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -104,7 +104,6 @@ static bool weak_pointer_callback = false;
 static std::set<ObjectInstance *> weak_pointer_list;
 
 extern struct JSClass gjs_object_instance_class;
-static GThread *gjs_eval_thread;
 static volatile gint pending_idle_toggles;
 static std::set<ObjectInstance *> dissociate_list;
 
@@ -1203,7 +1202,7 @@ wrapped_gobj_toggle_notify(gpointer      data,
      * but there aren't many peculiar objects like that and it's
      * not a big deal.
      */
-    is_main_thread = (gjs_eval_thread == g_thread_self());
+    is_main_thread = _gjs_context_get_is_owner_thread(context);
 
     toggle_up_queued = toggle_idle_source_is_queued(gobj, TOGGLE_UP);
     toggle_down_queued = toggle_idle_source_is_queued(gobj, TOGGLE_DOWN);
@@ -2707,8 +2706,6 @@ gjs_object_class_init(GObjectClass *klass,
     klass->set_property = gjs_object_set_gproperty;
     klass->get_property = gjs_object_get_gproperty;
 
-    gjs_eval_thread = g_thread_self();
-
     properties = (GPtrArray*) gjs_hash_table_for_gsize_lookup (class_init_properties, gtype);
     if (properties != NULL) {
         for (i = 0; i < properties->len; i++) {
diff --git a/gjs/context-private.h b/gjs/context-private.h
index 5b24b77..5bbcfa7 100644
--- a/gjs/context-private.h
+++ b/gjs/context-private.h
@@ -37,6 +37,8 @@ void         _gjs_context_schedule_gc_if_needed       (GjsContext *js_context);
 void _gjs_context_exit(GjsContext *js_context,
                        uint8_t     exit_code);
 
+bool _gjs_context_get_is_owner_thread(GjsContext *js_context);
+
 G_END_DECLS
 
 #endif  /* __GJS_CONTEXT_PRIVATE_H__ */
diff --git a/gjs/context.cpp b/gjs/context.cpp
index 08292fb..f0ce8e7 100644
--- a/gjs/context.cpp
+++ b/gjs/context.cpp
@@ -69,6 +69,7 @@ struct _GjsContext {
     JSRuntime *runtime;
     JSContext *context;
     JS::Heap<JSObject*> global;
+    intptr_t owner_thread;
 
     char *program_name;
 
@@ -489,6 +490,9 @@ gjs_context_constructed(GObject *object)
 
     js_context->runtime = gjs_runtime_ref();
 
+    JS_AbortIfWrongThread(js_context->runtime);
+    js_context->owner_thread = JS_GetCurrentThread();
+
     js_context->context = JS_NewContext(js_context->runtime, 8192 /* stack chunk size */);
     if (js_context->context == NULL)
         g_error("Failed to create javascript context");
@@ -661,6 +665,12 @@ context_reset_exit(GjsContext *js_context)
     js_context->exit_code = 0;
 }
 
+bool
+_gjs_context_get_is_owner_thread(GjsContext *js_context)
+{
+    return js_context->owner_thread == JS_GetCurrentThread();
+}
+
 /**
  * gjs_context_maybe_gc:
  * @context: a #GjsContext


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