/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=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/. */
// Called when the NodeChannel's refcount drops to `0`. void NodeChannel::Destroy() { // We want to dispatch the `delete` operation to the IO thread. We need to do // this even if we're already on the IO thread, as we could be in an // `IPC::Channel` callback which unfortunately will not hold a strong // reference to keep `this` alive.
nsISerialEventTarget* ioThread = XRE_GetAsyncIOEventTarget();
// Synchronously invoke `FinalDestroy` if we're already shutting the IO thread // down to ensure we're cleaned up before the thread dies. This is safe as we // can't be in a non-owning IPC::Channel callback at this point. if (ioThread->IsOnCurrentThread() && MessageLoop::current() &&
!MessageLoop::current()->IsAcceptingTasks()) {
FinalDestroy(); return;
}
base::ProcessId previousPid = base::kInvalidProcessId; if (!mOtherPid.compare_exchange_strong(previousPid, aNewPid)) { // The PID was already set before this call, double-check that it's correct.
MOZ_RELEASE_ASSERT(previousPid == aNewPid, "Different sources disagree on the correct pid?");
}
if (mState != State::Closed) {
mChannel->SetOtherMachTask(aTask);
}
} #endif
void NodeChannel::SendEventMessage(UniquePtr<IPC::Message> aMessage) { // Make sure we're not sending a message with one of our special internal // types ,as those should only be sent using the corresponding methods on // NodeChannel.
MOZ_DIAGNOSTIC_ASSERT(aMessage->type() != BROADCAST_MESSAGE_TYPE &&
aMessage->type() != INTRODUCE_MESSAGE_TYPE &&
aMessage->type() != REQUEST_INTRODUCTION_MESSAGE_TYPE &&
aMessage->type() != ACCEPT_INVITE_MESSAGE_TYPE);
SendMessage(std::move(aMessage));
}
void NodeChannel::SendMessage(UniquePtr<IPC::Message> aMessage) { if (aMessage->size() > IPC::Channel::kMaximumMessageSize) {
CrashReporter::RecordAnnotationCString(
CrashReporter::Annotation::IPCMessageName, aMessage->name());
CrashReporter::RecordAnnotationU32(
CrashReporter::Annotation::IPCMessageSize, aMessage->size());
CrashReporter::RecordAnnotationU32(
CrashReporter::Annotation::IPCMessageLargeBufferShmemFailureSize,
aMessage->LargeBufferShmemFailureSize());
MOZ_CRASH("IPC message size is too large");
}
aMessage->AssertAsLargeAsHeader();
#ifdef FUZZING_SNAPSHOT if (mBlockSendRecv) { return;
} #endif
if (mState != State::Active) {
NS_WARNING("Dropping message as channel has been closed"); return;
}
// NOTE: As this is not guaranteed to be running on the I/O thread, the // channel may have become closed since we checked above. IPC::Channel will // handle that and return `false` here, so we can re-check `mState`. if (!mChannel->Send(std::move(aMessage))) {
NS_WARNING("Call to Send() failed");
// If we're still active, update `mState` to `State::Closing`, and dispatch // a runnable to actually close our channel.
State expected = State::Active; if (mState.compare_exchange_strong(expected, State::Closing)) {
XRE_GetAsyncIOEventTarget()->Dispatch(
NewRunnableMethod("NodeChannel::CloseForSendError", this,
&NodeChannel::OnChannelError));
}
}
}
#ifdef FUZZING_SNAPSHOT if (mBlockSendRecv && !aMessage->IsFuzzMsg()) { return;
} #endif
IPC::MessageReader reader(*aMessage); switch (aMessage->type()) { case REQUEST_INTRODUCTION_MESSAGE_TYPE: {
NodeName name; if (IPC::ReadParam(&reader, &name)) {
mListener->OnRequestIntroduction(mName, name); return;
} break;
} case INTRODUCE_MESSAGE_TYPE: {
Introduction introduction; if (IPC::ReadParam(&reader, &introduction)) {
mListener->OnIntroduce(mName, std::move(introduction)); return;
} break;
} case BROADCAST_MESSAGE_TYPE: {
mListener->OnBroadcast(mName, std::move(aMessage)); return;
} case ACCEPT_INVITE_MESSAGE_TYPE: {
NodeName realName;
PortName initialPort; if (IPC::ReadParam(&reader, &realName) &&
IPC::ReadParam(&reader, &initialPort)) {
mListener->OnAcceptInvite(mName, realName, initialPort); return;
} break;
} // Assume all unrecognized types are intended as user event messages, and // deliver them to our listener as such. This allows us to use the same type // field for both internal messages and protocol messages. // // FIXME: Consider doing something cleaner in the future? case EVENT_MESSAGE_TYPE: default: { #ifdef FUZZING_SNAPSHOT if (!fuzzing::IPCFuzzController::instance().ObserveIPCMessage( this, *aMessage)) { return;
} #endif
// We may need to tell the GeckoChildProcessHost which we were created by that // the channel has been connected to unblock completing the process launch. if (mChildProcessHost) {
mChildProcessHost->OnChannelConnected(aPeerPid);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.