зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 6 changesets (bug 1171994) for causing smoketest bustage. a=me
Backed out changeset 46061230e77a (bug 1171994) Backed out changeset ea00769b70df (bug 1171994) Backed out changeset 2dc847e4650c (bug 1171994) Backed out changeset 14ec8c87f973 (bug 1171994) Backed out changeset 31cdbef9fe22 (bug 1171994) Backed out changeset 463528fcee4d (bug 1171994)
This commit is contained in:
Родитель
e2c91f7727
Коммит
4e75963b27
|
@ -119,7 +119,7 @@ SystemWorkerManager::Shutdown()
|
||||||
ShutdownAutoMounter();
|
ShutdownAutoMounter();
|
||||||
|
|
||||||
#ifdef MOZ_B2G_RIL
|
#ifdef MOZ_B2G_RIL
|
||||||
RilWorker::Shutdown();
|
RilConsumer::Shutdown();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nsCOMPtr<nsIWifi> wifi(do_QueryInterface(mWifiWorker));
|
nsCOMPtr<nsIWifi> wifi(do_QueryInterface(mWifiWorker));
|
||||||
|
@ -201,7 +201,7 @@ SystemWorkerManager::RegisterRilWorker(unsigned int aClientId,
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RilWorker::Register(aClientId, wctd);
|
return RilConsumer::Register(aClientId, wctd);
|
||||||
#endif // MOZ_B2G_RIL
|
#endif // MOZ_B2G_RIL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
527
ipc/ril/Ril.cpp
527
ipc/ril/Ril.cpp
|
@ -5,22 +5,13 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "mozilla/ipc/Ril.h"
|
#include "mozilla/ipc/Ril.h"
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include "jsfriendapi.h"
|
#include <netdb.h> // For gethostbyname.
|
||||||
#include "mozilla/ArrayUtils.h"
|
|
||||||
#include "mozilla/dom/ScriptSettings.h"
|
|
||||||
#include "mozilla/dom/workers/Workers.h"
|
|
||||||
#include "mozilla/ipc/RilSocket.h"
|
|
||||||
#include "mozilla/ipc/RilSocketConsumer.h"
|
|
||||||
#include "nsThreadUtils.h" // For NS_IsMainThread.
|
|
||||||
#include "RilConnector.h"
|
|
||||||
|
|
||||||
#ifdef CHROMIUM_LOG
|
|
||||||
#undef CHROMIUM_LOG
|
#undef CHROMIUM_LOG
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MOZ_WIDGET_GONK)
|
#if defined(MOZ_WIDGET_GONK)
|
||||||
#include <android/log.h>
|
#include <android/log.h>
|
||||||
#define CHROMIUM_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk", args)
|
#define CHROMIUM_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk", args)
|
||||||
|
@ -28,95 +19,189 @@
|
||||||
#define CHROMIUM_LOG(args...) printf(args);
|
#define CHROMIUM_LOG(args...) printf(args);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace mozilla {
|
#include "jsfriendapi.h"
|
||||||
namespace ipc {
|
#include "mozilla/ArrayUtils.h"
|
||||||
|
#include "nsTArray.h"
|
||||||
|
#include "nsThreadUtils.h" // For NS_IsMainThread.
|
||||||
|
#include "RilConnector.h"
|
||||||
|
|
||||||
USING_WORKERS_NAMESPACE;
|
USING_WORKERS_NAMESPACE
|
||||||
using namespace JS;
|
using namespace mozilla::ipc;
|
||||||
|
|
||||||
class RilConsumer;
|
namespace {
|
||||||
|
|
||||||
static const char RIL_SOCKET_NAME[] = "/dev/socket/rilproxy";
|
static const char RIL_SOCKET_NAME[] = "/dev/socket/rilproxy";
|
||||||
|
|
||||||
static nsTArray<nsAutoPtr<RilConsumer>> sRilConsumers;
|
static nsTArray<nsAutoPtr<mozilla::ipc::RilConsumer>> sRilConsumers;
|
||||||
|
|
||||||
//
|
class ConnectWorkerToRIL final : public WorkerTask
|
||||||
// RilConsumer
|
|
||||||
//
|
|
||||||
|
|
||||||
class RilConsumer final : public RilSocketConsumer
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RilConsumer();
|
bool RunTask(JSContext* aCx) override;
|
||||||
|
|
||||||
nsresult ConnectWorkerToRIL(JSContext* aCx);
|
|
||||||
|
|
||||||
nsresult Register(unsigned long aClientId,
|
|
||||||
WorkerCrossThreadDispatcher* aDispatcher);
|
|
||||||
void Unregister();
|
|
||||||
|
|
||||||
// Methods for |RilSocketConsumer|
|
|
||||||
//
|
|
||||||
|
|
||||||
void ReceiveSocketData(JSContext* aCx,
|
|
||||||
int aIndex,
|
|
||||||
nsAutoPtr<UnixSocketBuffer>& aBuffer) override;
|
|
||||||
void OnConnectSuccess(int aIndex) override;
|
|
||||||
void OnConnectError(int aIndex) override;
|
|
||||||
void OnDisconnect(int aIndex) override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
static bool PostRILMessage(JSContext* aCx, unsigned aArgc, Value* aVp);
|
|
||||||
|
|
||||||
nsresult Send(JSContext* aCx, const CallArgs& aArgs);
|
|
||||||
nsresult Receive(JSContext* aCx,
|
|
||||||
uint32_t aClientId,
|
|
||||||
const UnixSocketBuffer* aBuffer);
|
|
||||||
void Close();
|
|
||||||
|
|
||||||
private:
|
|
||||||
nsRefPtr<RilSocket> mSocket;
|
|
||||||
nsCString mAddress;
|
|
||||||
bool mShutdown;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
RilConsumer::RilConsumer()
|
class SendRilSocketDataTask final : public nsRunnable
|
||||||
: mShutdown(false)
|
{
|
||||||
{ }
|
public:
|
||||||
|
SendRilSocketDataTask(unsigned long aClientId,
|
||||||
|
UnixSocketRawData* aRawData)
|
||||||
|
: mRawData(aRawData)
|
||||||
|
, mClientId(aClientId)
|
||||||
|
{ }
|
||||||
|
|
||||||
nsresult
|
NS_IMETHOD Run() override
|
||||||
RilConsumer::ConnectWorkerToRIL(JSContext* aCx)
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
if (sRilConsumers.Length() <= mClientId || !sRilConsumers[mClientId]) {
|
||||||
|
// Probably shutting down.
|
||||||
|
delete mRawData;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
sRilConsumers[mClientId]->Send(mRawData);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
UnixSocketRawData* mRawData;
|
||||||
|
unsigned long mClientId;
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool
|
||||||
|
PostToRIL(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
|
||||||
|
{
|
||||||
|
JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Expecting to be on the worker thread");
|
||||||
|
|
||||||
|
if (args.length() != 2) {
|
||||||
|
JS_ReportError(aCx, "Expecting two arguments with the RIL message");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int clientId = args[0].toInt32();
|
||||||
|
JS::Value v = args[1];
|
||||||
|
|
||||||
|
UnixSocketRawData* raw = nullptr;
|
||||||
|
|
||||||
|
if (v.isString()) {
|
||||||
|
JSAutoByteString abs;
|
||||||
|
JS::Rooted<JSString*> str(aCx, v.toString());
|
||||||
|
if (!abs.encodeUtf8(aCx, str)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
raw = new UnixSocketRawData(abs.ptr(), abs.length());
|
||||||
|
} else if (!v.isPrimitive()) {
|
||||||
|
JSObject* obj = v.toObjectOrNull();
|
||||||
|
if (!JS_IsTypedArrayObject(obj)) {
|
||||||
|
JS_ReportError(aCx, "Object passed in wasn't a typed array");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t type = JS_GetArrayBufferViewType(obj);
|
||||||
|
if (type != js::Scalar::Int8 &&
|
||||||
|
type != js::Scalar::Uint8 &&
|
||||||
|
type != js::Scalar::Uint8Clamped) {
|
||||||
|
JS_ReportError(aCx, "Typed array data is not octets");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
JS::AutoCheckCannotGC nogc;
|
||||||
|
size_t size = JS_GetTypedArrayByteLength(obj);
|
||||||
|
void* data = JS_GetArrayBufferViewData(obj, nogc);
|
||||||
|
raw = new UnixSocketRawData(data, size);
|
||||||
|
} else {
|
||||||
|
JS_ReportError(
|
||||||
|
aCx, "Incorrect argument. Expecting a string or a typed array");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!raw) {
|
||||||
|
JS_ReportError(aCx, "Unable to post to RIL");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<SendRilSocketDataTask> task = new SendRilSocketDataTask(clientId,
|
||||||
|
raw);
|
||||||
|
NS_DispatchToMainThread(task);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ConnectWorkerToRIL::RunTask(JSContext* aCx)
|
||||||
{
|
{
|
||||||
// Set up the postRILMessage on the function for worker -> RIL thread
|
// Set up the postRILMessage on the function for worker -> RIL thread
|
||||||
// communication.
|
// communication.
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Expecting to be on the worker thread");
|
||||||
NS_ASSERTION(!JS_IsRunning(aCx), "Are we being called somehow?");
|
NS_ASSERTION(!JS_IsRunning(aCx), "Are we being called somehow?");
|
||||||
Rooted<JSObject*> workerGlobal(aCx, CurrentGlobalOrNull(aCx));
|
JS::Rooted<JSObject*> workerGlobal(aCx, JS::CurrentGlobalOrNull(aCx));
|
||||||
|
|
||||||
// Check whether |postRILMessage| has been defined. No one but this class
|
// Check whether |postRILMessage| has been defined. No one but this class
|
||||||
// should ever define |postRILMessage| in a RIL worker.
|
// should ever define |postRILMessage| in a RIL worker.
|
||||||
Rooted<Value> val(aCx);
|
JS::Rooted<JS::Value> val(aCx);
|
||||||
if (!JS_GetProperty(aCx, workerGlobal, "postRILMessage", &val)) {
|
if (!JS_GetProperty(aCx, workerGlobal, "postRILMessage", &val)) {
|
||||||
JS_ReportPendingException(aCx);
|
JS_ReportPendingException(aCx);
|
||||||
return NS_ERROR_FAILURE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure that |postRILMessage| is a function.
|
// Make sure that |postRILMessage| is a function.
|
||||||
if (JSTYPE_FUNCTION == JS_TypeOfValue(aCx, val)) {
|
if (JSTYPE_FUNCTION == JS_TypeOfValue(aCx, val)) {
|
||||||
return NS_OK;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSFunction* postRILMessage = JS_DefineFunction(aCx, workerGlobal,
|
return !!JS_DefineFunction(aCx, workerGlobal, "postRILMessage",
|
||||||
"postRILMessage",
|
PostToRIL, 2, 0);
|
||||||
PostRILMessage, 2, 0);
|
|
||||||
if (NS_WARN_IF(!postRILMessage)) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
class DispatchRILEvent final : public WorkerTask
|
||||||
RilConsumer::Register(unsigned long aClientId,
|
{
|
||||||
WorkerCrossThreadDispatcher* aDispatcher)
|
public:
|
||||||
|
DispatchRILEvent(unsigned long aClient, UnixSocketBuffer* aBuffer)
|
||||||
|
: mClientId(aClient)
|
||||||
|
, mBuffer(aBuffer)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
bool RunTask(JSContext* aCx) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned long mClientId;
|
||||||
|
nsAutoPtr<UnixSocketBuffer> mBuffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool
|
||||||
|
DispatchRILEvent::RunTask(JSContext* aCx)
|
||||||
|
{
|
||||||
|
JS::Rooted<JSObject*> obj(aCx, JS::CurrentGlobalOrNull(aCx));
|
||||||
|
|
||||||
|
JS::Rooted<JSObject*> array(aCx,
|
||||||
|
JS_NewUint8Array(aCx, mBuffer->GetSize()));
|
||||||
|
if (!array) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
JS::AutoCheckCannotGC nogc;
|
||||||
|
memcpy(JS_GetArrayBufferViewData(array, nogc),
|
||||||
|
mBuffer->GetData(), mBuffer->GetSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
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", args, &rval);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace ipc {
|
||||||
|
|
||||||
|
RilConsumer::RilConsumer(unsigned long aClientId,
|
||||||
|
WorkerCrossThreadDispatcher* aDispatcher)
|
||||||
|
: mDispatcher(aDispatcher)
|
||||||
|
, mShutdown(false)
|
||||||
{
|
{
|
||||||
// Only append client id after RIL_SOCKET_NAME when it's not connected to
|
// Only append client id after RIL_SOCKET_NAME when it's not connected to
|
||||||
// the first(0) rilproxy for compatibility.
|
// the first(0) rilproxy for compatibility.
|
||||||
|
@ -129,131 +214,60 @@ RilConsumer::Register(unsigned long aClientId,
|
||||||
mAddress = addr_un.sun_path;
|
mAddress = addr_un.sun_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
mSocket = new RilSocket(aDispatcher, this, aClientId);
|
mSocket = new StreamSocket(this, aClientId);
|
||||||
|
mSocket->Connect(new RilConnector(mAddress, aClientId));
|
||||||
|
}
|
||||||
|
|
||||||
nsresult rv = mSocket->Connect(new RilConnector(mAddress, aClientId));
|
nsresult
|
||||||
if (NS_FAILED(rv)) {
|
RilConsumer::Register(unsigned int aClientId,
|
||||||
return rv;
|
WorkerCrossThreadDispatcher* aDispatcher)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
sRilConsumers.EnsureLengthAtLeast(aClientId + 1);
|
||||||
|
|
||||||
|
if (sRilConsumers[aClientId]) {
|
||||||
|
NS_WARNING("RilConsumer already registered");
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsRefPtr<ConnectWorkerToRIL> connection = new ConnectWorkerToRIL();
|
||||||
|
if (!aDispatcher->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.
|
||||||
|
sRilConsumers[aClientId] = new RilConsumer(aClientId, aDispatcher);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
RilConsumer::Unregister()
|
RilConsumer::Shutdown()
|
||||||
{
|
{
|
||||||
mShutdown = true;
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
Close();
|
|
||||||
|
for (unsigned long i = 0; i < sRilConsumers.Length(); i++) {
|
||||||
|
nsAutoPtr<RilConsumer> instance(sRilConsumers[i]);
|
||||||
|
if (!instance) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
instance->mShutdown = true;
|
||||||
|
instance->Close();
|
||||||
|
instance = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
void
|
||||||
RilConsumer::PostRILMessage(JSContext* aCx, unsigned aArgc, Value* aVp)
|
RilConsumer::Send(UnixSocketRawData* aRawData)
|
||||||
{
|
{
|
||||||
CallArgs args = CallArgsFromVp(aArgc, aVp);
|
if (!mSocket || mSocket->GetConnectionStatus() != SOCKET_CONNECTED) {
|
||||||
|
|
||||||
if (args.length() != 2) {
|
|
||||||
JS_ReportError(aCx, "Expecting two arguments with the RIL message");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int clientId = args[0].toInt32();
|
|
||||||
|
|
||||||
if ((ssize_t)sRilConsumers.Length() <= clientId || !sRilConsumers[clientId]) {
|
|
||||||
// Probably shutting down.
|
// Probably shutting down.
|
||||||
return true;
|
delete aRawData;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
mSocket->SendSocketData(aRawData);
|
||||||
nsresult rv = sRilConsumers[clientId]->Send(aCx, args);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
RilConsumer::Send(JSContext* aCx, const CallArgs& aArgs)
|
|
||||||
{
|
|
||||||
if (NS_WARN_IF(!mSocket) ||
|
|
||||||
NS_WARN_IF(mSocket->GetConnectionStatus() != SOCKET_CONNECTED)) {
|
|
||||||
// Probably shutting down.
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsAutoPtr<UnixSocketRawData> raw;
|
|
||||||
|
|
||||||
Value v = aArgs[1];
|
|
||||||
|
|
||||||
if (v.isString()) {
|
|
||||||
JSAutoByteString abs;
|
|
||||||
Rooted<JSString*> str(aCx, v.toString());
|
|
||||||
if (!abs.encodeUtf8(aCx, str)) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
raw = new UnixSocketRawData(abs.ptr(), abs.length());
|
|
||||||
} else if (!v.isPrimitive()) {
|
|
||||||
JSObject* obj = v.toObjectOrNull();
|
|
||||||
if (!JS_IsTypedArrayObject(obj)) {
|
|
||||||
JS_ReportError(aCx, "Object passed in wasn't a typed array");
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t type = JS_GetArrayBufferViewType(obj);
|
|
||||||
if (type != js::Scalar::Int8 &&
|
|
||||||
type != js::Scalar::Uint8 &&
|
|
||||||
type != js::Scalar::Uint8Clamped) {
|
|
||||||
JS_ReportError(aCx, "Typed array data is not octets");
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
AutoCheckCannotGC nogc;
|
|
||||||
size_t size = JS_GetTypedArrayByteLength(obj);
|
|
||||||
void* data = JS_GetArrayBufferViewData(obj, nogc);
|
|
||||||
raw = new UnixSocketRawData(data, size);
|
|
||||||
} else {
|
|
||||||
JS_ReportError(
|
|
||||||
aCx, "Incorrect argument. Expecting a string or a typed array");
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!raw) {
|
|
||||||
JS_ReportError(aCx, "Unable to post to RIL");
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
mSocket->SendSocketData(raw.forget());
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
RilConsumer::Receive(JSContext* aCx,
|
|
||||||
uint32_t aClientId,
|
|
||||||
const UnixSocketBuffer* aBuffer)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(aBuffer);
|
|
||||||
|
|
||||||
Rooted<JSObject*> obj(aCx, CurrentGlobalOrNull(aCx));
|
|
||||||
|
|
||||||
Rooted<JSObject*> array(aCx, JS_NewUint8Array(aCx, aBuffer->GetSize()));
|
|
||||||
if (NS_WARN_IF(!array)) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
AutoCheckCannotGC nogc;
|
|
||||||
memcpy(JS_GetArrayBufferViewData(array, nogc),
|
|
||||||
aBuffer->GetData(), aBuffer->GetSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
AutoValueArray<2> args(aCx);
|
|
||||||
args[0].setNumber(aClientId);
|
|
||||||
args[1].setObject(*array);
|
|
||||||
|
|
||||||
Rooted<Value> rval(aCx);
|
|
||||||
JS_CallFunctionName(aCx, obj, "onRILMessage", args, &rval);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -265,14 +279,16 @@ RilConsumer::Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// |RilSocketConnector|
|
// |StreamSocketConnector|
|
||||||
|
|
||||||
void
|
void
|
||||||
RilConsumer::ReceiveSocketData(JSContext* aCx,
|
RilConsumer::ReceiveSocketData(int aIndex,
|
||||||
int aIndex,
|
|
||||||
nsAutoPtr<UnixSocketBuffer>& aBuffer)
|
nsAutoPtr<UnixSocketBuffer>& aBuffer)
|
||||||
{
|
{
|
||||||
Receive(aCx, (uint32_t)aIndex, aBuffer);
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
nsRefPtr<DispatchRILEvent> dre(new DispatchRILEvent(aIndex, aBuffer.forget()));
|
||||||
|
mDispatcher->PostTask(dre);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -300,140 +316,5 @@ RilConsumer::OnDisconnect(int aIndex)
|
||||||
mSocket->GetSuggestedConnectDelayMs());
|
mSocket->GetSuggestedConnectDelayMs());
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// RilWorker
|
|
||||||
//
|
|
||||||
|
|
||||||
nsTArray<nsAutoPtr<RilWorker>> RilWorker::sRilWorkers;
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
RilWorker::Register(unsigned int aClientId,
|
|
||||||
WorkerCrossThreadDispatcher* aDispatcher)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
|
|
||||||
sRilWorkers.EnsureLengthAtLeast(aClientId + 1);
|
|
||||||
|
|
||||||
if (sRilWorkers[aClientId]) {
|
|
||||||
NS_WARNING("RilWorkers already registered");
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now that we're set up, connect ourselves to the RIL thread.
|
|
||||||
sRilWorkers[aClientId] = new RilWorker(aDispatcher);
|
|
||||||
|
|
||||||
nsresult rv = sRilWorkers[aClientId]->RegisterConsumer(aClientId);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RilWorker::Shutdown()
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
|
|
||||||
for (size_t i = 0; i < sRilWorkers.Length(); ++i) {
|
|
||||||
if (!sRilWorkers[i]) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
sRilWorkers[i]->UnregisterConsumer(i);
|
|
||||||
sRilWorkers[i] = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RilWorker::RilWorker(WorkerCrossThreadDispatcher* aDispatcher)
|
|
||||||
: mDispatcher(aDispatcher)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(mDispatcher);
|
|
||||||
}
|
|
||||||
|
|
||||||
class RilWorker::RegisterConsumerTask : public WorkerTask
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
RegisterConsumerTask(unsigned int aClientId,
|
|
||||||
WorkerCrossThreadDispatcher* aDispatcher)
|
|
||||||
: mClientId(aClientId)
|
|
||||||
, mDispatcher(aDispatcher)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(mDispatcher);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RunTask(JSContext* aCx) override
|
|
||||||
{
|
|
||||||
sRilConsumers.EnsureLengthAtLeast(mClientId + 1);
|
|
||||||
|
|
||||||
MOZ_ASSERT(!sRilConsumers[mClientId]);
|
|
||||||
|
|
||||||
nsAutoPtr<RilConsumer> rilConsumer(new RilConsumer());
|
|
||||||
|
|
||||||
nsresult rv = rilConsumer->ConnectWorkerToRIL(aCx);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = rilConsumer->Register(mClientId, mDispatcher);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
sRilConsumers[mClientId] = rilConsumer;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
unsigned int mClientId;
|
|
||||||
nsRefPtr<WorkerCrossThreadDispatcher> mDispatcher;
|
|
||||||
};
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
RilWorker::RegisterConsumer(unsigned int aClientId)
|
|
||||||
{
|
|
||||||
nsRefPtr<RegisterConsumerTask> task = new RegisterConsumerTask(aClientId,
|
|
||||||
mDispatcher);
|
|
||||||
if (!mDispatcher->PostTask(task)) {
|
|
||||||
NS_WARNING("Failed to post register-consumer task.");
|
|
||||||
return NS_ERROR_UNEXPECTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
class RilWorker::UnregisterConsumerTask : public WorkerTask
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
UnregisterConsumerTask(unsigned int aClientId)
|
|
||||||
: mClientId(aClientId)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
bool RunTask(JSContext* aCx) override
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(mClientId < sRilConsumers.Length());
|
|
||||||
MOZ_ASSERT(sRilConsumers[mClientId]);
|
|
||||||
|
|
||||||
sRilConsumers[mClientId]->Unregister();
|
|
||||||
sRilConsumers[mClientId] = nullptr;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
unsigned int mClientId;
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
|
||||||
RilWorker::UnregisterConsumer(unsigned int aClientId)
|
|
||||||
{
|
|
||||||
nsRefPtr<UnregisterConsumerTask> task =
|
|
||||||
new UnregisterConsumerTask(aClientId);
|
|
||||||
|
|
||||||
if (!mDispatcher->PostTask(task)) {
|
|
||||||
NS_WARNING("Failed to post unregister-consumer task.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ipc
|
} // namespace ipc
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -7,45 +7,42 @@
|
||||||
#ifndef mozilla_ipc_Ril_h
|
#ifndef mozilla_ipc_Ril_h
|
||||||
#define mozilla_ipc_Ril_h 1
|
#define mozilla_ipc_Ril_h 1
|
||||||
|
|
||||||
#include "nsAutoPtr.h"
|
#include <mozilla/dom/workers/Workers.h>
|
||||||
#include "nsError.h"
|
#include <mozilla/ipc/StreamSocket.h>
|
||||||
#include "nsTArray.h"
|
#include <mozilla/ipc/StreamSocketConsumer.h>
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
namespace dom {
|
|
||||||
namespace workers {
|
|
||||||
|
|
||||||
class WorkerCrossThreadDispatcher;
|
|
||||||
|
|
||||||
} // namespace workers
|
|
||||||
} // namespace dom
|
|
||||||
|
|
||||||
namespace ipc {
|
namespace ipc {
|
||||||
|
|
||||||
class RilConsumer;
|
class RilConsumer final : public StreamSocketConsumer
|
||||||
|
|
||||||
class RilWorker final
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static nsresult Register(
|
static nsresult Register(
|
||||||
unsigned int aClientId,
|
unsigned int aClientId,
|
||||||
mozilla::dom::workers::WorkerCrossThreadDispatcher* aDispatcher);
|
mozilla::dom::workers::WorkerCrossThreadDispatcher* aDispatcher);
|
||||||
|
|
||||||
static void Shutdown();
|
static void Shutdown();
|
||||||
|
|
||||||
|
void Send(UnixSocketRawData* aRawData);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class RegisterConsumerTask;
|
RilConsumer(unsigned long aClientId,
|
||||||
class UnregisterConsumerTask;
|
mozilla::dom::workers::WorkerCrossThreadDispatcher* aDispatcher);
|
||||||
|
|
||||||
RilWorker(mozilla::dom::workers::WorkerCrossThreadDispatcher* aDispatcher);
|
void Close();
|
||||||
|
|
||||||
nsresult RegisterConsumer(unsigned int aClientId);
|
// Methods for |StreamSocketConsumer|
|
||||||
void UnregisterConsumer(unsigned int aClientId);
|
//
|
||||||
|
|
||||||
static nsTArray<nsAutoPtr<RilWorker>> sRilWorkers;
|
void ReceiveSocketData(int aIndex,
|
||||||
|
nsAutoPtr<UnixSocketBuffer>& aBuffer) override;
|
||||||
|
void OnConnectSuccess(int aIndex) override;
|
||||||
|
void OnConnectError(int aIndex) override;
|
||||||
|
void OnDisconnect(int aIndex) override;
|
||||||
|
|
||||||
|
nsRefPtr<StreamSocket> mSocket;
|
||||||
nsRefPtr<mozilla::dom::workers::WorkerCrossThreadDispatcher> mDispatcher;
|
nsRefPtr<mozilla::dom::workers::WorkerCrossThreadDispatcher> mDispatcher;
|
||||||
|
nsCString mAddress;
|
||||||
|
bool mShutdown;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ipc
|
} // namespace ipc
|
||||||
|
|
|
@ -1,433 +0,0 @@
|
||||||
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
|
|
||||||
/* vim: set ts=2 et sw=2 tw=80: */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include "RilSocket.h"
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include "mozilla/dom/workers/Workers.h"
|
|
||||||
#include "mozilla/ipc/UnixSocketConnector.h"
|
|
||||||
#include "mozilla/RefPtr.h"
|
|
||||||
#include "nsXULAppAPI.h"
|
|
||||||
#include "RilSocketConsumer.h"
|
|
||||||
|
|
||||||
static const size_t MAX_READ_SIZE = 1 << 16;
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace ipc {
|
|
||||||
|
|
||||||
USING_WORKERS_NAMESPACE
|
|
||||||
|
|
||||||
//
|
|
||||||
// RilSocketIO
|
|
||||||
//
|
|
||||||
|
|
||||||
class RilSocketIO final : public ConnectionOrientedSocketIO
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
class ConnectTask;
|
|
||||||
class DelayedConnectTask;
|
|
||||||
class ReceiveTask;
|
|
||||||
|
|
||||||
RilSocketIO(WorkerCrossThreadDispatcher* aDispatcher,
|
|
||||||
MessageLoop* aConsumerLoop,
|
|
||||||
MessageLoop* aIOLoop,
|
|
||||||
RilSocket* aRilSocket,
|
|
||||||
UnixSocketConnector* aConnector);
|
|
||||||
~RilSocketIO();
|
|
||||||
|
|
||||||
RilSocket* GetRilSocket();
|
|
||||||
DataSocket* GetDataSocket();
|
|
||||||
|
|
||||||
// Delayed-task handling
|
|
||||||
//
|
|
||||||
|
|
||||||
void SetDelayedConnectTask(CancelableTask* aTask);
|
|
||||||
void ClearDelayedConnectTask();
|
|
||||||
void CancelDelayedConnectTask();
|
|
||||||
|
|
||||||
// Methods for |DataSocket|
|
|
||||||
//
|
|
||||||
|
|
||||||
nsresult QueryReceiveBuffer(UnixSocketIOBuffer** aBuffer) override;
|
|
||||||
void ConsumeBuffer() override;
|
|
||||||
void DiscardBuffer() override;
|
|
||||||
|
|
||||||
// Methods for |SocketIOBase|
|
|
||||||
//
|
|
||||||
|
|
||||||
SocketBase* GetSocketBase() override;
|
|
||||||
|
|
||||||
bool IsShutdownOnConsumerThread() const override;
|
|
||||||
bool IsShutdownOnIOThread() const override;
|
|
||||||
|
|
||||||
void ShutdownOnConsumerThread() override;
|
|
||||||
void ShutdownOnIOThread() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* Cross-thread dispatcher for the RIL worker
|
|
||||||
*/
|
|
||||||
nsRefPtr<WorkerCrossThreadDispatcher> mDispatcher;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Consumer pointer. Non-thread safe RefPtr, so should only be manipulated
|
|
||||||
* directly from consumer thread. All non-consumer-thread accesses should
|
|
||||||
* happen with mIO as container.
|
|
||||||
*/
|
|
||||||
RefPtr<RilSocket> mRilSocket;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If true, do not requeue whatever task we're running
|
|
||||||
*/
|
|
||||||
bool mShuttingDownOnIOThread;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Task member for delayed connect task. Should only be access on consumer
|
|
||||||
* thread.
|
|
||||||
*/
|
|
||||||
CancelableTask* mDelayedConnectTask;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* I/O buffer for received data
|
|
||||||
*/
|
|
||||||
nsAutoPtr<UnixSocketRawData> mBuffer;
|
|
||||||
};
|
|
||||||
|
|
||||||
RilSocketIO::RilSocketIO(WorkerCrossThreadDispatcher* aDispatcher,
|
|
||||||
MessageLoop* aConsumerLoop,
|
|
||||||
MessageLoop* aIOLoop,
|
|
||||||
RilSocket* aRilSocket,
|
|
||||||
UnixSocketConnector* aConnector)
|
|
||||||
: ConnectionOrientedSocketIO(aConsumerLoop, aIOLoop, aConnector)
|
|
||||||
, mDispatcher(aDispatcher)
|
|
||||||
, mRilSocket(aRilSocket)
|
|
||||||
, mShuttingDownOnIOThread(false)
|
|
||||||
, mDelayedConnectTask(nullptr)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(mDispatcher);
|
|
||||||
MOZ_ASSERT(mRilSocket);
|
|
||||||
}
|
|
||||||
|
|
||||||
RilSocketIO::~RilSocketIO()
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(IsConsumerThread());
|
|
||||||
MOZ_ASSERT(IsShutdownOnConsumerThread());
|
|
||||||
}
|
|
||||||
|
|
||||||
RilSocket*
|
|
||||||
RilSocketIO::GetRilSocket()
|
|
||||||
{
|
|
||||||
return mRilSocket.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
DataSocket*
|
|
||||||
RilSocketIO::GetDataSocket()
|
|
||||||
{
|
|
||||||
return mRilSocket.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RilSocketIO::SetDelayedConnectTask(CancelableTask* aTask)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(IsConsumerThread());
|
|
||||||
|
|
||||||
mDelayedConnectTask = aTask;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RilSocketIO::ClearDelayedConnectTask()
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(IsConsumerThread());
|
|
||||||
|
|
||||||
mDelayedConnectTask = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RilSocketIO::CancelDelayedConnectTask()
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(IsConsumerThread());
|
|
||||||
|
|
||||||
if (!mDelayedConnectTask) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mDelayedConnectTask->Cancel();
|
|
||||||
ClearDelayedConnectTask();
|
|
||||||
}
|
|
||||||
|
|
||||||
// |DataSocketIO|
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
RilSocketIO::QueryReceiveBuffer(UnixSocketIOBuffer** aBuffer)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(aBuffer);
|
|
||||||
|
|
||||||
if (!mBuffer) {
|
|
||||||
mBuffer = new UnixSocketRawData(MAX_READ_SIZE);
|
|
||||||
}
|
|
||||||
*aBuffer = mBuffer.get();
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* |ReceiveTask| transfers data received on the I/O thread
|
|
||||||
* to an instance of |RilSocket| on the consumer thread.
|
|
||||||
*/
|
|
||||||
class RilSocketIO::ReceiveTask final : public WorkerTask
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ReceiveTask(RilSocketIO* aIO, UnixSocketBuffer* aBuffer)
|
|
||||||
: mIO(aIO)
|
|
||||||
, mBuffer(aBuffer)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(mIO);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RunTask(JSContext* aCx) override
|
|
||||||
{
|
|
||||||
// Dispatched via WCTD, but still needs to run on the consumer thread
|
|
||||||
MOZ_ASSERT(mIO->IsConsumerThread());
|
|
||||||
|
|
||||||
if (NS_WARN_IF(mIO->IsShutdownOnConsumerThread())) {
|
|
||||||
// Since we've already explicitly closed and the close
|
|
||||||
// happened before this, this isn't really an error.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
RilSocket* rilSocket = mIO->GetRilSocket();
|
|
||||||
MOZ_ASSERT(rilSocket);
|
|
||||||
|
|
||||||
rilSocket->ReceiveSocketData(aCx, mBuffer);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
RilSocketIO* mIO;
|
|
||||||
nsAutoPtr<UnixSocketBuffer> mBuffer;
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
|
||||||
RilSocketIO::ConsumeBuffer()
|
|
||||||
{
|
|
||||||
nsRefPtr<ReceiveTask> task = new ReceiveTask(this, mBuffer.forget());
|
|
||||||
NS_WARN_IF(!mDispatcher->PostTask(task));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RilSocketIO::DiscardBuffer()
|
|
||||||
{
|
|
||||||
// Nothing to do.
|
|
||||||
}
|
|
||||||
|
|
||||||
// |SocketIOBase|
|
|
||||||
|
|
||||||
SocketBase*
|
|
||||||
RilSocketIO::GetSocketBase()
|
|
||||||
{
|
|
||||||
return GetDataSocket();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
RilSocketIO::IsShutdownOnConsumerThread() const
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(IsConsumerThread());
|
|
||||||
|
|
||||||
return mRilSocket == nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
RilSocketIO::IsShutdownOnIOThread() const
|
|
||||||
{
|
|
||||||
return mShuttingDownOnIOThread;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RilSocketIO::ShutdownOnConsumerThread()
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(IsConsumerThread());
|
|
||||||
MOZ_ASSERT(!IsShutdownOnConsumerThread());
|
|
||||||
|
|
||||||
mRilSocket = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RilSocketIO::ShutdownOnIOThread()
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(!IsConsumerThread());
|
|
||||||
MOZ_ASSERT(!mShuttingDownOnIOThread);
|
|
||||||
|
|
||||||
Close(); // will also remove fd from I/O loop
|
|
||||||
mShuttingDownOnIOThread = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Socket tasks
|
|
||||||
//
|
|
||||||
|
|
||||||
class RilSocketIO::ConnectTask final
|
|
||||||
: public SocketIOTask<RilSocketIO>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ConnectTask(RilSocketIO* aIO)
|
|
||||||
: SocketIOTask<RilSocketIO>(aIO)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
void Run() override
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(!GetIO()->IsConsumerThread());
|
|
||||||
MOZ_ASSERT(!IsCanceled());
|
|
||||||
|
|
||||||
GetIO()->Connect();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class RilSocketIO::DelayedConnectTask final
|
|
||||||
: public SocketIOTask<RilSocketIO>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
DelayedConnectTask(RilSocketIO* aIO)
|
|
||||||
: SocketIOTask<RilSocketIO>(aIO)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
void Run() override
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(GetIO()->IsConsumerThread());
|
|
||||||
|
|
||||||
if (IsCanceled()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
RilSocketIO* io = GetIO();
|
|
||||||
if (io->IsShutdownOnConsumerThread()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
io->ClearDelayedConnectTask();
|
|
||||||
io->GetIOLoop()->PostTask(FROM_HERE, new ConnectTask(io));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// RilSocket
|
|
||||||
//
|
|
||||||
|
|
||||||
RilSocket::RilSocket(WorkerCrossThreadDispatcher* aDispatcher,
|
|
||||||
RilSocketConsumer* aConsumer, int aIndex)
|
|
||||||
: mIO(nullptr)
|
|
||||||
, mDispatcher(aDispatcher)
|
|
||||||
, mConsumer(aConsumer)
|
|
||||||
, mIndex(aIndex)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(mDispatcher);
|
|
||||||
MOZ_ASSERT(mConsumer);
|
|
||||||
}
|
|
||||||
|
|
||||||
RilSocket::~RilSocket()
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(!mIO);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RilSocket::ReceiveSocketData(JSContext* aCx,
|
|
||||||
nsAutoPtr<UnixSocketBuffer>& aBuffer)
|
|
||||||
{
|
|
||||||
mConsumer->ReceiveSocketData(aCx, mIndex, aBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
RilSocket::Connect(UnixSocketConnector* aConnector, int aDelayMs,
|
|
||||||
MessageLoop* aConsumerLoop, MessageLoop* aIOLoop)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(!mIO);
|
|
||||||
|
|
||||||
mIO = new RilSocketIO(mDispatcher, aConsumerLoop, aIOLoop, this, aConnector);
|
|
||||||
SetConnectionStatus(SOCKET_CONNECTING);
|
|
||||||
|
|
||||||
if (aDelayMs > 0) {
|
|
||||||
RilSocketIO::DelayedConnectTask* connectTask =
|
|
||||||
new RilSocketIO::DelayedConnectTask(mIO);
|
|
||||||
mIO->SetDelayedConnectTask(connectTask);
|
|
||||||
MessageLoop::current()->PostDelayedTask(FROM_HERE, connectTask, aDelayMs);
|
|
||||||
} else {
|
|
||||||
aIOLoop->PostTask(FROM_HERE, new RilSocketIO::ConnectTask(mIO));
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
RilSocket::Connect(UnixSocketConnector* aConnector, int aDelayMs)
|
|
||||||
{
|
|
||||||
return Connect(aConnector, aDelayMs,
|
|
||||||
MessageLoop::current(), XRE_GetIOMessageLoop());
|
|
||||||
}
|
|
||||||
|
|
||||||
// |ConnectionOrientedSocket|
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
RilSocket::PrepareAccept(UnixSocketConnector* aConnector,
|
|
||||||
MessageLoop* aConsumerLoop,
|
|
||||||
MessageLoop* aIOLoop,
|
|
||||||
ConnectionOrientedSocketIO*& aIO)
|
|
||||||
{
|
|
||||||
MOZ_CRASH("|RilSocket| does not support accepting connections.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// |DataSocket|
|
|
||||||
|
|
||||||
void
|
|
||||||
RilSocket::SendSocketData(UnixSocketIOBuffer* aBuffer)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(mIO);
|
|
||||||
MOZ_ASSERT(mIO->IsConsumerThread());
|
|
||||||
MOZ_ASSERT(!mIO->IsShutdownOnConsumerThread());
|
|
||||||
|
|
||||||
mIO->GetIOLoop()->PostTask(
|
|
||||||
FROM_HERE,
|
|
||||||
new SocketIOSendTask<RilSocketIO, UnixSocketIOBuffer>(mIO, aBuffer));
|
|
||||||
}
|
|
||||||
|
|
||||||
// |SocketBase|
|
|
||||||
|
|
||||||
void
|
|
||||||
RilSocket::Close()
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(mIO);
|
|
||||||
MOZ_ASSERT(mIO->IsConsumerThread());
|
|
||||||
|
|
||||||
mIO->CancelDelayedConnectTask();
|
|
||||||
|
|
||||||
// From this point on, we consider |mIO| as being deleted. We sever
|
|
||||||
// the relationship here so any future calls to |Connect| will create
|
|
||||||
// a new I/O object.
|
|
||||||
mIO->ShutdownOnConsumerThread();
|
|
||||||
mIO->GetIOLoop()->PostTask(FROM_HERE, new SocketIOShutdownTask(mIO));
|
|
||||||
mIO = nullptr;
|
|
||||||
|
|
||||||
NotifyDisconnect();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RilSocket::OnConnectSuccess()
|
|
||||||
{
|
|
||||||
mConsumer->OnConnectSuccess(mIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RilSocket::OnConnectError()
|
|
||||||
{
|
|
||||||
mConsumer->OnConnectError(mIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RilSocket::OnDisconnect()
|
|
||||||
{
|
|
||||||
mConsumer->OnDisconnect(mIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ipc
|
|
||||||
} // namespace mozilla
|
|
|
@ -1,110 +0,0 @@
|
||||||
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
|
|
||||||
/* vim: set ts=2 et sw=2 tw=80: */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#ifndef mozilla_ipc_RilSocket_h
|
|
||||||
#define mozilla_ipc_RilSocket_h
|
|
||||||
|
|
||||||
#include "mozilla/ipc/ConnectionOrientedSocket.h"
|
|
||||||
|
|
||||||
class JSContext;
|
|
||||||
class MessageLoop;
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace dom {
|
|
||||||
namespace workers {
|
|
||||||
|
|
||||||
class WorkerCrossThreadDispatcher;
|
|
||||||
|
|
||||||
} // namespace workers
|
|
||||||
} // namespace dom
|
|
||||||
} // namespace mozilla
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace ipc {
|
|
||||||
|
|
||||||
class RilSocketConsumer;
|
|
||||||
class RilSocketIO;
|
|
||||||
class UnixSocketConnector;
|
|
||||||
|
|
||||||
class RilSocket final : public ConnectionOrientedSocket
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Constructs an instance of |RilSocket|.
|
|
||||||
*
|
|
||||||
* @param aDispatcher The dispatcher class for the received messages.
|
|
||||||
* @param aConsumer The consumer for the socket.
|
|
||||||
* @param aIndex An arbitrary index.
|
|
||||||
*/
|
|
||||||
RilSocket(mozilla::dom::workers::WorkerCrossThreadDispatcher* aDispatcher,
|
|
||||||
RilSocketConsumer* aConsumer, int aIndex);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method to be called whenever data is received. RIL-worker only.
|
|
||||||
*
|
|
||||||
* @param aCx The RIL worker's JS context.
|
|
||||||
* @param aBuffer Data received from the socket.
|
|
||||||
*/
|
|
||||||
void ReceiveSocketData(JSContext* aCx, nsAutoPtr<UnixSocketBuffer>& aBuffer);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts a task on the socket that will try to connect to a socket in a
|
|
||||||
* non-blocking manner.
|
|
||||||
*
|
|
||||||
* @param aConnector Connector object for socket type specific functions
|
|
||||||
* @param aDelayMs Time delay in milliseconds.
|
|
||||||
* @param aConsumerLoop The socket's consumer thread.
|
|
||||||
* @param aIOLoop The socket's I/O thread.
|
|
||||||
* @return NS_OK on success, or an XPCOM error code otherwise.
|
|
||||||
*/
|
|
||||||
nsresult Connect(UnixSocketConnector* aConnector, int aDelayMs,
|
|
||||||
MessageLoop* aConsumerLoop, MessageLoop* aIOLoop);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts a task on the socket that will try to connect to a socket in a
|
|
||||||
* non-blocking manner.
|
|
||||||
*
|
|
||||||
* @param aConnector Connector object for socket type specific functions
|
|
||||||
* @param aDelayMs Time delay in milliseconds.
|
|
||||||
* @return NS_OK on success, or an XPCOM error code otherwise.
|
|
||||||
*/
|
|
||||||
nsresult Connect(UnixSocketConnector* aConnector, int aDelayMs = 0);
|
|
||||||
|
|
||||||
// Methods for |ConnectionOrientedSocket|
|
|
||||||
//
|
|
||||||
|
|
||||||
nsresult PrepareAccept(UnixSocketConnector* aConnector,
|
|
||||||
MessageLoop* aConsumerLoop,
|
|
||||||
MessageLoop* aIOLoop,
|
|
||||||
ConnectionOrientedSocketIO*& aIO) override;
|
|
||||||
|
|
||||||
// Methods for |DataSocket|
|
|
||||||
//
|
|
||||||
|
|
||||||
void SendSocketData(UnixSocketIOBuffer* aBuffer) override;
|
|
||||||
|
|
||||||
// Methods for |SocketBase|
|
|
||||||
//
|
|
||||||
|
|
||||||
void Close() override;
|
|
||||||
void OnConnectSuccess() override;
|
|
||||||
void OnConnectError() override;
|
|
||||||
void OnDisconnect() override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual ~RilSocket();
|
|
||||||
|
|
||||||
private:
|
|
||||||
RilSocketIO* mIO;
|
|
||||||
nsRefPtr<mozilla::dom::workers::WorkerCrossThreadDispatcher> mDispatcher;
|
|
||||||
RilSocketConsumer* mConsumer;
|
|
||||||
int mIndex;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ipc
|
|
||||||
} // namepsace mozilla
|
|
||||||
|
|
||||||
#endif // mozilla_ipc_RilSocket_h
|
|
|
@ -1,20 +0,0 @@
|
||||||
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
|
|
||||||
/* vim: set ts=2 et sw=2 tw=80: */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include "RilSocketConsumer.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace ipc {
|
|
||||||
|
|
||||||
//
|
|
||||||
// RilSocketConsumer
|
|
||||||
//
|
|
||||||
|
|
||||||
RilSocketConsumer::~RilSocketConsumer()
|
|
||||||
{ }
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
|
|
||||||
/* vim: set ts=2 et sw=2 tw=80: */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#ifndef mozilla_ipc_RilSocketConsumer_h
|
|
||||||
#define mozilla_ipc_RilSocketConsumer_h
|
|
||||||
|
|
||||||
#include "nsAutoPtr.h"
|
|
||||||
|
|
||||||
class JSContext;
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace ipc {
|
|
||||||
|
|
||||||
class UnixSocketBuffer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* |RilSocketConsumer| handles socket events and received data.
|
|
||||||
*/
|
|
||||||
class RilSocketConsumer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Method to be called whenever data is received. RIL-worker only.
|
|
||||||
*
|
|
||||||
* @param aCx The RIL worker's JS context.
|
|
||||||
* @param aIndex The index that has been given to the stream socket.
|
|
||||||
* @param aBuffer Data received from the socket.
|
|
||||||
*/
|
|
||||||
virtual void ReceiveSocketData(JSContext* aCx,
|
|
||||||
int aIndex,
|
|
||||||
nsAutoPtr<UnixSocketBuffer>& aBuffer) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback for socket success. Consumer-thread only.
|
|
||||||
*
|
|
||||||
* @param aIndex The index that has been given to the stream socket.
|
|
||||||
*/
|
|
||||||
virtual void OnConnectSuccess(int aIndex) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback for socket errors. Consumer-thread only.
|
|
||||||
*
|
|
||||||
* @param aIndex The index that has been given to the stream socket.
|
|
||||||
*/
|
|
||||||
virtual void OnConnectError(int aIndex) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback for socket disconnect. Consumer-thread only.
|
|
||||||
*
|
|
||||||
* @param aIndex The index that has been given to the stream socket.
|
|
||||||
*/
|
|
||||||
virtual void OnDisconnect(int aIndex) = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual ~RilSocketConsumer();
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -6,15 +6,11 @@
|
||||||
|
|
||||||
EXPORTS.mozilla.ipc += [
|
EXPORTS.mozilla.ipc += [
|
||||||
'Ril.h',
|
'Ril.h',
|
||||||
'RilSocket.h',
|
|
||||||
'RilSocketConsumer.h'
|
|
||||||
]
|
]
|
||||||
|
|
||||||
SOURCES += [
|
SOURCES += [
|
||||||
'Ril.cpp',
|
'Ril.cpp',
|
||||||
'RilConnector.cpp',
|
'RilConnector.cpp'
|
||||||
'RilSocket.cpp',
|
|
||||||
'RilSocketConsumer.cpp'
|
|
||||||
]
|
]
|
||||||
|
|
||||||
include('/ipc/chromium/chromium-config.mozbuild')
|
include('/ipc/chromium/chromium-config.mozbuild')
|
||||||
|
|
Загрузка…
Ссылка в новой задаче