[gjs] [dbus] Add getCurrentMessageContext, remove old _dbus_sender



commit ed6ee5f54a2da78d068d53fd910857f123eaba96
Author: Colin Walters <walters verbum org>
Date:   Fri Feb 5 13:43:02 2010 -0500

    [dbus] Add getCurrentMessageContext, remove old _dbus_sender
    
    The dbus binding had inconsistent and pretty broken support for
    retrieving the sender of a DBusMessage.  The function
    gjs_js_add_dbus_props, when passed an object, added a _dbus_sender
    property.  However, in many cases it won't be passed an object,
    such as a service method implementation.
    
    There are a number of cases here; the primary ones that we need
    to support are service methods, signals, and asynchronous callbacks.
    
    This patch regresses one case, which is that previously if you
    did a synchronous call that *also* returned multiple values, you
    could access _dbus_sender.  This patch has no support for synchronous
    calls, however there is a workaround - convert them to asynchronous.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=609121

 modules/dbus-exports.c |    5 ++-
 modules/dbus-values.c  |   23 ------------
 modules/dbus-values.h  |    5 +--
 modules/dbus.c         |   93 +++++++++++++++++++++++++++++++++++++++++++++---
 test/js/testDbus.js    |    6 +---
 5 files changed, 94 insertions(+), 38 deletions(-)
---
diff --git a/modules/dbus-exports.c b/modules/dbus-exports.c
index 9978ccd..f407667 100644
--- a/modules/dbus-exports.c
+++ b/modules/dbus-exports.c
@@ -320,11 +320,10 @@ invoke_js_from_dbus(JSContext   *context,
     argc = gjs_rooted_array_get_length(context, values);
     argv = gjs_rooted_array_get_data(context, values);
 
-    gjs_js_add_dbus_props(context, method_call, argv[0]);
-
     rval = JSVAL_VOID;
     JS_AddRoot(context, &rval);
 
+    gjs_js_set_current_message(method_call);
     if (!gjs_call_function_value(context,
                                  this_obj,
                                  OBJECT_TO_JSVAL(method_obj),
@@ -370,6 +369,8 @@ invoke_js_from_dbus(JSContext   *context,
     gjs_rooted_array_free(context, values, TRUE);
     JS_RemoveRoot(context, &rval);
 
+   gjs_js_set_current_message(NULL);
+
     if (reply)
         gjs_debug(GJS_DEBUG_DBUS, "Sending %s reply to dbus method %s",
                   dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_METHOD_RETURN ?
diff --git a/modules/dbus-values.c b/modules/dbus-values.c
index 19a954a..1ddbd79 100644
--- a/modules/dbus-values.c
+++ b/modules/dbus-values.c
@@ -1028,26 +1028,3 @@ gjs_js_values_to_dbus(JSContext         *context,
     return JS_TRUE;
 }
 
-/* If jsval is an object, add properties from the DBusMessage such as the
- * sender. If jsval is not an object, do nothing.
- */
-JSBool
-gjs_js_add_dbus_props(JSContext       *context,
-                      DBusMessage     *message,
-                      jsval            value)
-{
-    const char *sender;
-
-    if (!JSVAL_IS_OBJECT(value))
-        return JS_TRUE;
-
-    sender = dbus_message_get_sender(message);
-
-    if (!JS_DefineProperty(context, JSVAL_TO_OBJECT(value),
-                           "_dbus_sender",
-                           STRING_TO_JSVAL(JS_NewStringCopyZ(context, sender)),
-                           NULL, NULL, JSPROP_ENUMERATE))
-        return JS_FALSE;
-
-    return JS_TRUE;
-}
diff --git a/modules/dbus-values.h b/modules/dbus-values.h
index 2937210..e9ff697 100644
--- a/modules/dbus-values.h
+++ b/modules/dbus-values.h
@@ -43,9 +43,8 @@ JSBool gjs_js_one_value_to_dbus   (JSContext          *context,
                                    jsval               value,
                                    DBusMessageIter    *iter,
                                    DBusSignatureIter  *sig_iter);
-JSBool gjs_js_add_dbus_props      (JSContext          *context,
-                                   DBusMessage        *message,
-                                   jsval               value);
+                                            
+void gjs_js_set_current_message   (DBusMessage        *message);
 
 
 G_END_DECLS
diff --git a/modules/dbus.c b/modules/dbus.c
index 64e112d..9507115 100644
--- a/modules/dbus.c
+++ b/modules/dbus.c
@@ -36,6 +36,12 @@ static DBusConnection *session_bus = NULL;
 static gboolean system_bus_weakref_added = FALSE;
 static DBusConnection *system_bus = NULL;
 
+/* A global not-threadsafe reference to the DBusMessage
+ * currently being processed when invoking a user callback.
+ * Accessible via dbus.currentMessageContext.
+ */
+static DBusMessage *_gjs_current_dbus_message = NULL;
+
 #define DBUS_CONNECTION_FROM_TYPE(type) ((type) == DBUS_BUS_SESSION ? session_bus : system_bus)
 
 static JSBool
@@ -88,6 +94,17 @@ bus_check(JSContext *context, DBusBusType bus_type)
     return JS_TRUE;
 }
 
+void
+gjs_js_set_current_message (DBusMessage        *message)
+{
+  g_assert ((message == NULL && _gjs_current_dbus_message != NULL) ||
+            (message != NULL && _gjs_current_dbus_message == NULL));
+  /* Don't need to take a ref here, if someone forgets to unset the message,
+   * that's a bug.
+   */
+  _gjs_current_dbus_message = message;
+}
+
 static DBusMessage*
 prepare_call(JSContext   *context,
              JSObject    *obj,
@@ -247,8 +264,6 @@ complete_call(JSContext   *context,
      */
     gjs_rooted_array_free(context, ret_values, TRUE);
 
-    gjs_js_add_dbus_props(context, reply, *retval);
-
     return JS_TRUE;
 }
 
@@ -288,12 +303,11 @@ pending_notify(DBusPendingCall *pending,
     /* argv[0] will be the return value if any, argv[1] we fill with exception if any */
     gjs_set_values(context, argv, 2, JSVAL_NULL);
     gjs_root_value_locations(context, argv, 2);
+    gjs_js_set_current_message(reply);
     complete_call(context, &argv[0], reply, &derror);
+    gjs_js_set_current_message(NULL);
     g_assert(!dbus_error_is_set(&derror)); /* not supposed to be left set by complete_call() */
 
-    if (reply)
-        dbus_message_unref(reply);
-
     /* If completing the call failed, we still call the callback, but with null for the reply
      * and an extra arg that is the exception. Kind of odd maybe.
      */
@@ -302,7 +316,12 @@ pending_notify(DBusPendingCall *pending,
         JS_ClearPendingException(context);
     }
 
+    gjs_js_set_current_message(reply);
     gjs_closure_invoke(closure, 2, &argv[0], &discard);
+    gjs_js_set_current_message(NULL);
+    
+    if (reply)
+        dbus_message_unref(reply);
 
     gjs_unroot_value_locations(context, argv, 2);
 
@@ -628,10 +647,12 @@ signal_handler_callback(DBusConnection *connection,
     gjs_debug(GJS_DEBUG_DBUS,
               "Invoking closure on signal received, %d args",
               gjs_rooted_array_get_length(context, arguments));
+    gjs_js_set_current_message(message);
     gjs_closure_invoke(handler->closure,
                        gjs_rooted_array_get_length(context, arguments),
                        gjs_rooted_array_get_data(context, arguments),
                        &ret_val);
+    gjs_js_set_current_message(NULL);
 
     gjs_rooted_array_free(context, arguments, TRUE);
 
@@ -1492,6 +1513,62 @@ gjs_js_dbus_get_machine_id(JSContext *context,
 }
 
 static JSBool
+gjs_js_dbus_get_current_message_context(JSContext  *context,
+                                        JSObject   *obj,
+                                        uintN       argc,
+                                        jsval      *argv,
+                                        jsval      *retval)
+{
+    const char *sender;
+    JSString *sender_str;
+    JSObject *context_obj;
+    jsval context_val;
+    JSBool result = JS_FALSE;
+        
+    if (!gjs_parse_args(context, "getCurrentMessageContext", "", argc, argv))
+        return JS_FALSE;
+
+    if (!_gjs_current_dbus_message) {
+        *retval = JSVAL_NULL;
+        return JS_TRUE;
+    }
+
+    context_obj = JS_ConstructObject(context, NULL, NULL, NULL);
+    if (context_obj == NULL)
+        return JS_FALSE;
+
+    context_val = OBJECT_TO_JSVAL(context_obj);
+    JS_AddRoot(context, &context_val);
+    
+    sender = dbus_message_get_sender(_gjs_current_dbus_message);
+    if (sender)
+        sender_str = JS_NewStringCopyZ(context, sender);
+    else
+        sender_str = NULL;
+
+    if (!JS_DefineProperty(context, context_obj,
+                           "sender",
+                           sender_str ? STRING_TO_JSVAL(sender_str) : JSVAL_NULL,
+                           NULL, NULL,
+                           JSPROP_ENUMERATE))
+        goto out;
+        
+    if (!JS_DefineProperty(context, context_obj,
+                           "serial", INT_TO_JSVAL(dbus_message_get_serial(_gjs_current_dbus_message)),
+                           NULL, NULL,
+                           JSPROP_ENUMERATE))
+        goto out;
+
+    result = JS_TRUE;
+    *retval = context_val;
+
+out:
+    JS_RemoveRoot(context, &context_val);
+    return result;
+}
+
+
+static JSBool
 define_bus_proto(JSContext *context,
                  JSObject *module_obj,
                  JSObject **bus_proto_obj_out)
@@ -1705,6 +1782,12 @@ gjs_js_define_dbus_stuff(JSContext      *context,
                            gjs_js_dbus_get_machine_id, NULL,
                            GJS_MODULE_PROP_FLAGS))
         return JS_FALSE;
+        
+    if (!JS_DefineFunction(context, module_obj,
+                           "getCurrentMessageContext",
+                           gjs_js_dbus_get_current_message_context,
+                           0, GJS_MODULE_PROP_FLAGS))
+        return JS_FALSE;
 
     /* Define both the session and system objects */
     if (!define_bus_proto(context, module_obj, &bus_proto_obj))
diff --git a/test/js/testDbus.js b/test/js/testDbus.js
index a1ed63d..e98df00 100644
--- a/test/js/testDbus.js
+++ b/test/js/testDbus.js
@@ -726,7 +726,6 @@ function testGetAllProperties() {
     assertNotNull(theResult);
     assertTrue('PropReadOnly' in theResult);
     assertTrue('PropReadWrite' in theResult);
-    assertTrue('_dbus_sender' in theResult);
     assertFalse('PropWriteOnly' in theResult);
 
     assertEquals(true,
@@ -738,10 +737,7 @@ function testGetAllProperties() {
     for (let p in theResult) {
         count += 1;
     }
-    // two props plus _dbus_sender
-    // (I think including _dbus_sender is an API bug in our dbus
-    // stuff, but for now some code may rely on it)
-    assertEquals(3, count);
+    assertEquals(2, count);
 }
 
 function testByteArrays() {



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