Bug 540886, part 1: Refactor "special message" dispatch in AsyncChannel. r=bent

--HG--
extra : transplant_source : %81%F6%01%EB%0CE%B0%04R%02%A8%0B%F8c%EF/%1D%CC%3Ep
This commit is contained in:
Chris Jones 2010-01-27 00:41:31 -06:00
Родитель 40ab77cad5
Коммит 162bed2213
2 изменённых файлов: 48 добавлений и 36 удалений

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

@ -54,6 +54,32 @@ struct RunnableMethodTraits<mozilla::ipc::AsyncChannel>
static void ReleaseCallee(mozilla::ipc::AsyncChannel* obj) { }
};
namespace {
// This is an async message
class GoodbyeMessage : public IPC::Message
{
public:
enum { ID = GOODBYE_MESSAGE_TYPE };
GoodbyeMessage() :
IPC::Message(MSG_ROUTING_NONE, ID, PRIORITY_NORMAL)
{
}
// XXX not much point in implementing this; maybe could help with
// debugging?
static bool Read(const Message* msg)
{
return true;
}
void Log(const std::string& aPrefix,
FILE* aOutf) const
{
fputs("(special `Goodbye' message)", aOutf);
}
};
} // namespace <anon>
namespace mozilla {
namespace ipc {
@ -150,7 +176,7 @@ AsyncChannel::Close()
AssertWorkerThread();
// notify the other side that we're about to close our socket
SendGoodbye();
SendSpecialMessage(new GoodbyeMessage());
mChannelState = ChannelClosing;
@ -198,10 +224,12 @@ AsyncChannel::OnDispatchMessage(const Message& msg)
NS_ASSERTION(!msg.is_reply(), "can't process replies here");
NS_ASSERTION(!(msg.is_sync() || msg.is_rpc()), "async dispatch only");
if (MaybeInterceptGoodbye(msg))
// there's a NotifyMaybeChannelError event waiting for us, or
// will be soon
if (MSG_ROUTING_NONE == msg.routing_id()) {
if (!OnSpecialMessage(msg.type(), msg))
// XXX real error handling
NS_RUNTIMEABORT("unhandled special message!");
return;
}
// it's OK to dispatch messages if the channel is closed/error'd,
// since we don't have a reply to send back
@ -209,49 +237,31 @@ AsyncChannel::OnDispatchMessage(const Message& msg)
(void)MaybeHandleError(mListener->OnMessageReceived(msg), "AsyncChannel");
}
// This is an async message
class GoodbyeMessage : public IPC::Message
bool
AsyncChannel::OnSpecialMessage(uint16 id, const Message& msg)
{
public:
enum { ID = GOODBYE_MESSAGE_TYPE };
GoodbyeMessage() :
IPC::Message(MSG_ROUTING_NONE, ID, PRIORITY_NORMAL)
{
switch (id) {
case GOODBYE_MESSAGE_TYPE:
return ProcessGoodbyeMessage();
default:
return false;
}
// XXX not much point in implementing this; maybe could help with
// debugging?
static bool Read(const Message* msg)
{
return true;
}
void Log(const std::string& aPrefix,
FILE* aOutf) const
{
fputs("(special `Goodbye' message)", aOutf);
}
};
}
void
AsyncChannel::SendGoodbye()
AsyncChannel::SendSpecialMessage(Message* msg)
{
AssertWorkerThread();
mIOLoop->PostTask(
FROM_HERE,
NewRunnableMethod(this, &AsyncChannel::OnSend, new GoodbyeMessage()));
NewRunnableMethod(this, &AsyncChannel::OnSend, msg));
}
bool
AsyncChannel::MaybeInterceptGoodbye(const Message& msg)
AsyncChannel::ProcessGoodbyeMessage()
{
// IPDL code isn't allowed to send MSG_ROUTING_NONE messages, so
// there's no chance of confusion here
if (MSG_ROUTING_NONE != msg.routing_id())
return false;
if (msg.is_sync() || msg.is_rpc() || GOODBYE_MESSAGE_TYPE != msg.type())
NS_RUNTIMEABORT("received unknown MSG_ROUTING_NONE message when expecting `Goodbye'");
MutexAutoLock lock(mMutex);
// TODO sort out Close() on this side racing with Close() on the
// other side

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

@ -143,6 +143,9 @@ protected:
// Run on the worker thread
void OnDispatchMessage(const Message& aMsg);
virtual bool OnSpecialMessage(uint16 id, const Message& msg);
void SendSpecialMessage(Message* msg);
bool MaybeHandleError(Result code, const char* channelName);
void ReportConnectionError(const char* channelName);
@ -154,8 +157,7 @@ protected:
// Run on the worker thread
void SendGoodbye();
bool MaybeInterceptGoodbye(const Message& msg);
bool ProcessGoodbyeMessage();
void NotifyChannelClosed();
void NotifyMaybeChannelError();