Bug 814579: connect client socket by id. r=qDot

This commit is contained in:
Vicamo Yang 2013-02-02 13:06:27 +08:00
Родитель f8ab8f1ffe
Коммит 0b69ea42e6
7 изменённых файлов: 85 добавлений и 27 удалений

Просмотреть файл

@ -331,7 +331,7 @@ function RadioInterfaceLayer() {
this.worker.postMessage({rilMessageType: "setDebugEnabled",
enabled: debugPref});
gSystemWorkerManager.registerRilWorker(this.worker);
gSystemWorkerManager.registerRilWorker(0, this.worker);
}
RadioInterfaceLayer.prototype = {

Просмотреть файл

@ -60,26 +60,35 @@ SystemWorkerManager *gInstance = nullptr;
class ConnectWorkerToRIL : public WorkerTask
{
const unsigned long mClientId;
public:
ConnectWorkerToRIL(unsigned long aClientId)
: mClientId(aClientId)
{ }
virtual bool RunTask(JSContext *aCx);
};
class SendRilSocketDataTask : public nsRunnable
{
public:
SendRilSocketDataTask(UnixSocketRawData *aRawData)
SendRilSocketDataTask(unsigned long aClientId,
UnixSocketRawData *aRawData)
: mRawData(aRawData)
, mClientId(aClientId)
{ }
NS_IMETHOD Run()
{
MOZ_ASSERT(NS_IsMainThread());
SystemWorkerManager::SendRilRawData(mRawData);
SystemWorkerManager::SendRilRawData(mClientId, mRawData);
return NS_OK;
}
private:
UnixSocketRawData *mRawData;
unsigned long mClientId;
};
JSBool
@ -87,12 +96,15 @@ PostToRIL(JSContext *cx, unsigned argc, jsval *vp)
{
NS_ASSERTION(!NS_IsMainThread(), "Expecting to be on the worker thread");
if (argc != 1) {
JS_ReportError(cx, "Expecting a single argument with the RIL message");
if (argc != 2) {
JS_ReportError(cx, "Expecting two arguments with the RIL message");
return false;
}
jsval v = JS_ARGV(cx, vp)[0];
jsval cv = JS_ARGV(cx, vp)[0];
int clientId = cv.toInt32();
jsval v = JS_ARGV(cx, vp)[1];
JSAutoByteString abs;
void *data;
@ -131,7 +143,7 @@ PostToRIL(JSContext *cx, unsigned argc, jsval *vp)
UnixSocketRawData* raw = new UnixSocketRawData(size);
memcpy(raw->mData, data, raw->mSize);
nsRefPtr<SendRilSocketDataTask> task = new SendRilSocketDataTask(raw);
nsRefPtr<SendRilSocketDataTask> task = new SendRilSocketDataTask(clientId, raw);
NS_DispatchToMainThread(task);
return true;
}
@ -145,6 +157,11 @@ ConnectWorkerToRIL::RunTask(JSContext *aCx)
NS_ASSERTION(!JS_IsRunning(aCx), "Are we being called somehow?");
JSObject *workerGlobal = JS_GetGlobalObject(aCx);
if (!JS_DefineProperty(aCx, workerGlobal, "CLIENT_ID",
INT_TO_JSVAL(mClientId), nullptr, nullptr, 0)) {
return false;
}
return !!JS_DefineFunction(aCx, workerGlobal, "postRILMessage", PostToRIL, 1,
0);
}
@ -373,9 +390,11 @@ SystemWorkerManager::Shutdown()
ShutdownAutoMounter();
#endif
if (mRilConsumer) {
mRilConsumer->Shutdown();
mRilConsumer = nullptr;
for (unsigned long i = 0; i < mRilConsumers.Length(); i++) {
if (mRilConsumers[i]) {
mRilConsumers[i]->Shutdown();
mRilConsumers[i] = nullptr;
}
}
#ifdef MOZ_WIDGET_GONK
@ -426,14 +445,16 @@ SystemWorkerManager::GetInterfaceRequestor()
}
bool
SystemWorkerManager::SendRilRawData(UnixSocketRawData* aRaw)
SystemWorkerManager::SendRilRawData(unsigned long aClientId,
UnixSocketRawData* aRaw)
{
if (!gInstance->mRilConsumer) {
if ((gInstance->mRilConsumers.Length() <= aClientId) ||
!gInstance->mRilConsumers[aClientId]) {
// Probably shuting down.
delete aRaw;
return true;
}
return gInstance->mRilConsumer->SendSocketData(aRaw);
return gInstance->mRilConsumers[aClientId]->SendSocketData(aRaw);
}
NS_IMETHODIMP
@ -458,27 +479,40 @@ SystemWorkerManager::GetInterface(const nsIID &aIID, void **aResult)
}
nsresult
SystemWorkerManager::RegisterRilWorker(const JS::Value& aWorker,
SystemWorkerManager::RegisterRilWorker(unsigned int aClientId,
const JS::Value& aWorker,
JSContext *aCx)
{
NS_ENSURE_TRUE(!JSVAL_IS_PRIMITIVE(aWorker), NS_ERROR_UNEXPECTED);
if (!mRilConsumers.EnsureLengthAtLeast(aClientId + 1)) {
NS_WARNING("Failed to ensure minimum length of mRilConsumers");
return NS_ERROR_FAILURE;
}
if (mRilConsumers[aClientId]) {
NS_WARNING("RilConsumer already registered");
return NS_ERROR_FAILURE;
}
JSAutoRequest ar(aCx);
JSAutoCompartment ac(aCx, JSVAL_TO_OBJECT(aWorker));
WorkerCrossThreadDispatcher *wctd =
GetWorkerCrossThreadDispatcher(aCx, aWorker);
if (!wctd) {
NS_WARNING("Failed to GetWorkerCrossThreadDispatcher for ril");
return NS_ERROR_FAILURE;
}
nsRefPtr<ConnectWorkerToRIL> connection = new ConnectWorkerToRIL();
nsRefPtr<ConnectWorkerToRIL> connection = new ConnectWorkerToRIL(aClientId);
if (!wctd->PostTask(connection)) {
NS_WARNING("Failed to connect worker to ril");
return NS_ERROR_UNEXPECTED;
}
// Now that we're set up, connect ourselves to the RIL thread.
mRilConsumer = new RilConsumer(wctd);
mRilConsumers[aClientId] = new RilConsumer(aClientId, wctd);
return NS_OK;
}
@ -500,7 +534,7 @@ SystemWorkerManager::InitNetd(JSContext *cx)
WorkerCrossThreadDispatcher *wctd =
GetWorkerCrossThreadDispatcher(cx, workerval);
if (!wctd) {
NS_WARNING("Failed to GetWorkerCrossThreadDispatcher");
NS_WARNING("Failed to GetWorkerCrossThreadDispatcher for netd");
return NS_ERROR_FAILURE;
}

Просмотреть файл

@ -59,7 +59,8 @@ public:
static nsIInterfaceRequestor*
GetInterfaceRequestor();
static bool SendRilRawData(ipc::UnixSocketRawData* aRaw);
static bool SendRilRawData(unsigned long aClientId,
ipc::UnixSocketRawData* aRaw);
private:
SystemWorkerManager();
@ -75,7 +76,7 @@ private:
#endif
nsCOMPtr<nsIWorkerHolder> mWifiWorker;
nsRefPtr<ipc::RilConsumer> mRilConsumer;
nsTArray<nsRefPtr<ipc::RilConsumer> > mRilConsumers;
bool mShutdown;
};

Просмотреть файл

@ -11,5 +11,6 @@
interface nsISystemWorkerManager : nsISupports
{
[implicit_jscontext]
void registerRilWorker(in jsval aWorker);
void registerRilWorker(in unsigned long aClientId,
in jsval aWorker);
};

Просмотреть файл

@ -693,7 +693,7 @@ let Buf = {
// right away!
let parcel = this.outgoingBytes.subarray(0, this.outgoingIndex);
if (DEBUG) debug("Outgoing parcel: " + Array.slice(parcel));
postRILMessage(parcel);
postRILMessage(CLIENT_ID, parcel);
this.outgoingIndex = PARCEL_SIZE_SIZE;
},
@ -9950,7 +9950,7 @@ let ICCContactHelper = {
if (!this.debug) {
// Debugging stub that goes nowhere.
this.debug = function debug(message) {
dump("RIL Worker: " + message + "\n");
dump("RIL Worker[" + CLIENT_ID + "]: " + message + "\n");
};
}

Просмотреть файл

@ -63,6 +63,9 @@ DispatchRILEvent::RunTask(JSContext *aCx)
class RilConnector : public mozilla::ipc::UnixSocketConnector
{
public:
RilConnector(unsigned long aClientId) : mClientId(aClientId)
{}
virtual ~RilConnector()
{}
@ -74,6 +77,9 @@ public:
virtual bool SetUp(int aFd);
virtual void GetSocketAddr(const sockaddr& aAddr,
nsAString& aAddrStr);
private:
unsigned long mClientId;
};
int
@ -134,7 +140,7 @@ RilConnector::CreateAddr(bool aIsServer,
memset(&addr_in, 0, sizeof(addr_in));
addr_in.sin_family = hp->h_addrtype;
addr_in.sin_port = htons(RIL_TEST_PORT);
addr_in.sin_port = htons(RIL_TEST_PORT + mClientId);
memcpy(&addr_in.sin_addr, hp->h_addr, hp->h_length);
aAddrSize = sizeof(addr_in);
@ -162,11 +168,24 @@ RilConnector::GetSocketAddr(const sockaddr& aAddr,
namespace mozilla {
namespace ipc {
RilConsumer::RilConsumer(WorkerCrossThreadDispatcher* aDispatcher)
RilConsumer::RilConsumer(unsigned long aClientId,
WorkerCrossThreadDispatcher* aDispatcher)
: mDispatcher(aDispatcher)
, mClientId(aClientId)
, mShutdown(false)
{
ConnectSocket(new RilConnector(), RIL_SOCKET_NAME);
// Only append client id after RIL_SOCKET_NAME when it's not connected to
// the first(0) rilproxy for compatibility.
if (!aClientId) {
mAddress = RIL_SOCKET_NAME;
} else {
struct sockaddr_un addr_un;
snprintf(addr_un.sun_path, sizeof addr_un.sun_path, "%s%lu",
RIL_SOCKET_NAME, aClientId);
mAddress = addr_un.sun_path;
}
ConnectSocket(new RilConnector(mClientId), mAddress.get());
}
void
@ -204,7 +223,7 @@ RilConsumer::OnDisconnect()
{
LOG("%s\n", __FUNCTION__);
if (!mShutdown) {
ConnectSocket(new RilConnector(), RIL_SOCKET_NAME, 1000);
ConnectSocket(new RilConnector(mClientId), mAddress.get(), 1000);
}
}

Просмотреть файл

@ -16,7 +16,8 @@ namespace ipc {
class RilConsumer : public mozilla::ipc::UnixSocketConsumer
{
public:
RilConsumer(mozilla::dom::workers::WorkerCrossThreadDispatcher* aDispatcher);
RilConsumer(unsigned long aClientId,
mozilla::dom::workers::WorkerCrossThreadDispatcher* aDispatcher);
virtual ~RilConsumer() { }
void Shutdown();
@ -30,6 +31,8 @@ private:
private:
nsRefPtr<mozilla::dom::workers::WorkerCrossThreadDispatcher> mDispatcher;
unsigned long mClientId;
nsCString mAddress;
bool mShutdown;
};