Bug 960894 - 1/4: allow representing multiple clients in one RIL worker. r=bz
authorVicamo Yang <vyang@mozilla.com>
Mon, 17 Feb 2014 19:35:01 +0800
changeset 169135 d01667dc2bc3e399ab3cee50df9405e03085a876
parent 169134 e9055e7476f1e139fe035e6183a45c838e92df39
child 169136 5ddf528d09dff99814c7d9131db2c741d94f1ecc
push id26234
push userphilringnalda@gmail.com
push dateMon, 17 Feb 2014 23:16:21 +0000
treeherdermozilla-central@6b6450d3fbf0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs960894
milestone30.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 960894 - 1/4: allow representing multiple clients in one RIL worker. r=bz
dom/system/gonk/ril_worker.js
ipc/ril/Ril.cpp
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -13903,17 +13903,17 @@ let ICCContactHelper = {
 /**
  * Global stuff.
  */
 
 // Initialize buffers. This is a separate function so that unit tests can
 // re-initialize the buffers at will.
 Buf.init();
 
-function onRILMessage(data) {
+function onRILMessage(/*unused*/aClientId, data) {
   Buf.processIncoming(data);
 }
 
 onmessage = function onmessage(event) {
   RIL.handleChromeMessage(event.data);
 };
 
 onerror = function onerror(event) {
--- a/ipc/ril/Ril.cpp
+++ b/ipc/ril/Ril.cpp
@@ -139,47 +139,69 @@ bool
 ConnectWorkerToRIL::RunTask(JSContext *aCx)
 {
     // Set up the postRILMessage on the function for worker -> RIL thread
     // communication.
     NS_ASSERTION(!NS_IsMainThread(), "Expecting to be on the worker thread");
     NS_ASSERTION(!JS_IsRunning(aCx), "Are we being called somehow?");
     JS::Rooted<JSObject*> workerGlobal(aCx, JS::CurrentGlobalOrNull(aCx));
 
+    // Check whether |postRILMessage| has been defined.  No one but this class
+    // should ever define |postRILMessage| in a RIL worker, so we call to
+    // |JS_LookupProperty| instead of |JS_GetProperty| here.
+    JS::Rooted<JS::Value> val(aCx);
+    if (!JS_LookupProperty(aCx, workerGlobal, "postRILMessage", &val)) {
+        JS_ReportPendingException(aCx);
+        return false;
+    }
+
+    // |JS_LookupProperty| could still return JS_TRUE with an "undefined"
+    // |postRILMessage|, so we have to make sure that with an additional call
+    // to |JS_TypeOfValue|.
+    if (JSTYPE_FUNCTION == JS_TypeOfValue(aCx, val)) {
+        return true;
+    }
+
     return !!JS_DefineFunction(aCx, workerGlobal,
                                "postRILMessage", PostToRIL, 2, 0);
 }
 
 class DispatchRILEvent : public WorkerTask
 {
 public:
-        DispatchRILEvent(UnixSocketRawData* aMessage)
-            : mMessage(aMessage)
+        DispatchRILEvent(unsigned long aClient,
+                         UnixSocketRawData* aMessage)
+            : mClientId(aClient)
+            , mMessage(aMessage)
         { }
 
         virtual bool RunTask(JSContext *aCx);
 
 private:
+        unsigned long mClientId;
         nsAutoPtr<UnixSocketRawData> mMessage;
 };
 
 bool
 DispatchRILEvent::RunTask(JSContext *aCx)
 {
     JS::Rooted<JSObject*> obj(aCx, JS::CurrentGlobalOrNull(aCx));
 
-    JSObject *array = JS_NewUint8Array(aCx, mMessage->mSize);
+    JS::Rooted<JSObject*> array(aCx, JS_NewUint8Array(aCx, mMessage->mSize));
     if (!array) {
         return false;
     }
-    JS::Rooted<JS::Value> arrayVal(aCx, JS::ObjectValue(*array));
+    memcpy(JS_GetArrayBufferViewData(array), mMessage->mData, mMessage->mSize);
 
-    memcpy(JS_GetArrayBufferViewData(array), mMessage->mData, mMessage->mSize);
+    JS::AutoValueArray<2> args(aCx);
+    args[0].setNumber((uint32_t)mClientId);
+    args[1].setObject(*array);
+
     JS::Rooted<JS::Value> rval(aCx);
-    return JS_CallFunctionName(aCx, obj, "onRILMessage", arrayVal, &rval);
+    return JS_CallFunctionName(aCx, obj, "onRILMessage", args, &rval);
 }
 
 class RilConnector : public mozilla::ipc::UnixSocketConnector
 {
 public:
   RilConnector(unsigned long aClientId) : mClientId(aClientId)
   {}
 
@@ -349,17 +371,17 @@ RilConsumer::Shutdown()
     }
 }
 
 void
 RilConsumer::ReceiveSocketData(nsAutoPtr<UnixSocketRawData>& aMessage)
 {
     MOZ_ASSERT(NS_IsMainThread());
 
-    nsRefPtr<DispatchRILEvent> dre(new DispatchRILEvent(aMessage.forget()));
+    nsRefPtr<DispatchRILEvent> dre(new DispatchRILEvent(mClientId, aMessage.forget()));
     mDispatcher->PostTask(dre);
 }
 
 void
 RilConsumer::OnConnectSuccess()
 {
     // Nothing to do here.
     CHROMIUM_LOG("RIL[%lu]: %s\n", mClientId, __FUNCTION__);