зеркало из https://github.com/mozilla/pjs.git
Bug 556214, part 3: IPC code wants to be using non-reentrant Monitor. r=bent
This commit is contained in:
Родитель
6a87d2af28
Коммит
240e3f8d9e
|
@ -45,7 +45,7 @@
|
|||
#include "nsTraceRefcnt.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
using mozilla::MutexAutoLock;
|
||||
using mozilla::MonitorAutoLock;
|
||||
|
||||
template<>
|
||||
struct RunnableMethodTraits<mozilla::ipc::AsyncChannel>
|
||||
|
@ -106,8 +106,7 @@ AsyncChannel::AsyncChannel(AsyncListener* aListener)
|
|||
: mTransport(0),
|
||||
mListener(aListener),
|
||||
mChannelState(ChannelClosed),
|
||||
mMutex("mozilla.ipc.AsyncChannel.mMutex"),
|
||||
mCvar(mMutex, "mozilla.ipc.AsyncChannel.mCvar"),
|
||||
mMonitor("mozilla.ipc.AsyncChannel.mMonitor"),
|
||||
mIOLoop(),
|
||||
mWorkerLoop(),
|
||||
mChild(false),
|
||||
|
@ -155,7 +154,7 @@ AsyncChannel::Open(Transport* aTransport, MessageLoop* aIOLoop)
|
|||
NS_ASSERTION(mWorkerLoop, "need a worker loop");
|
||||
|
||||
if (needOpen) { // child process
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
mIOLoop->PostTask(FROM_HERE,
|
||||
NewRunnableMethod(this,
|
||||
|
@ -163,7 +162,7 @@ AsyncChannel::Open(Transport* aTransport, MessageLoop* aIOLoop)
|
|||
|
||||
// FIXME/cjones: handle errors
|
||||
while (mChannelState != ChannelConnected) {
|
||||
mCvar.Wait();
|
||||
mMonitor.Wait();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,7 +175,7 @@ AsyncChannel::Close()
|
|||
AssertWorkerThread();
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
if (ChannelError == mChannelState ||
|
||||
ChannelTimeout == mChannelState) {
|
||||
|
@ -186,7 +185,7 @@ AsyncChannel::Close()
|
|||
// also be deleted and the listener will never be notified
|
||||
// of the channel error.
|
||||
if (mListener) {
|
||||
MutexAutoUnlock unlock(mMutex);
|
||||
MonitorAutoUnlock unlock(mMonitor);
|
||||
NotifyMaybeChannelError();
|
||||
}
|
||||
return;
|
||||
|
@ -212,24 +211,24 @@ void
|
|||
AsyncChannel::SynchronouslyClose()
|
||||
{
|
||||
AssertWorkerThread();
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
|
||||
mIOLoop->PostTask(
|
||||
FROM_HERE, NewRunnableMethod(this, &AsyncChannel::OnCloseChannel));
|
||||
|
||||
while (ChannelClosed != mChannelState)
|
||||
mCvar.Wait();
|
||||
mMonitor.Wait();
|
||||
}
|
||||
|
||||
bool
|
||||
AsyncChannel::Send(Message* msg)
|
||||
{
|
||||
AssertWorkerThread();
|
||||
mMutex.AssertNotCurrentThreadOwns();
|
||||
mMonitor.AssertNotCurrentThreadOwns();
|
||||
NS_ABORT_IF_FALSE(MSG_ROUTING_NONE != msg->routing_id(), "need a route");
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
if (!Connected()) {
|
||||
ReportConnectionError("AsyncChannel");
|
||||
|
@ -289,14 +288,14 @@ void
|
|||
AsyncChannel::OnNotifyMaybeChannelError()
|
||||
{
|
||||
AssertWorkerThread();
|
||||
mMutex.AssertNotCurrentThreadOwns();
|
||||
mMonitor.AssertNotCurrentThreadOwns();
|
||||
|
||||
// OnChannelError holds mMutex when it posts this task and this
|
||||
// OnChannelError holds mMonitor when it posts this task and this
|
||||
// task cannot be allowed to run until OnChannelError has
|
||||
// exited. We enforce that order by grabbing the mutex here which
|
||||
// should only continue once OnChannelError has completed.
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
|
@ -314,7 +313,7 @@ AsyncChannel::OnNotifyMaybeChannelError()
|
|||
void
|
||||
AsyncChannel::NotifyChannelClosed()
|
||||
{
|
||||
mMutex.AssertNotCurrentThreadOwns();
|
||||
mMonitor.AssertNotCurrentThreadOwns();
|
||||
|
||||
if (ChannelClosed != mChannelState)
|
||||
NS_RUNTIMEABORT("channel should have been closed!");
|
||||
|
@ -329,7 +328,7 @@ AsyncChannel::NotifyChannelClosed()
|
|||
void
|
||||
AsyncChannel::NotifyMaybeChannelError()
|
||||
{
|
||||
mMutex.AssertNotCurrentThreadOwns();
|
||||
mMonitor.AssertNotCurrentThreadOwns();
|
||||
|
||||
// TODO sort out Close() on this side racing with Close() on the
|
||||
// other side
|
||||
|
@ -456,7 +455,7 @@ AsyncChannel::OnMessageReceived(const Message& msg)
|
|||
AssertIOThread();
|
||||
NS_ASSERTION(mChannelState != ChannelError, "Shouldn't get here!");
|
||||
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
if (!MaybeInterceptSpecialIOMessage(msg))
|
||||
// wake up the worker, there's work to do
|
||||
|
@ -470,7 +469,7 @@ AsyncChannel::OnChannelOpened()
|
|||
{
|
||||
AssertIOThread();
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
mChannelState = ChannelOpening;
|
||||
}
|
||||
/*assert*/mTransport->Connect();
|
||||
|
@ -490,9 +489,9 @@ AsyncChannel::OnChannelConnected(int32 peer_pid)
|
|||
AssertIOThread();
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
mChannelState = ChannelConnected;
|
||||
mCvar.Notify();
|
||||
mMonitor.Notify();
|
||||
}
|
||||
|
||||
if(mExistingListener)
|
||||
|
@ -508,7 +507,7 @@ AsyncChannel::OnChannelError()
|
|||
{
|
||||
AssertIOThread();
|
||||
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
if (ChannelClosing != mChannelState)
|
||||
mChannelState = ChannelError;
|
||||
|
@ -520,7 +519,7 @@ void
|
|||
AsyncChannel::PostErrorNotifyTask()
|
||||
{
|
||||
AssertIOThread();
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
|
||||
NS_ASSERTION(!mChannelErrorTask, "OnChannelError called twice?");
|
||||
|
||||
|
@ -537,16 +536,16 @@ AsyncChannel::OnCloseChannel()
|
|||
|
||||
mTransport->Close();
|
||||
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
mChannelState = ChannelClosed;
|
||||
mCvar.Notify();
|
||||
mMonitor.Notify();
|
||||
}
|
||||
|
||||
bool
|
||||
AsyncChannel::MaybeInterceptSpecialIOMessage(const Message& msg)
|
||||
{
|
||||
AssertIOThread();
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
|
||||
if (MSG_ROUTING_NONE == msg.routing_id()
|
||||
&& GOODBYE_MESSAGE_TYPE == msg.type()) {
|
||||
|
@ -560,7 +559,7 @@ void
|
|||
AsyncChannel::ProcessGoodbyeMessage()
|
||||
{
|
||||
AssertIOThread();
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
|
||||
// TODO sort out Close() on this side racing with Close() on the
|
||||
// other side
|
||||
|
|
|
@ -44,8 +44,7 @@
|
|||
#include "base/message_loop.h"
|
||||
#include "chrome/common/ipc_channel.h"
|
||||
|
||||
#include "mozilla/CondVar.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/Monitor.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -70,8 +69,7 @@ struct HasResultCodes
|
|||
class AsyncChannel : public IPC::Channel::Listener, protected HasResultCodes
|
||||
{
|
||||
protected:
|
||||
typedef mozilla::CondVar CondVar;
|
||||
typedef mozilla::Mutex Mutex;
|
||||
typedef mozilla::Monitor Monitor;
|
||||
|
||||
enum ChannelState {
|
||||
ChannelClosed,
|
||||
|
@ -145,7 +143,7 @@ protected:
|
|||
}
|
||||
|
||||
bool Connected() const {
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
return ChannelConnected == mChannelState;
|
||||
}
|
||||
|
||||
|
@ -187,8 +185,7 @@ protected:
|
|||
Transport* mTransport;
|
||||
AsyncListener* mListener;
|
||||
ChannelState mChannelState;
|
||||
Mutex mMutex;
|
||||
CondVar mCvar;
|
||||
Monitor mMonitor;
|
||||
MessageLoop* mIOLoop; // thread where IO happens
|
||||
MessageLoop* mWorkerLoop; // thread where work is done
|
||||
bool mChild; // am I the child or parent?
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
#include "APKOpen.h"
|
||||
#endif
|
||||
|
||||
using mozilla::ReentrantMonitorAutoEnter;
|
||||
using mozilla::MonitorAutoLock;
|
||||
using mozilla::ipc::GeckoChildProcessHost;
|
||||
|
||||
#ifdef ANDROID
|
||||
|
@ -95,7 +95,7 @@ GeckoChildProcessHost::GeckoChildProcessHost(GeckoProcessType aProcessType,
|
|||
base::WaitableEventWatcher::Delegate* aDelegate)
|
||||
: ChildProcessHost(RENDER_PROCESS), // FIXME/cjones: we should own this enum
|
||||
mProcessType(aProcessType),
|
||||
mReentrantMonitor("mozilla.ipc.GeckChildProcessHost.mReentrantMonitor"),
|
||||
mMonitor("mozilla.ipc.GeckChildProcessHost.mMonitor"),
|
||||
mLaunched(false),
|
||||
mChannelInitialized(false),
|
||||
mDelegate(aDelegate),
|
||||
|
@ -289,14 +289,14 @@ GeckoChildProcessHost::SyncLaunch(std::vector<std::string> aExtraOpts, int aTime
|
|||
aExtraOpts, arch));
|
||||
// NB: this uses a different mechanism than the chromium parent
|
||||
// class.
|
||||
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
PRIntervalTime waitStart = PR_IntervalNow();
|
||||
PRIntervalTime current;
|
||||
|
||||
// We'll receive several notifications, we need to exit when we
|
||||
// have either successfully launched or have timed out.
|
||||
while (!mLaunched) {
|
||||
mon.Wait(timeoutTicks);
|
||||
lock.Wait(timeoutTicks);
|
||||
|
||||
if (timeoutTicks != PR_INTERVAL_NO_TIMEOUT) {
|
||||
current = PR_IntervalNow();
|
||||
|
@ -327,9 +327,9 @@ GeckoChildProcessHost::AsyncLaunch(std::vector<std::string> aExtraOpts)
|
|||
|
||||
// This may look like the sync launch wait, but we only delay as
|
||||
// long as it takes to create the channel.
|
||||
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
while (!mChannelInitialized) {
|
||||
mon.Wait();
|
||||
lock.Wait();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -340,9 +340,9 @@ GeckoChildProcessHost::InitializeChannel()
|
|||
{
|
||||
CreateChannel();
|
||||
|
||||
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
mChannelInitialized = true;
|
||||
mon.Notify();
|
||||
lock.Notify();
|
||||
}
|
||||
|
||||
PRInt32 GeckoChildProcessHost::mChildCounter = 0;
|
||||
|
@ -644,13 +644,13 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
|
|||
void
|
||||
GeckoChildProcessHost::OnChannelConnected(int32 peer_pid)
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
mLaunched = true;
|
||||
|
||||
if (!base::OpenPrivilegedProcessHandle(peer_pid, &mChildProcessHandle))
|
||||
NS_RUNTIMEABORT("can't open handle to child process");
|
||||
|
||||
mon.Notify();
|
||||
lock.Notify();
|
||||
}
|
||||
|
||||
// XXX/cjones: these next two methods should basically never be called.
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
#include "base/waitable_event.h"
|
||||
#include "chrome/common/child_process_host.h"
|
||||
|
||||
#include "mozilla/ReentrantMonitor.h"
|
||||
#include "mozilla/Monitor.h"
|
||||
|
||||
#include "nsXULAppAPI.h" // for GeckoProcessType
|
||||
#include "nsString.h"
|
||||
|
@ -54,7 +54,7 @@ namespace ipc {
|
|||
class GeckoChildProcessHost : public ChildProcessHost
|
||||
{
|
||||
protected:
|
||||
typedef mozilla::ReentrantMonitor ReentrantMonitor;
|
||||
typedef mozilla::Monitor Monitor;
|
||||
|
||||
public:
|
||||
typedef base::ProcessHandle ProcessHandle;
|
||||
|
@ -106,7 +106,7 @@ public:
|
|||
|
||||
protected:
|
||||
GeckoProcessType mProcessType;
|
||||
ReentrantMonitor mReentrantMonitor;
|
||||
Monitor mMonitor;
|
||||
bool mLaunched;
|
||||
bool mChannelInitialized;
|
||||
FilePath mProcessPath;
|
||||
|
|
|
@ -49,8 +49,8 @@
|
|||
DebugAbort(__FILE__, __LINE__, #_cond,## __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
using mozilla::MutexAutoLock;
|
||||
using mozilla::MutexAutoUnlock;
|
||||
using mozilla::MonitorAutoLock;
|
||||
using mozilla::MonitorAutoUnlock;
|
||||
|
||||
template<>
|
||||
struct RunnableMethodTraits<mozilla::ipc::RPCChannel>
|
||||
|
@ -124,7 +124,7 @@ bool
|
|||
RPCChannel::EventOccurred() const
|
||||
{
|
||||
AssertWorkerThread();
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
RPC_ASSERT(StackDepth() > 0, "not in wait loop");
|
||||
|
||||
return (!Connected() ||
|
||||
|
@ -154,7 +154,7 @@ bool
|
|||
RPCChannel::Call(Message* msg, Message* reply)
|
||||
{
|
||||
AssertWorkerThread();
|
||||
mMutex.AssertNotCurrentThreadOwns();
|
||||
mMonitor.AssertNotCurrentThreadOwns();
|
||||
RPC_ASSERT(!ProcessingSyncMessage(),
|
||||
"violation of sync handler invariant");
|
||||
RPC_ASSERT(msg->is_rpc(), "can only Call() RPC messages here");
|
||||
|
@ -166,7 +166,7 @@ RPCChannel::Call(Message* msg, Message* reply)
|
|||
Message copy = *msg;
|
||||
CxxStackFrame f(*this, OUT_MESSAGE, ©);
|
||||
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
if (!Connected()) {
|
||||
ReportConnectionError("RPCChannel");
|
||||
|
@ -238,7 +238,7 @@ RPCChannel::Call(Message* msg, Message* reply)
|
|||
}
|
||||
|
||||
if (!recvd.is_sync() && !recvd.is_rpc()) {
|
||||
MutexAutoUnlock unlock(mMutex);
|
||||
MonitorAutoUnlock unlock(mMonitor);
|
||||
|
||||
CxxStackFrame f(*this, IN_MESSAGE, &recvd);
|
||||
AsyncChannel::OnDispatchMessage(recvd);
|
||||
|
@ -249,7 +249,7 @@ RPCChannel::Call(Message* msg, Message* reply)
|
|||
if (recvd.is_sync()) {
|
||||
RPC_ASSERT(mPending.empty(),
|
||||
"other side should have been blocked");
|
||||
MutexAutoUnlock unlock(mMutex);
|
||||
MonitorAutoUnlock unlock(mMonitor);
|
||||
|
||||
CxxStackFrame f(*this, IN_MESSAGE, &recvd);
|
||||
SyncChannel::OnDispatchMessage(recvd);
|
||||
|
@ -301,10 +301,10 @@ RPCChannel::Call(Message* msg, Message* reply)
|
|||
|
||||
// in-call. process in a new stack frame.
|
||||
|
||||
// "snapshot" the current stack depth while we own the Mutex
|
||||
// "snapshot" the current stack depth while we own the Monitor
|
||||
size_t stackDepth = StackDepth();
|
||||
{
|
||||
MutexAutoUnlock unlock(mMutex);
|
||||
MonitorAutoUnlock unlock(mMonitor);
|
||||
// someone called in to us from the other side. handle the call
|
||||
CxxStackFrame f(*this, IN_MESSAGE, &recvd);
|
||||
Incall(recvd, stackDepth);
|
||||
|
@ -319,7 +319,7 @@ void
|
|||
RPCChannel::MaybeUndeferIncall()
|
||||
{
|
||||
AssertWorkerThread();
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
|
||||
if (mDeferred.empty())
|
||||
return;
|
||||
|
@ -348,7 +348,7 @@ void
|
|||
RPCChannel::EnqueuePendingMessages()
|
||||
{
|
||||
AssertWorkerThread();
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
|
||||
MaybeUndeferIncall();
|
||||
|
||||
|
@ -370,10 +370,10 @@ void
|
|||
RPCChannel::FlushPendingRPCQueue()
|
||||
{
|
||||
AssertWorkerThread();
|
||||
mMutex.AssertNotCurrentThreadOwns();
|
||||
mMonitor.AssertNotCurrentThreadOwns();
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
if (mDeferred.empty()) {
|
||||
if (mPending.empty())
|
||||
|
@ -395,11 +395,11 @@ RPCChannel::OnMaybeDequeueOne()
|
|||
// messages here
|
||||
|
||||
AssertWorkerThread();
|
||||
mMutex.AssertNotCurrentThreadOwns();
|
||||
mMonitor.AssertNotCurrentThreadOwns();
|
||||
|
||||
Message recvd;
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
if (!Connected()) {
|
||||
ReportConnectionError("RPCChannel");
|
||||
|
@ -439,7 +439,7 @@ void
|
|||
RPCChannel::Incall(const Message& call, size_t stackDepth)
|
||||
{
|
||||
AssertWorkerThread();
|
||||
mMutex.AssertNotCurrentThreadOwns();
|
||||
mMonitor.AssertNotCurrentThreadOwns();
|
||||
RPC_ASSERT(call.is_rpc() && !call.is_reply(), "wrong message type");
|
||||
|
||||
// Race detection: see the long comment near
|
||||
|
@ -502,7 +502,7 @@ void
|
|||
RPCChannel::DispatchIncall(const Message& call)
|
||||
{
|
||||
AssertWorkerThread();
|
||||
mMutex.AssertNotCurrentThreadOwns();
|
||||
mMonitor.AssertNotCurrentThreadOwns();
|
||||
RPC_ASSERT(call.is_rpc() && !call.is_reply(),
|
||||
"wrong message type");
|
||||
|
||||
|
@ -523,7 +523,7 @@ RPCChannel::DispatchIncall(const Message& call)
|
|||
reply->set_seqno(call.seqno());
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
if (ChannelConnected == mChannelState)
|
||||
SendThroughTransport(reply);
|
||||
}
|
||||
|
@ -578,7 +578,7 @@ RPCChannel::BlockOnParent()
|
|||
if (!mChild)
|
||||
NS_RUNTIMEABORT("child tried to block parent");
|
||||
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
if (mBlockedOnParent || AwaitingSyncReply() || 0 < StackDepth())
|
||||
NS_RUNTIMEABORT("attempt to block child when it's already blocked");
|
||||
|
@ -602,7 +602,7 @@ RPCChannel::BlockOnParent()
|
|||
Message recvd = mPending.front();
|
||||
mPending.pop();
|
||||
|
||||
MutexAutoUnlock unlock(mMutex);
|
||||
MonitorAutoUnlock unlock(mMonitor);
|
||||
|
||||
CxxStackFrame f(*this, IN_MESSAGE, &recvd);
|
||||
if (recvd.is_rpc()) {
|
||||
|
@ -628,7 +628,7 @@ RPCChannel::UnblockFromParent()
|
|||
|
||||
if (!mChild)
|
||||
NS_RUNTIMEABORT("child tried to block parent");
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
mBlockedOnParent = false;
|
||||
}
|
||||
|
||||
|
@ -637,7 +637,7 @@ RPCChannel::ExitedCxxStack()
|
|||
{
|
||||
Listener()->OnExitedCxxStack();
|
||||
if (mSawRPCOutMsg) {
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
// see long comment in OnMaybeDequeueOne()
|
||||
EnqueuePendingMessages();
|
||||
mSawRPCOutMsg = false;
|
||||
|
@ -710,7 +710,7 @@ void
|
|||
RPCChannel::OnMessageReceived(const Message& msg)
|
||||
{
|
||||
AssertIOThread();
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
if (MaybeInterceptSpecialIOMessage(msg))
|
||||
return;
|
||||
|
@ -740,7 +740,7 @@ RPCChannel::OnChannelError()
|
|||
{
|
||||
AssertIOThread();
|
||||
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
if (ChannelClosing != mChannelState)
|
||||
mChannelState = ChannelError;
|
||||
|
|
|
@ -311,7 +311,7 @@ protected:
|
|||
|
||||
// Called from both threads
|
||||
size_t StackDepth() const {
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
return mStack.size();
|
||||
}
|
||||
|
||||
|
@ -425,7 +425,7 @@ protected:
|
|||
// !mCxxStackFrames.empty() => RPCChannel code on C++ stack
|
||||
//
|
||||
// This member is only accessed on the worker thread, and so is
|
||||
// not protected by mMutex. It is managed exclusively by the
|
||||
// not protected by mMonitor. It is managed exclusively by the
|
||||
// helper |class CxxStackFrame|.
|
||||
std::vector<RPCFrame> mCxxStackFrames;
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
#include "nsDebug.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
|
||||
using mozilla::MutexAutoLock;
|
||||
using mozilla::MonitorAutoLock;
|
||||
|
||||
template<>
|
||||
struct RunnableMethodTraits<mozilla::ipc::SyncChannel>
|
||||
|
@ -88,7 +88,7 @@ bool
|
|||
SyncChannel::EventOccurred()
|
||||
{
|
||||
AssertWorkerThread();
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
NS_ABORT_IF_FALSE(AwaitingSyncReply(), "not in wait loop");
|
||||
|
||||
return (!Connected() || 0 != mRecvd.type());
|
||||
|
@ -98,7 +98,7 @@ bool
|
|||
SyncChannel::Send(Message* msg, Message* reply)
|
||||
{
|
||||
AssertWorkerThread();
|
||||
mMutex.AssertNotCurrentThreadOwns();
|
||||
mMonitor.AssertNotCurrentThreadOwns();
|
||||
NS_ABORT_IF_FALSE(!ProcessingSyncMessage(),
|
||||
"violation of sync handler invariant");
|
||||
NS_ABORT_IF_FALSE(msg->is_sync(), "can only Send() sync messages here");
|
||||
|
@ -109,7 +109,7 @@ SyncChannel::Send(Message* msg, Message* reply)
|
|||
|
||||
msg->set_seqno(NextSeqno());
|
||||
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
if (!Connected()) {
|
||||
ReportConnectionError("SyncChannel");
|
||||
|
@ -181,7 +181,7 @@ SyncChannel::OnDispatchMessage(const Message& msg)
|
|||
reply->set_seqno(msg.seqno());
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
if (ChannelConnected == mChannelState)
|
||||
SendThroughTransport(reply);
|
||||
}
|
||||
|
@ -200,7 +200,7 @@ SyncChannel::OnMessageReceived(const Message& msg)
|
|||
return AsyncChannel::OnMessageReceived(msg);
|
||||
}
|
||||
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
if (MaybeInterceptSpecialIOMessage(msg))
|
||||
return;
|
||||
|
@ -223,7 +223,7 @@ SyncChannel::OnChannelError()
|
|||
{
|
||||
AssertIOThread();
|
||||
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
if (ChannelClosing != mChannelState)
|
||||
mChannelState = ChannelError;
|
||||
|
@ -253,11 +253,11 @@ bool
|
|||
SyncChannel::ShouldContinueFromTimeout()
|
||||
{
|
||||
AssertWorkerThread();
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
|
||||
bool cont;
|
||||
{
|
||||
MutexAutoUnlock unlock(mMutex);
|
||||
MonitorAutoUnlock unlock(mMonitor);
|
||||
cont = static_cast<SyncListener*>(mListener)->OnReplyTimeout();
|
||||
}
|
||||
|
||||
|
@ -295,7 +295,7 @@ SyncChannel::WaitForNotify()
|
|||
// XXX could optimize away this syscall for "no timeout" case if desired
|
||||
PRIntervalTime waitStart = PR_IntervalNow();
|
||||
|
||||
mCvar.Wait(timeout);
|
||||
mMonitor.Wait(timeout);
|
||||
|
||||
// if the timeout didn't expire, we know we received an event.
|
||||
// The converse is not true.
|
||||
|
@ -305,7 +305,7 @@ SyncChannel::WaitForNotify()
|
|||
void
|
||||
SyncChannel::NotifyWorkerThread()
|
||||
{
|
||||
mCvar.Notify();
|
||||
mMonitor.Notify();
|
||||
}
|
||||
|
||||
#endif // ifndef OS_WIN
|
||||
|
|
|
@ -171,7 +171,7 @@ protected:
|
|||
|
||||
// On both
|
||||
bool AwaitingSyncReply() const {
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
return mPendingReply != 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -655,7 +655,7 @@ RPCChannel::SpinInternalEventLoop()
|
|||
|
||||
// Don't get wrapped up in here if the child connection dies.
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
if (!Connected()) {
|
||||
return;
|
||||
}
|
||||
|
@ -692,7 +692,7 @@ RPCChannel::SpinInternalEventLoop()
|
|||
bool
|
||||
SyncChannel::WaitForNotify()
|
||||
{
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
|
||||
// Initialize global objects used in deferred messaging.
|
||||
Init();
|
||||
|
@ -700,7 +700,7 @@ SyncChannel::WaitForNotify()
|
|||
NS_ASSERTION(mTopFrame && !mTopFrame->mRPC,
|
||||
"Top frame is not a sync frame!");
|
||||
|
||||
MutexAutoUnlock unlock(mMutex);
|
||||
MonitorAutoUnlock unlock(mMonitor);
|
||||
|
||||
bool retval = true;
|
||||
|
||||
|
@ -730,7 +730,7 @@ SyncChannel::WaitForNotify()
|
|||
MSG msg = { 0 };
|
||||
// Don't get wrapped up in here if the child connection dies.
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
if (!Connected()) {
|
||||
break;
|
||||
}
|
||||
|
@ -814,7 +814,7 @@ SyncChannel::WaitForNotify()
|
|||
bool
|
||||
RPCChannel::WaitForNotify()
|
||||
{
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
|
||||
if (!StackDepth() && !mBlockedOnParent) {
|
||||
// There is currently no way to recover from this condition.
|
||||
|
@ -827,7 +827,7 @@ RPCChannel::WaitForNotify()
|
|||
NS_ASSERTION(mTopFrame && mTopFrame->mRPC,
|
||||
"Top frame is not a sync frame!");
|
||||
|
||||
MutexAutoUnlock unlock(mMutex);
|
||||
MonitorAutoUnlock unlock(mMonitor);
|
||||
|
||||
bool retval = true;
|
||||
|
||||
|
@ -890,7 +890,7 @@ RPCChannel::WaitForNotify()
|
|||
|
||||
// Don't get wrapped up in here if the child connection dies.
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
if (!Connected()) {
|
||||
break;
|
||||
}
|
||||
|
@ -954,7 +954,7 @@ RPCChannel::WaitForNotify()
|
|||
void
|
||||
SyncChannel::NotifyWorkerThread()
|
||||
{
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
NS_ASSERTION(mEvent, "No signal event to set, this is really bad!");
|
||||
if (!SetEvent(mEvent)) {
|
||||
NS_WARNING("Failed to set NotifyWorkerThread event!");
|
||||
|
|
Загрузка…
Ссылка в новой задаче