Bug 556214, part 3: IPC code wants to be using non-reentrant Monitor. r=bent

This commit is contained in:
Chris Jones 2011-04-29 14:21:57 -05:00
Родитель 6a87d2af28
Коммит 240e3f8d9e
9 изменённых файлов: 88 добавлений и 92 удалений

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

@ -45,7 +45,7 @@
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"
#include "nsXULAppAPI.h" #include "nsXULAppAPI.h"
using mozilla::MutexAutoLock; using mozilla::MonitorAutoLock;
template<> template<>
struct RunnableMethodTraits<mozilla::ipc::AsyncChannel> struct RunnableMethodTraits<mozilla::ipc::AsyncChannel>
@ -106,8 +106,7 @@ AsyncChannel::AsyncChannel(AsyncListener* aListener)
: mTransport(0), : mTransport(0),
mListener(aListener), mListener(aListener),
mChannelState(ChannelClosed), mChannelState(ChannelClosed),
mMutex("mozilla.ipc.AsyncChannel.mMutex"), mMonitor("mozilla.ipc.AsyncChannel.mMonitor"),
mCvar(mMutex, "mozilla.ipc.AsyncChannel.mCvar"),
mIOLoop(), mIOLoop(),
mWorkerLoop(), mWorkerLoop(),
mChild(false), mChild(false),
@ -155,7 +154,7 @@ AsyncChannel::Open(Transport* aTransport, MessageLoop* aIOLoop)
NS_ASSERTION(mWorkerLoop, "need a worker loop"); NS_ASSERTION(mWorkerLoop, "need a worker loop");
if (needOpen) { // child process if (needOpen) { // child process
MutexAutoLock lock(mMutex); MonitorAutoLock lock(mMonitor);
mIOLoop->PostTask(FROM_HERE, mIOLoop->PostTask(FROM_HERE,
NewRunnableMethod(this, NewRunnableMethod(this,
@ -163,7 +162,7 @@ AsyncChannel::Open(Transport* aTransport, MessageLoop* aIOLoop)
// FIXME/cjones: handle errors // FIXME/cjones: handle errors
while (mChannelState != ChannelConnected) { while (mChannelState != ChannelConnected) {
mCvar.Wait(); mMonitor.Wait();
} }
} }
@ -176,7 +175,7 @@ AsyncChannel::Close()
AssertWorkerThread(); AssertWorkerThread();
{ {
MutexAutoLock lock(mMutex); MonitorAutoLock lock(mMonitor);
if (ChannelError == mChannelState || if (ChannelError == mChannelState ||
ChannelTimeout == mChannelState) { ChannelTimeout == mChannelState) {
@ -186,7 +185,7 @@ AsyncChannel::Close()
// also be deleted and the listener will never be notified // also be deleted and the listener will never be notified
// of the channel error. // of the channel error.
if (mListener) { if (mListener) {
MutexAutoUnlock unlock(mMutex); MonitorAutoUnlock unlock(mMonitor);
NotifyMaybeChannelError(); NotifyMaybeChannelError();
} }
return; return;
@ -212,24 +211,24 @@ void
AsyncChannel::SynchronouslyClose() AsyncChannel::SynchronouslyClose()
{ {
AssertWorkerThread(); AssertWorkerThread();
mMutex.AssertCurrentThreadOwns(); mMonitor.AssertCurrentThreadOwns();
mIOLoop->PostTask( mIOLoop->PostTask(
FROM_HERE, NewRunnableMethod(this, &AsyncChannel::OnCloseChannel)); FROM_HERE, NewRunnableMethod(this, &AsyncChannel::OnCloseChannel));
while (ChannelClosed != mChannelState) while (ChannelClosed != mChannelState)
mCvar.Wait(); mMonitor.Wait();
} }
bool bool
AsyncChannel::Send(Message* msg) AsyncChannel::Send(Message* msg)
{ {
AssertWorkerThread(); AssertWorkerThread();
mMutex.AssertNotCurrentThreadOwns(); mMonitor.AssertNotCurrentThreadOwns();
NS_ABORT_IF_FALSE(MSG_ROUTING_NONE != msg->routing_id(), "need a route"); NS_ABORT_IF_FALSE(MSG_ROUTING_NONE != msg->routing_id(), "need a route");
{ {
MutexAutoLock lock(mMutex); MonitorAutoLock lock(mMonitor);
if (!Connected()) { if (!Connected()) {
ReportConnectionError("AsyncChannel"); ReportConnectionError("AsyncChannel");
@ -289,14 +288,14 @@ void
AsyncChannel::OnNotifyMaybeChannelError() AsyncChannel::OnNotifyMaybeChannelError()
{ {
AssertWorkerThread(); 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 // task cannot be allowed to run until OnChannelError has
// exited. We enforce that order by grabbing the mutex here which // exited. We enforce that order by grabbing the mutex here which
// should only continue once OnChannelError has completed. // should only continue once OnChannelError has completed.
{ {
MutexAutoLock lock(mMutex); MonitorAutoLock lock(mMonitor);
// nothing to do here // nothing to do here
} }
@ -314,7 +313,7 @@ AsyncChannel::OnNotifyMaybeChannelError()
void void
AsyncChannel::NotifyChannelClosed() AsyncChannel::NotifyChannelClosed()
{ {
mMutex.AssertNotCurrentThreadOwns(); mMonitor.AssertNotCurrentThreadOwns();
if (ChannelClosed != mChannelState) if (ChannelClosed != mChannelState)
NS_RUNTIMEABORT("channel should have been closed!"); NS_RUNTIMEABORT("channel should have been closed!");
@ -329,7 +328,7 @@ AsyncChannel::NotifyChannelClosed()
void void
AsyncChannel::NotifyMaybeChannelError() AsyncChannel::NotifyMaybeChannelError()
{ {
mMutex.AssertNotCurrentThreadOwns(); mMonitor.AssertNotCurrentThreadOwns();
// TODO sort out Close() on this side racing with Close() on the // TODO sort out Close() on this side racing with Close() on the
// other side // other side
@ -456,7 +455,7 @@ AsyncChannel::OnMessageReceived(const Message& msg)
AssertIOThread(); AssertIOThread();
NS_ASSERTION(mChannelState != ChannelError, "Shouldn't get here!"); NS_ASSERTION(mChannelState != ChannelError, "Shouldn't get here!");
MutexAutoLock lock(mMutex); MonitorAutoLock lock(mMonitor);
if (!MaybeInterceptSpecialIOMessage(msg)) if (!MaybeInterceptSpecialIOMessage(msg))
// wake up the worker, there's work to do // wake up the worker, there's work to do
@ -470,7 +469,7 @@ AsyncChannel::OnChannelOpened()
{ {
AssertIOThread(); AssertIOThread();
{ {
MutexAutoLock lock(mMutex); MonitorAutoLock lock(mMonitor);
mChannelState = ChannelOpening; mChannelState = ChannelOpening;
} }
/*assert*/mTransport->Connect(); /*assert*/mTransport->Connect();
@ -490,9 +489,9 @@ AsyncChannel::OnChannelConnected(int32 peer_pid)
AssertIOThread(); AssertIOThread();
{ {
MutexAutoLock lock(mMutex); MonitorAutoLock lock(mMonitor);
mChannelState = ChannelConnected; mChannelState = ChannelConnected;
mCvar.Notify(); mMonitor.Notify();
} }
if(mExistingListener) if(mExistingListener)
@ -508,7 +507,7 @@ AsyncChannel::OnChannelError()
{ {
AssertIOThread(); AssertIOThread();
MutexAutoLock lock(mMutex); MonitorAutoLock lock(mMonitor);
if (ChannelClosing != mChannelState) if (ChannelClosing != mChannelState)
mChannelState = ChannelError; mChannelState = ChannelError;
@ -520,7 +519,7 @@ void
AsyncChannel::PostErrorNotifyTask() AsyncChannel::PostErrorNotifyTask()
{ {
AssertIOThread(); AssertIOThread();
mMutex.AssertCurrentThreadOwns(); mMonitor.AssertCurrentThreadOwns();
NS_ASSERTION(!mChannelErrorTask, "OnChannelError called twice?"); NS_ASSERTION(!mChannelErrorTask, "OnChannelError called twice?");
@ -537,16 +536,16 @@ AsyncChannel::OnCloseChannel()
mTransport->Close(); mTransport->Close();
MutexAutoLock lock(mMutex); MonitorAutoLock lock(mMonitor);
mChannelState = ChannelClosed; mChannelState = ChannelClosed;
mCvar.Notify(); mMonitor.Notify();
} }
bool bool
AsyncChannel::MaybeInterceptSpecialIOMessage(const Message& msg) AsyncChannel::MaybeInterceptSpecialIOMessage(const Message& msg)
{ {
AssertIOThread(); AssertIOThread();
mMutex.AssertCurrentThreadOwns(); mMonitor.AssertCurrentThreadOwns();
if (MSG_ROUTING_NONE == msg.routing_id() if (MSG_ROUTING_NONE == msg.routing_id()
&& GOODBYE_MESSAGE_TYPE == msg.type()) { && GOODBYE_MESSAGE_TYPE == msg.type()) {
@ -560,7 +559,7 @@ void
AsyncChannel::ProcessGoodbyeMessage() AsyncChannel::ProcessGoodbyeMessage()
{ {
AssertIOThread(); AssertIOThread();
mMutex.AssertCurrentThreadOwns(); mMonitor.AssertCurrentThreadOwns();
// TODO sort out Close() on this side racing with Close() on the // TODO sort out Close() on this side racing with Close() on the
// other side // other side

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

@ -44,8 +44,7 @@
#include "base/message_loop.h" #include "base/message_loop.h"
#include "chrome/common/ipc_channel.h" #include "chrome/common/ipc_channel.h"
#include "mozilla/CondVar.h" #include "mozilla/Monitor.h"
#include "mozilla/Mutex.h"
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -70,8 +69,7 @@ struct HasResultCodes
class AsyncChannel : public IPC::Channel::Listener, protected HasResultCodes class AsyncChannel : public IPC::Channel::Listener, protected HasResultCodes
{ {
protected: protected:
typedef mozilla::CondVar CondVar; typedef mozilla::Monitor Monitor;
typedef mozilla::Mutex Mutex;
enum ChannelState { enum ChannelState {
ChannelClosed, ChannelClosed,
@ -145,7 +143,7 @@ protected:
} }
bool Connected() const { bool Connected() const {
mMutex.AssertCurrentThreadOwns(); mMonitor.AssertCurrentThreadOwns();
return ChannelConnected == mChannelState; return ChannelConnected == mChannelState;
} }
@ -187,8 +185,7 @@ protected:
Transport* mTransport; Transport* mTransport;
AsyncListener* mListener; AsyncListener* mListener;
ChannelState mChannelState; ChannelState mChannelState;
Mutex mMutex; Monitor mMonitor;
CondVar mCvar;
MessageLoop* mIOLoop; // thread where IO happens MessageLoop* mIOLoop; // thread where IO happens
MessageLoop* mWorkerLoop; // thread where work is done MessageLoop* mWorkerLoop; // thread where work is done
bool mChild; // am I the child or parent? bool mChild; // am I the child or parent?

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

@ -74,7 +74,7 @@
#include "APKOpen.h" #include "APKOpen.h"
#endif #endif
using mozilla::ReentrantMonitorAutoEnter; using mozilla::MonitorAutoLock;
using mozilla::ipc::GeckoChildProcessHost; using mozilla::ipc::GeckoChildProcessHost;
#ifdef ANDROID #ifdef ANDROID
@ -95,7 +95,7 @@ GeckoChildProcessHost::GeckoChildProcessHost(GeckoProcessType aProcessType,
base::WaitableEventWatcher::Delegate* aDelegate) base::WaitableEventWatcher::Delegate* aDelegate)
: ChildProcessHost(RENDER_PROCESS), // FIXME/cjones: we should own this enum : ChildProcessHost(RENDER_PROCESS), // FIXME/cjones: we should own this enum
mProcessType(aProcessType), mProcessType(aProcessType),
mReentrantMonitor("mozilla.ipc.GeckChildProcessHost.mReentrantMonitor"), mMonitor("mozilla.ipc.GeckChildProcessHost.mMonitor"),
mLaunched(false), mLaunched(false),
mChannelInitialized(false), mChannelInitialized(false),
mDelegate(aDelegate), mDelegate(aDelegate),
@ -289,14 +289,14 @@ GeckoChildProcessHost::SyncLaunch(std::vector<std::string> aExtraOpts, int aTime
aExtraOpts, arch)); aExtraOpts, arch));
// NB: this uses a different mechanism than the chromium parent // NB: this uses a different mechanism than the chromium parent
// class. // class.
ReentrantMonitorAutoEnter mon(mReentrantMonitor); MonitorAutoLock lock(mMonitor);
PRIntervalTime waitStart = PR_IntervalNow(); PRIntervalTime waitStart = PR_IntervalNow();
PRIntervalTime current; PRIntervalTime current;
// We'll receive several notifications, we need to exit when we // We'll receive several notifications, we need to exit when we
// have either successfully launched or have timed out. // have either successfully launched or have timed out.
while (!mLaunched) { while (!mLaunched) {
mon.Wait(timeoutTicks); lock.Wait(timeoutTicks);
if (timeoutTicks != PR_INTERVAL_NO_TIMEOUT) { if (timeoutTicks != PR_INTERVAL_NO_TIMEOUT) {
current = PR_IntervalNow(); 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 // This may look like the sync launch wait, but we only delay as
// long as it takes to create the channel. // long as it takes to create the channel.
ReentrantMonitorAutoEnter mon(mReentrantMonitor); MonitorAutoLock lock(mMonitor);
while (!mChannelInitialized) { while (!mChannelInitialized) {
mon.Wait(); lock.Wait();
} }
return true; return true;
@ -340,9 +340,9 @@ GeckoChildProcessHost::InitializeChannel()
{ {
CreateChannel(); CreateChannel();
ReentrantMonitorAutoEnter mon(mReentrantMonitor); MonitorAutoLock lock(mMonitor);
mChannelInitialized = true; mChannelInitialized = true;
mon.Notify(); lock.Notify();
} }
PRInt32 GeckoChildProcessHost::mChildCounter = 0; PRInt32 GeckoChildProcessHost::mChildCounter = 0;
@ -644,13 +644,13 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
void void
GeckoChildProcessHost::OnChannelConnected(int32 peer_pid) GeckoChildProcessHost::OnChannelConnected(int32 peer_pid)
{ {
ReentrantMonitorAutoEnter mon(mReentrantMonitor); MonitorAutoLock lock(mMonitor);
mLaunched = true; mLaunched = true;
if (!base::OpenPrivilegedProcessHandle(peer_pid, &mChildProcessHandle)) if (!base::OpenPrivilegedProcessHandle(peer_pid, &mChildProcessHandle))
NS_RUNTIMEABORT("can't open handle to child process"); NS_RUNTIMEABORT("can't open handle to child process");
mon.Notify(); lock.Notify();
} }
// XXX/cjones: these next two methods should basically never be called. // XXX/cjones: these next two methods should basically never be called.

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

@ -43,7 +43,7 @@
#include "base/waitable_event.h" #include "base/waitable_event.h"
#include "chrome/common/child_process_host.h" #include "chrome/common/child_process_host.h"
#include "mozilla/ReentrantMonitor.h" #include "mozilla/Monitor.h"
#include "nsXULAppAPI.h" // for GeckoProcessType #include "nsXULAppAPI.h" // for GeckoProcessType
#include "nsString.h" #include "nsString.h"
@ -54,7 +54,7 @@ namespace ipc {
class GeckoChildProcessHost : public ChildProcessHost class GeckoChildProcessHost : public ChildProcessHost
{ {
protected: protected:
typedef mozilla::ReentrantMonitor ReentrantMonitor; typedef mozilla::Monitor Monitor;
public: public:
typedef base::ProcessHandle ProcessHandle; typedef base::ProcessHandle ProcessHandle;
@ -106,7 +106,7 @@ public:
protected: protected:
GeckoProcessType mProcessType; GeckoProcessType mProcessType;
ReentrantMonitor mReentrantMonitor; Monitor mMonitor;
bool mLaunched; bool mLaunched;
bool mChannelInitialized; bool mChannelInitialized;
FilePath mProcessPath; FilePath mProcessPath;

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

@ -49,8 +49,8 @@
DebugAbort(__FILE__, __LINE__, #_cond,## __VA_ARGS__); \ DebugAbort(__FILE__, __LINE__, #_cond,## __VA_ARGS__); \
} while (0) } while (0)
using mozilla::MutexAutoLock; using mozilla::MonitorAutoLock;
using mozilla::MutexAutoUnlock; using mozilla::MonitorAutoUnlock;
template<> template<>
struct RunnableMethodTraits<mozilla::ipc::RPCChannel> struct RunnableMethodTraits<mozilla::ipc::RPCChannel>
@ -124,7 +124,7 @@ bool
RPCChannel::EventOccurred() const RPCChannel::EventOccurred() const
{ {
AssertWorkerThread(); AssertWorkerThread();
mMutex.AssertCurrentThreadOwns(); mMonitor.AssertCurrentThreadOwns();
RPC_ASSERT(StackDepth() > 0, "not in wait loop"); RPC_ASSERT(StackDepth() > 0, "not in wait loop");
return (!Connected() || return (!Connected() ||
@ -154,7 +154,7 @@ bool
RPCChannel::Call(Message* msg, Message* reply) RPCChannel::Call(Message* msg, Message* reply)
{ {
AssertWorkerThread(); AssertWorkerThread();
mMutex.AssertNotCurrentThreadOwns(); mMonitor.AssertNotCurrentThreadOwns();
RPC_ASSERT(!ProcessingSyncMessage(), RPC_ASSERT(!ProcessingSyncMessage(),
"violation of sync handler invariant"); "violation of sync handler invariant");
RPC_ASSERT(msg->is_rpc(), "can only Call() RPC messages here"); RPC_ASSERT(msg->is_rpc(), "can only Call() RPC messages here");
@ -166,7 +166,7 @@ RPCChannel::Call(Message* msg, Message* reply)
Message copy = *msg; Message copy = *msg;
CxxStackFrame f(*this, OUT_MESSAGE, &copy); CxxStackFrame f(*this, OUT_MESSAGE, &copy);
MutexAutoLock lock(mMutex); MonitorAutoLock lock(mMonitor);
if (!Connected()) { if (!Connected()) {
ReportConnectionError("RPCChannel"); ReportConnectionError("RPCChannel");
@ -238,7 +238,7 @@ RPCChannel::Call(Message* msg, Message* reply)
} }
if (!recvd.is_sync() && !recvd.is_rpc()) { if (!recvd.is_sync() && !recvd.is_rpc()) {
MutexAutoUnlock unlock(mMutex); MonitorAutoUnlock unlock(mMonitor);
CxxStackFrame f(*this, IN_MESSAGE, &recvd); CxxStackFrame f(*this, IN_MESSAGE, &recvd);
AsyncChannel::OnDispatchMessage(recvd); AsyncChannel::OnDispatchMessage(recvd);
@ -249,7 +249,7 @@ RPCChannel::Call(Message* msg, Message* reply)
if (recvd.is_sync()) { if (recvd.is_sync()) {
RPC_ASSERT(mPending.empty(), RPC_ASSERT(mPending.empty(),
"other side should have been blocked"); "other side should have been blocked");
MutexAutoUnlock unlock(mMutex); MonitorAutoUnlock unlock(mMonitor);
CxxStackFrame f(*this, IN_MESSAGE, &recvd); CxxStackFrame f(*this, IN_MESSAGE, &recvd);
SyncChannel::OnDispatchMessage(recvd); SyncChannel::OnDispatchMessage(recvd);
@ -301,10 +301,10 @@ RPCChannel::Call(Message* msg, Message* reply)
// in-call. process in a new stack frame. // 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(); size_t stackDepth = StackDepth();
{ {
MutexAutoUnlock unlock(mMutex); MonitorAutoUnlock unlock(mMonitor);
// someone called in to us from the other side. handle the call // someone called in to us from the other side. handle the call
CxxStackFrame f(*this, IN_MESSAGE, &recvd); CxxStackFrame f(*this, IN_MESSAGE, &recvd);
Incall(recvd, stackDepth); Incall(recvd, stackDepth);
@ -319,7 +319,7 @@ void
RPCChannel::MaybeUndeferIncall() RPCChannel::MaybeUndeferIncall()
{ {
AssertWorkerThread(); AssertWorkerThread();
mMutex.AssertCurrentThreadOwns(); mMonitor.AssertCurrentThreadOwns();
if (mDeferred.empty()) if (mDeferred.empty())
return; return;
@ -348,7 +348,7 @@ void
RPCChannel::EnqueuePendingMessages() RPCChannel::EnqueuePendingMessages()
{ {
AssertWorkerThread(); AssertWorkerThread();
mMutex.AssertCurrentThreadOwns(); mMonitor.AssertCurrentThreadOwns();
MaybeUndeferIncall(); MaybeUndeferIncall();
@ -370,10 +370,10 @@ void
RPCChannel::FlushPendingRPCQueue() RPCChannel::FlushPendingRPCQueue()
{ {
AssertWorkerThread(); AssertWorkerThread();
mMutex.AssertNotCurrentThreadOwns(); mMonitor.AssertNotCurrentThreadOwns();
{ {
MutexAutoLock lock(mMutex); MonitorAutoLock lock(mMonitor);
if (mDeferred.empty()) { if (mDeferred.empty()) {
if (mPending.empty()) if (mPending.empty())
@ -395,11 +395,11 @@ RPCChannel::OnMaybeDequeueOne()
// messages here // messages here
AssertWorkerThread(); AssertWorkerThread();
mMutex.AssertNotCurrentThreadOwns(); mMonitor.AssertNotCurrentThreadOwns();
Message recvd; Message recvd;
{ {
MutexAutoLock lock(mMutex); MonitorAutoLock lock(mMonitor);
if (!Connected()) { if (!Connected()) {
ReportConnectionError("RPCChannel"); ReportConnectionError("RPCChannel");
@ -439,7 +439,7 @@ void
RPCChannel::Incall(const Message& call, size_t stackDepth) RPCChannel::Incall(const Message& call, size_t stackDepth)
{ {
AssertWorkerThread(); AssertWorkerThread();
mMutex.AssertNotCurrentThreadOwns(); mMonitor.AssertNotCurrentThreadOwns();
RPC_ASSERT(call.is_rpc() && !call.is_reply(), "wrong message type"); RPC_ASSERT(call.is_rpc() && !call.is_reply(), "wrong message type");
// Race detection: see the long comment near // Race detection: see the long comment near
@ -502,7 +502,7 @@ void
RPCChannel::DispatchIncall(const Message& call) RPCChannel::DispatchIncall(const Message& call)
{ {
AssertWorkerThread(); AssertWorkerThread();
mMutex.AssertNotCurrentThreadOwns(); mMonitor.AssertNotCurrentThreadOwns();
RPC_ASSERT(call.is_rpc() && !call.is_reply(), RPC_ASSERT(call.is_rpc() && !call.is_reply(),
"wrong message type"); "wrong message type");
@ -523,7 +523,7 @@ RPCChannel::DispatchIncall(const Message& call)
reply->set_seqno(call.seqno()); reply->set_seqno(call.seqno());
{ {
MutexAutoLock lock(mMutex); MonitorAutoLock lock(mMonitor);
if (ChannelConnected == mChannelState) if (ChannelConnected == mChannelState)
SendThroughTransport(reply); SendThroughTransport(reply);
} }
@ -578,7 +578,7 @@ RPCChannel::BlockOnParent()
if (!mChild) if (!mChild)
NS_RUNTIMEABORT("child tried to block parent"); NS_RUNTIMEABORT("child tried to block parent");
MutexAutoLock lock(mMutex); MonitorAutoLock lock(mMonitor);
if (mBlockedOnParent || AwaitingSyncReply() || 0 < StackDepth()) if (mBlockedOnParent || AwaitingSyncReply() || 0 < StackDepth())
NS_RUNTIMEABORT("attempt to block child when it's already blocked"); NS_RUNTIMEABORT("attempt to block child when it's already blocked");
@ -602,7 +602,7 @@ RPCChannel::BlockOnParent()
Message recvd = mPending.front(); Message recvd = mPending.front();
mPending.pop(); mPending.pop();
MutexAutoUnlock unlock(mMutex); MonitorAutoUnlock unlock(mMonitor);
CxxStackFrame f(*this, IN_MESSAGE, &recvd); CxxStackFrame f(*this, IN_MESSAGE, &recvd);
if (recvd.is_rpc()) { if (recvd.is_rpc()) {
@ -628,7 +628,7 @@ RPCChannel::UnblockFromParent()
if (!mChild) if (!mChild)
NS_RUNTIMEABORT("child tried to block parent"); NS_RUNTIMEABORT("child tried to block parent");
MutexAutoLock lock(mMutex); MonitorAutoLock lock(mMonitor);
mBlockedOnParent = false; mBlockedOnParent = false;
} }
@ -637,7 +637,7 @@ RPCChannel::ExitedCxxStack()
{ {
Listener()->OnExitedCxxStack(); Listener()->OnExitedCxxStack();
if (mSawRPCOutMsg) { if (mSawRPCOutMsg) {
MutexAutoLock lock(mMutex); MonitorAutoLock lock(mMonitor);
// see long comment in OnMaybeDequeueOne() // see long comment in OnMaybeDequeueOne()
EnqueuePendingMessages(); EnqueuePendingMessages();
mSawRPCOutMsg = false; mSawRPCOutMsg = false;
@ -710,7 +710,7 @@ void
RPCChannel::OnMessageReceived(const Message& msg) RPCChannel::OnMessageReceived(const Message& msg)
{ {
AssertIOThread(); AssertIOThread();
MutexAutoLock lock(mMutex); MonitorAutoLock lock(mMonitor);
if (MaybeInterceptSpecialIOMessage(msg)) if (MaybeInterceptSpecialIOMessage(msg))
return; return;
@ -740,7 +740,7 @@ RPCChannel::OnChannelError()
{ {
AssertIOThread(); AssertIOThread();
MutexAutoLock lock(mMutex); MonitorAutoLock lock(mMonitor);
if (ChannelClosing != mChannelState) if (ChannelClosing != mChannelState)
mChannelState = ChannelError; mChannelState = ChannelError;

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

@ -311,7 +311,7 @@ protected:
// Called from both threads // Called from both threads
size_t StackDepth() const { size_t StackDepth() const {
mMutex.AssertCurrentThreadOwns(); mMonitor.AssertCurrentThreadOwns();
return mStack.size(); return mStack.size();
} }
@ -425,7 +425,7 @@ protected:
// !mCxxStackFrames.empty() => RPCChannel code on C++ stack // !mCxxStackFrames.empty() => RPCChannel code on C++ stack
// //
// This member is only accessed on the worker thread, and so is // 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|. // helper |class CxxStackFrame|.
std::vector<RPCFrame> mCxxStackFrames; std::vector<RPCFrame> mCxxStackFrames;

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

@ -42,7 +42,7 @@
#include "nsDebug.h" #include "nsDebug.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"
using mozilla::MutexAutoLock; using mozilla::MonitorAutoLock;
template<> template<>
struct RunnableMethodTraits<mozilla::ipc::SyncChannel> struct RunnableMethodTraits<mozilla::ipc::SyncChannel>
@ -88,7 +88,7 @@ bool
SyncChannel::EventOccurred() SyncChannel::EventOccurred()
{ {
AssertWorkerThread(); AssertWorkerThread();
mMutex.AssertCurrentThreadOwns(); mMonitor.AssertCurrentThreadOwns();
NS_ABORT_IF_FALSE(AwaitingSyncReply(), "not in wait loop"); NS_ABORT_IF_FALSE(AwaitingSyncReply(), "not in wait loop");
return (!Connected() || 0 != mRecvd.type()); return (!Connected() || 0 != mRecvd.type());
@ -98,7 +98,7 @@ bool
SyncChannel::Send(Message* msg, Message* reply) SyncChannel::Send(Message* msg, Message* reply)
{ {
AssertWorkerThread(); AssertWorkerThread();
mMutex.AssertNotCurrentThreadOwns(); mMonitor.AssertNotCurrentThreadOwns();
NS_ABORT_IF_FALSE(!ProcessingSyncMessage(), NS_ABORT_IF_FALSE(!ProcessingSyncMessage(),
"violation of sync handler invariant"); "violation of sync handler invariant");
NS_ABORT_IF_FALSE(msg->is_sync(), "can only Send() sync messages here"); 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()); msg->set_seqno(NextSeqno());
MutexAutoLock lock(mMutex); MonitorAutoLock lock(mMonitor);
if (!Connected()) { if (!Connected()) {
ReportConnectionError("SyncChannel"); ReportConnectionError("SyncChannel");
@ -181,7 +181,7 @@ SyncChannel::OnDispatchMessage(const Message& msg)
reply->set_seqno(msg.seqno()); reply->set_seqno(msg.seqno());
{ {
MutexAutoLock lock(mMutex); MonitorAutoLock lock(mMonitor);
if (ChannelConnected == mChannelState) if (ChannelConnected == mChannelState)
SendThroughTransport(reply); SendThroughTransport(reply);
} }
@ -200,7 +200,7 @@ SyncChannel::OnMessageReceived(const Message& msg)
return AsyncChannel::OnMessageReceived(msg); return AsyncChannel::OnMessageReceived(msg);
} }
MutexAutoLock lock(mMutex); MonitorAutoLock lock(mMonitor);
if (MaybeInterceptSpecialIOMessage(msg)) if (MaybeInterceptSpecialIOMessage(msg))
return; return;
@ -223,7 +223,7 @@ SyncChannel::OnChannelError()
{ {
AssertIOThread(); AssertIOThread();
MutexAutoLock lock(mMutex); MonitorAutoLock lock(mMonitor);
if (ChannelClosing != mChannelState) if (ChannelClosing != mChannelState)
mChannelState = ChannelError; mChannelState = ChannelError;
@ -253,11 +253,11 @@ bool
SyncChannel::ShouldContinueFromTimeout() SyncChannel::ShouldContinueFromTimeout()
{ {
AssertWorkerThread(); AssertWorkerThread();
mMutex.AssertCurrentThreadOwns(); mMonitor.AssertCurrentThreadOwns();
bool cont; bool cont;
{ {
MutexAutoUnlock unlock(mMutex); MonitorAutoUnlock unlock(mMonitor);
cont = static_cast<SyncListener*>(mListener)->OnReplyTimeout(); cont = static_cast<SyncListener*>(mListener)->OnReplyTimeout();
} }
@ -295,7 +295,7 @@ SyncChannel::WaitForNotify()
// XXX could optimize away this syscall for "no timeout" case if desired // XXX could optimize away this syscall for "no timeout" case if desired
PRIntervalTime waitStart = PR_IntervalNow(); PRIntervalTime waitStart = PR_IntervalNow();
mCvar.Wait(timeout); mMonitor.Wait(timeout);
// if the timeout didn't expire, we know we received an event. // if the timeout didn't expire, we know we received an event.
// The converse is not true. // The converse is not true.
@ -305,7 +305,7 @@ SyncChannel::WaitForNotify()
void void
SyncChannel::NotifyWorkerThread() SyncChannel::NotifyWorkerThread()
{ {
mCvar.Notify(); mMonitor.Notify();
} }
#endif // ifndef OS_WIN #endif // ifndef OS_WIN

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

@ -171,7 +171,7 @@ protected:
// On both // On both
bool AwaitingSyncReply() const { bool AwaitingSyncReply() const {
mMutex.AssertCurrentThreadOwns(); mMonitor.AssertCurrentThreadOwns();
return mPendingReply != 0; return mPendingReply != 0;
} }

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

@ -655,7 +655,7 @@ RPCChannel::SpinInternalEventLoop()
// Don't get wrapped up in here if the child connection dies. // Don't get wrapped up in here if the child connection dies.
{ {
MutexAutoLock lock(mMutex); MonitorAutoLock lock(mMonitor);
if (!Connected()) { if (!Connected()) {
return; return;
} }
@ -692,7 +692,7 @@ RPCChannel::SpinInternalEventLoop()
bool bool
SyncChannel::WaitForNotify() SyncChannel::WaitForNotify()
{ {
mMutex.AssertCurrentThreadOwns(); mMonitor.AssertCurrentThreadOwns();
// Initialize global objects used in deferred messaging. // Initialize global objects used in deferred messaging.
Init(); Init();
@ -700,7 +700,7 @@ SyncChannel::WaitForNotify()
NS_ASSERTION(mTopFrame && !mTopFrame->mRPC, NS_ASSERTION(mTopFrame && !mTopFrame->mRPC,
"Top frame is not a sync frame!"); "Top frame is not a sync frame!");
MutexAutoUnlock unlock(mMutex); MonitorAutoUnlock unlock(mMonitor);
bool retval = true; bool retval = true;
@ -730,7 +730,7 @@ SyncChannel::WaitForNotify()
MSG msg = { 0 }; MSG msg = { 0 };
// Don't get wrapped up in here if the child connection dies. // Don't get wrapped up in here if the child connection dies.
{ {
MutexAutoLock lock(mMutex); MonitorAutoLock lock(mMonitor);
if (!Connected()) { if (!Connected()) {
break; break;
} }
@ -814,7 +814,7 @@ SyncChannel::WaitForNotify()
bool bool
RPCChannel::WaitForNotify() RPCChannel::WaitForNotify()
{ {
mMutex.AssertCurrentThreadOwns(); mMonitor.AssertCurrentThreadOwns();
if (!StackDepth() && !mBlockedOnParent) { if (!StackDepth() && !mBlockedOnParent) {
// There is currently no way to recover from this condition. // There is currently no way to recover from this condition.
@ -827,7 +827,7 @@ RPCChannel::WaitForNotify()
NS_ASSERTION(mTopFrame && mTopFrame->mRPC, NS_ASSERTION(mTopFrame && mTopFrame->mRPC,
"Top frame is not a sync frame!"); "Top frame is not a sync frame!");
MutexAutoUnlock unlock(mMutex); MonitorAutoUnlock unlock(mMonitor);
bool retval = true; bool retval = true;
@ -890,7 +890,7 @@ RPCChannel::WaitForNotify()
// Don't get wrapped up in here if the child connection dies. // Don't get wrapped up in here if the child connection dies.
{ {
MutexAutoLock lock(mMutex); MonitorAutoLock lock(mMonitor);
if (!Connected()) { if (!Connected()) {
break; break;
} }
@ -954,7 +954,7 @@ RPCChannel::WaitForNotify()
void void
SyncChannel::NotifyWorkerThread() SyncChannel::NotifyWorkerThread()
{ {
mMutex.AssertCurrentThreadOwns(); mMonitor.AssertCurrentThreadOwns();
NS_ASSERTION(mEvent, "No signal event to set, this is really bad!"); NS_ASSERTION(mEvent, "No signal event to set, this is really bad!");
if (!SetEvent(mEvent)) { if (!SetEvent(mEvent)) {
NS_WARNING("Failed to set NotifyWorkerThread event!"); NS_WARNING("Failed to set NotifyWorkerThread event!");