зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1049879 - Remove urgent and rpc message types and replace with message priorities (r=dvander,bent,ehsan)
This commit is contained in:
Родитель
4985d0ee76
Коммит
2ab547d3ab
2
CLOBBER
2
CLOBBER
|
@ -22,4 +22,4 @@
|
|||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||
# don't change CLOBBER for WebIDL changes any more.
|
||||
|
||||
Bug 1069071: IPDL changes require CLOBBER
|
||||
Bug 1069071: IPDL changes require CLOBBER (second time around)
|
||||
|
|
|
@ -1735,7 +1735,7 @@ public:
|
|||
return cc->SendSyncMessage(PromiseFlatString(aMessage), data, cpows,
|
||||
IPC::Principal(aPrincipal), aJSONRetVal);
|
||||
}
|
||||
return cc->CallRpcMessage(PromiseFlatString(aMessage), data, cpows,
|
||||
return cc->SendRpcMessage(PromiseFlatString(aMessage), data, cpows,
|
||||
IPC::Principal(aPrincipal), aJSONRetVal);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ struct RemoteVoice {
|
|||
bool localService;
|
||||
};
|
||||
|
||||
intr protocol PSpeechSynthesis
|
||||
sync protocol PSpeechSynthesis
|
||||
{
|
||||
manager PContent;
|
||||
manages PSpeechSynthesisRequest;
|
||||
|
|
|
@ -9,7 +9,7 @@ include protocol PSpeechSynthesis;
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
intr protocol PSpeechSynthesisRequest
|
||||
async protocol PSpeechSynthesisRequest
|
||||
{
|
||||
manager PSpeechSynthesis;
|
||||
|
||||
|
|
|
@ -3517,14 +3517,14 @@ ContentParent::RecvSyncMessage(const nsString& aMsg,
|
|||
}
|
||||
|
||||
bool
|
||||
ContentParent::AnswerRpcMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
InfallibleTArray<nsString>* aRetvals)
|
||||
ContentParent::RecvRpcMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
InfallibleTArray<nsString>* aRetvals)
|
||||
{
|
||||
return nsIContentParent::AnswerRpcMessage(aMsg, aData, aCpows, aPrincipal,
|
||||
aRetvals);
|
||||
return nsIContentParent::RecvRpcMessage(aMsg, aData, aCpows, aPrincipal,
|
||||
aRetvals);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -563,11 +563,11 @@ private:
|
|||
const InfallibleTArray<CpowEntry>& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
InfallibleTArray<nsString>* aRetvals) MOZ_OVERRIDE;
|
||||
virtual bool AnswerRpcMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
InfallibleTArray<nsString>* aRetvals) MOZ_OVERRIDE;
|
||||
virtual bool RecvRpcMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
InfallibleTArray<nsString>* aRetvals) MOZ_OVERRIDE;
|
||||
virtual bool RecvAsyncMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows,
|
||||
|
|
|
@ -69,7 +69,7 @@ union MaybeNativeKeyBinding
|
|||
void_t;
|
||||
};
|
||||
|
||||
intr protocol PBrowser
|
||||
prio(normal upto high) intr protocol PBrowser
|
||||
{
|
||||
manager PContent or PContentBridge;
|
||||
|
||||
|
@ -108,8 +108,8 @@ parent:
|
|||
CpowEntry[] aCpows, Principal aPrincipal)
|
||||
returns (nsString[] retval);
|
||||
|
||||
rpc RpcMessage(nsString aMessage, ClonedMessageData aData,
|
||||
CpowEntry[] aCpows, Principal aPrincipal)
|
||||
prio(high) sync RpcMessage(nsString aMessage, ClonedMessageData aData,
|
||||
CpowEntry[] aCpows, Principal aPrincipal)
|
||||
returns (nsString[] retval);
|
||||
|
||||
/**
|
||||
|
|
|
@ -319,7 +319,7 @@ union MaybeFileDesc {
|
|||
void_t;
|
||||
};
|
||||
|
||||
intr protocol PContent
|
||||
prio(normal upto high) intr protocol PContent
|
||||
{
|
||||
parent opens PCompositor;
|
||||
parent opens PSharedBufferManager;
|
||||
|
@ -537,7 +537,7 @@ parent:
|
|||
|
||||
PNecko();
|
||||
|
||||
rpc PScreenManager()
|
||||
prio(high) sync PScreenManager()
|
||||
returns (uint32_t numberOfScreens,
|
||||
float systemDefaultScale,
|
||||
bool success);
|
||||
|
@ -577,8 +577,8 @@ parent:
|
|||
CpowEntry[] aCpows, Principal aPrincipal)
|
||||
returns (nsString[] retval);
|
||||
|
||||
rpc RpcMessage(nsString aMessage, ClonedMessageData aData,
|
||||
CpowEntry[] aCpows, Principal aPrincipal)
|
||||
prio(high) sync RpcMessage(nsString aMessage, ClonedMessageData aData,
|
||||
CpowEntry[] aCpows, Principal aPrincipal)
|
||||
returns (nsString[] retval);
|
||||
|
||||
ShowAlertNotification(nsString imageUrl,
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace dom {
|
|||
* allocate the PContentBridgeChild. This protocol allows these processes to
|
||||
* share PBrowsers and send messages to each other.
|
||||
*/
|
||||
intr protocol PContentBridge
|
||||
prio(normal upto high) intr protocol PContentBridge
|
||||
{
|
||||
bridges PContent, PContent;
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ struct Mapping {
|
|||
size_t file_offset;
|
||||
};
|
||||
|
||||
intr protocol PCrashReporter {
|
||||
async protocol PCrashReporter {
|
||||
manager PContent or PPluginModule or PGMP;
|
||||
parent:
|
||||
AnnotateCrashReport(nsCString key, nsCString data);
|
||||
|
|
|
@ -22,32 +22,32 @@ struct ScreenDetails {
|
|||
double contentsScaleFactor;
|
||||
};
|
||||
|
||||
rpc protocol PScreenManager
|
||||
prio(normal upto high) sync protocol PScreenManager
|
||||
{
|
||||
manager PContent;
|
||||
|
||||
parent:
|
||||
rpc Refresh()
|
||||
prio(high) sync Refresh()
|
||||
returns (uint32_t numberOfScreens,
|
||||
float systemDefaultScale,
|
||||
bool success);
|
||||
|
||||
rpc ScreenRefresh(uint32_t aId)
|
||||
prio(high) sync ScreenRefresh(uint32_t aId)
|
||||
returns (ScreenDetails screen,
|
||||
bool success);
|
||||
|
||||
rpc GetPrimaryScreen()
|
||||
prio(high) sync GetPrimaryScreen()
|
||||
returns (ScreenDetails screen,
|
||||
bool success);
|
||||
|
||||
rpc ScreenForRect(int32_t aLeft,
|
||||
prio(high) sync ScreenForRect(int32_t aLeft,
|
||||
int32_t aTop,
|
||||
int32_t aWidth,
|
||||
int32_t aHeight)
|
||||
returns (ScreenDetails screen,
|
||||
bool success);
|
||||
|
||||
rpc ScreenForBrowser(PBrowser aBrowser)
|
||||
prio(high) sync ScreenForBrowser(PBrowser aBrowser)
|
||||
returns (ScreenDetails screen,
|
||||
bool success);
|
||||
|
||||
|
|
|
@ -24,13 +24,13 @@ ScreenManagerParent::ScreenManagerParent(uint32_t* aNumberOfScreens,
|
|||
MOZ_CRASH("Couldn't get nsIScreenManager from ScreenManagerParent.");
|
||||
}
|
||||
|
||||
unused << AnswerRefresh(aNumberOfScreens, aSystemDefaultScale, aSuccess);
|
||||
unused << RecvRefresh(aNumberOfScreens, aSystemDefaultScale, aSuccess);
|
||||
}
|
||||
|
||||
bool
|
||||
ScreenManagerParent::AnswerRefresh(uint32_t* aNumberOfScreens,
|
||||
float* aSystemDefaultScale,
|
||||
bool* aSuccess)
|
||||
ScreenManagerParent::RecvRefresh(uint32_t* aNumberOfScreens,
|
||||
float* aSystemDefaultScale,
|
||||
bool* aSuccess)
|
||||
{
|
||||
*aSuccess = false;
|
||||
|
||||
|
@ -49,9 +49,9 @@ ScreenManagerParent::AnswerRefresh(uint32_t* aNumberOfScreens,
|
|||
}
|
||||
|
||||
bool
|
||||
ScreenManagerParent::AnswerScreenRefresh(const uint32_t& aId,
|
||||
ScreenDetails* aRetVal,
|
||||
bool* aSuccess)
|
||||
ScreenManagerParent::RecvScreenRefresh(const uint32_t& aId,
|
||||
ScreenDetails* aRetVal,
|
||||
bool* aSuccess)
|
||||
{
|
||||
*aSuccess = false;
|
||||
|
||||
|
@ -70,8 +70,8 @@ ScreenManagerParent::AnswerScreenRefresh(const uint32_t& aId,
|
|||
}
|
||||
|
||||
bool
|
||||
ScreenManagerParent::AnswerGetPrimaryScreen(ScreenDetails* aRetVal,
|
||||
bool* aSuccess)
|
||||
ScreenManagerParent::RecvGetPrimaryScreen(ScreenDetails* aRetVal,
|
||||
bool* aSuccess)
|
||||
{
|
||||
*aSuccess = false;
|
||||
|
||||
|
@ -91,12 +91,12 @@ ScreenManagerParent::AnswerGetPrimaryScreen(ScreenDetails* aRetVal,
|
|||
}
|
||||
|
||||
bool
|
||||
ScreenManagerParent::AnswerScreenForRect(const int32_t& aLeft,
|
||||
const int32_t& aTop,
|
||||
const int32_t& aWidth,
|
||||
const int32_t& aHeight,
|
||||
ScreenDetails* aRetVal,
|
||||
bool* aSuccess)
|
||||
ScreenManagerParent::RecvScreenForRect(const int32_t& aLeft,
|
||||
const int32_t& aTop,
|
||||
const int32_t& aWidth,
|
||||
const int32_t& aHeight,
|
||||
ScreenDetails* aRetVal,
|
||||
bool* aSuccess)
|
||||
{
|
||||
*aSuccess = false;
|
||||
|
||||
|
@ -116,9 +116,9 @@ ScreenManagerParent::AnswerScreenForRect(const int32_t& aLeft,
|
|||
}
|
||||
|
||||
bool
|
||||
ScreenManagerParent::AnswerScreenForBrowser(PBrowserParent* aBrowser,
|
||||
ScreenDetails* aRetVal,
|
||||
bool* aSuccess)
|
||||
ScreenManagerParent::RecvScreenForBrowser(PBrowserParent* aBrowser,
|
||||
ScreenDetails* aRetVal,
|
||||
bool* aSuccess)
|
||||
{
|
||||
*aSuccess = false;
|
||||
|
||||
|
|
|
@ -21,29 +21,29 @@ class ScreenManagerParent : public PScreenManagerParent
|
|||
bool* aSuccess);
|
||||
~ScreenManagerParent() {};
|
||||
|
||||
virtual bool AnswerRefresh(uint32_t* aNumberOfScreens,
|
||||
float* aSystemDefaultScale,
|
||||
bool* aSuccess) MOZ_OVERRIDE;
|
||||
virtual bool RecvRefresh(uint32_t* aNumberOfScreens,
|
||||
float* aSystemDefaultScale,
|
||||
bool* aSuccess) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool AnswerScreenRefresh(const uint32_t& aId,
|
||||
ScreenDetails* aRetVal,
|
||||
bool* aSuccess) MOZ_OVERRIDE;
|
||||
virtual bool RecvScreenRefresh(const uint32_t& aId,
|
||||
ScreenDetails* aRetVal,
|
||||
bool* aSuccess) MOZ_OVERRIDE;
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool AnswerGetPrimaryScreen(ScreenDetails* aRetVal,
|
||||
bool* aSuccess) MOZ_OVERRIDE;
|
||||
virtual bool RecvGetPrimaryScreen(ScreenDetails* aRetVal,
|
||||
bool* aSuccess) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool AnswerScreenForRect(const int32_t& aLeft,
|
||||
const int32_t& aTop,
|
||||
const int32_t& aWidth,
|
||||
const int32_t& aHeight,
|
||||
ScreenDetails* aRetVal,
|
||||
bool* aSuccess) MOZ_OVERRIDE;
|
||||
virtual bool RecvScreenForRect(const int32_t& aLeft,
|
||||
const int32_t& aTop,
|
||||
const int32_t& aWidth,
|
||||
const int32_t& aHeight,
|
||||
ScreenDetails* aRetVal,
|
||||
bool* aSuccess) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool AnswerScreenForBrowser(PBrowserParent* aBrowser,
|
||||
ScreenDetails* aRetVal,
|
||||
bool* aSuccess);
|
||||
virtual bool RecvScreenForBrowser(PBrowserParent* aBrowser,
|
||||
ScreenDetails* aRetVal,
|
||||
bool* aSuccess);
|
||||
|
||||
private:
|
||||
bool ExtractScreenDetails(nsIScreen* aScreen, ScreenDetails &aDetails);
|
||||
|
|
|
@ -2922,7 +2922,7 @@ TabChild::DoSendBlockingMessage(JSContext* aCx,
|
|||
Principal(aPrincipal), aJSONRetVal);
|
||||
}
|
||||
|
||||
return CallRpcMessage(PromiseFlatString(aMessage), data, cpows,
|
||||
return SendRpcMessage(PromiseFlatString(aMessage), data, cpows,
|
||||
Principal(aPrincipal), aJSONRetVal);
|
||||
}
|
||||
|
||||
|
|
|
@ -1128,11 +1128,11 @@ TabParent::RecvSyncMessage(const nsString& aMessage,
|
|||
}
|
||||
|
||||
bool
|
||||
TabParent::AnswerRpcMessage(const nsString& aMessage,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
InfallibleTArray<nsString>* aJSONRetVal)
|
||||
TabParent::RecvRpcMessage(const nsString& aMessage,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
InfallibleTArray<nsString>* aJSONRetVal)
|
||||
{
|
||||
// FIXME Permission check for TabParent in Content process
|
||||
nsIPrincipal* principal = aPrincipal;
|
||||
|
|
|
@ -147,11 +147,11 @@ public:
|
|||
const InfallibleTArray<CpowEntry>& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
InfallibleTArray<nsString>* aJSONRetVal) MOZ_OVERRIDE;
|
||||
virtual bool AnswerRpcMessage(const nsString& aMessage,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
InfallibleTArray<nsString>* aJSONRetVal) MOZ_OVERRIDE;
|
||||
virtual bool RecvRpcMessage(const nsString& aMessage,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
InfallibleTArray<nsString>* aJSONRetVal) MOZ_OVERRIDE;
|
||||
virtual bool RecvAsyncMessage(const nsString& aMessage,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows,
|
||||
|
|
|
@ -193,11 +193,11 @@ nsIContentParent::RecvSyncMessage(const nsString& aMsg,
|
|||
}
|
||||
|
||||
bool
|
||||
nsIContentParent::AnswerRpcMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
InfallibleTArray<nsString>* aRetvals)
|
||||
nsIContentParent::RecvRpcMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
InfallibleTArray<nsString>* aRetvals)
|
||||
{
|
||||
// FIXME Permission check in Content process
|
||||
nsIPrincipal* principal = aPrincipal;
|
||||
|
|
|
@ -91,11 +91,11 @@ protected: // IPDL methods
|
|||
const InfallibleTArray<jsipc::CpowEntry>& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
InfallibleTArray<nsString>* aRetvals);
|
||||
virtual bool AnswerRpcMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<jsipc::CpowEntry>& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
InfallibleTArray<nsString>* aRetvals);
|
||||
virtual bool RecvRpcMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<jsipc::CpowEntry>& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
InfallibleTArray<nsString>* aRetvals);
|
||||
virtual bool RecvAsyncMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<jsipc::CpowEntry>& aCpows,
|
||||
|
|
|
@ -53,9 +53,9 @@ class Message : public Pickle {
|
|||
};
|
||||
|
||||
enum PriorityValue {
|
||||
PRIORITY_LOW = 1,
|
||||
PRIORITY_NORMAL,
|
||||
PRIORITY_HIGH
|
||||
PRIORITY_NORMAL = 1,
|
||||
PRIORITY_HIGH = 2,
|
||||
PRIORITY_URGENT = 3
|
||||
};
|
||||
|
||||
enum MessageCompression {
|
||||
|
@ -85,6 +85,11 @@ class Message : public Pickle {
|
|||
return static_cast<PriorityValue>(header()->flags & PRIORITY_MASK);
|
||||
}
|
||||
|
||||
void set_priority(int prio) {
|
||||
DCHECK((prio & ~PRIORITY_MASK) == 0);
|
||||
header()->flags = (header()->flags & ~PRIORITY_MASK) | prio;
|
||||
}
|
||||
|
||||
// True if this is a synchronous message.
|
||||
bool is_sync() const {
|
||||
return (header()->flags & SYNC_BIT) != 0;
|
||||
|
@ -95,16 +100,6 @@ class Message : public Pickle {
|
|||
return (header()->flags & INTERRUPT_BIT) != 0;
|
||||
}
|
||||
|
||||
// True if this is an urgent message.
|
||||
bool is_urgent() const {
|
||||
return (header()->flags & URGENT_BIT) != 0;
|
||||
}
|
||||
|
||||
// True if this is an RPC message.
|
||||
bool is_rpc() const {
|
||||
return (header()->flags & RPC_BIT) != 0;
|
||||
}
|
||||
|
||||
// True if compression is enabled for this message.
|
||||
bool compress() const {
|
||||
return (header()->flags & COMPRESS_BIT) != 0;
|
||||
|
@ -296,14 +291,6 @@ class Message : public Pickle {
|
|||
header()->flags |= INTERRUPT_BIT;
|
||||
}
|
||||
|
||||
void set_urgent() {
|
||||
header()->flags |= URGENT_BIT;
|
||||
}
|
||||
|
||||
void set_rpc() {
|
||||
header()->flags |= RPC_BIT;
|
||||
}
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
protected:
|
||||
#endif
|
||||
|
@ -319,8 +306,6 @@ class Message : public Pickle {
|
|||
HAS_SENT_TIME_BIT = 0x0080,
|
||||
INTERRUPT_BIT = 0x0100,
|
||||
COMPRESS_BIT = 0x0200,
|
||||
URGENT_BIT = 0x0400,
|
||||
RPC_BIT = 0x0800
|
||||
};
|
||||
|
||||
struct Header : Pickle::Header {
|
||||
|
|
|
@ -20,6 +20,62 @@
|
|||
// Undo the damage done by mozzconf.h
|
||||
#undef compress
|
||||
|
||||
/*
|
||||
* IPC design:
|
||||
*
|
||||
* There are three kinds of messages: async, sync, and intr. Sync and intr
|
||||
* messages are blocking. Only intr and high-priority sync messages can nest.
|
||||
*
|
||||
* Terminology: To dispatch a message Foo is to run the RecvFoo code for
|
||||
* it. This is also called "handling" the message.
|
||||
*
|
||||
* Sync messages have priorities while async and intr messages always have
|
||||
* normal priority. The three possible priorities are normal, high, and urgent.
|
||||
* The intended uses of these priorities are:
|
||||
* NORMAL - most messages.
|
||||
* HIGH - CPOW-related messages, which can go in either direction.
|
||||
* URGENT - messages where we don't want to dispatch
|
||||
* incoming CPOWs while waiting for the response.
|
||||
*
|
||||
* To avoid jank, the parent process is not allowed to send sync messages of
|
||||
* normal priority. The parent also is not allowed to send urgent messages at
|
||||
* all. When a process is waiting for a response to a sync message M0, it will
|
||||
* dispatch an incoming message M if:
|
||||
* 1. M has a higher priority than M0, or
|
||||
* 2. if M has the same priority as M0 and we're in the child, or
|
||||
* 3. if M has the same priority as M0 and it was sent by the other side
|
||||
while dispatching M0 (nesting).
|
||||
* The idea is that higher priority messages should take precendence, and we
|
||||
* also want to allow nesting. The purpose of rule 2 is to handle a race where
|
||||
* both processes send to each other simultaneously. In this case, we resolve
|
||||
* the race in favor of the parent (so the child dispatches first).
|
||||
*
|
||||
* Sync messages satisfy the following properties:
|
||||
* A. When waiting for a response to a sync message, we won't dispatch any
|
||||
* messages of lower priority.
|
||||
* B. Sync messages of the same priority will be dispatched roughly in the
|
||||
* order they were sent. The exception is when the parent and child send
|
||||
* sync messages to each other simulataneously. In this case, the parent's
|
||||
* message is dispatched first. While it is dispatched, the child may send
|
||||
* further nested messages, and these messages may be dispatched before the
|
||||
* child's original message. We can consider ordering to be preserved here
|
||||
* because we pretend that the child's original message wasn't sent until
|
||||
* after the parent's message is finished being dispatched.
|
||||
*
|
||||
* Intr messages are blocking but not prioritized. While waiting for an intr
|
||||
* response, all incoming messages are dispatched until a response is
|
||||
* received. Intr messages also can be nested. When two intr messages race with
|
||||
* each other, a similar scheme is used to ensure that one side wins. The
|
||||
* winning side is chosen based on the message type.
|
||||
*
|
||||
* Intr messages differ from sync messages in that, while sending an intr
|
||||
* message, we may dispatch an async message. This causes some additional
|
||||
* complexity. One issue is that replies can be received out of order. It's also
|
||||
* more difficult to determine whether one message is nested inside
|
||||
* another. Consequently, intr handling uses mOutOfTurnReplies and
|
||||
* mRemoteStackDepthGuess, which are not needed for sync messages.
|
||||
*/
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace std;
|
||||
|
||||
|
@ -39,7 +95,7 @@ struct RunnableMethodTraits<mozilla::ipc::MessageChannel>
|
|||
DebugAbort(__FILE__, __LINE__, #_cond,## __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
static uintptr_t gDispatchingUrgentMessageCount;
|
||||
static bool gParentIsBlocked;
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
@ -195,9 +251,9 @@ namespace {
|
|||
|
||||
class MOZ_STACK_CLASS MaybeScriptBlocker {
|
||||
public:
|
||||
explicit MaybeScriptBlocker(MessageChannel *aChannel
|
||||
explicit MaybeScriptBlocker(MessageChannel *aChannel, bool aBlock
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: mBlocked(aChannel->ShouldBlockScripts())
|
||||
: mBlocked(aChannel->ShouldBlockScripts() && aBlock)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
if (mBlocked) {
|
||||
|
@ -227,12 +283,11 @@ MessageChannel::MessageChannel(MessageListener *aListener)
|
|||
mTimeoutMs(kNoTimeout),
|
||||
mInTimeoutSecondHalf(false),
|
||||
mNextSeqno(0),
|
||||
mPendingSyncReplies(0),
|
||||
mPendingUrgentReplies(0),
|
||||
mPendingRPCReplies(0),
|
||||
mCurrentRPCTransaction(0),
|
||||
mAwaitingSyncReply(false),
|
||||
mAwaitingSyncReplyPriority(0),
|
||||
mDispatchingSyncMessage(false),
|
||||
mDispatchingUrgentMessageCount(0),
|
||||
mDispatchingSyncMessagePriority(0),
|
||||
mCurrentTransaction(0),
|
||||
mRemoteStackDepthGuess(false),
|
||||
mSawInterruptOutMsg(false),
|
||||
mAbortOnError(false),
|
||||
|
@ -327,8 +382,7 @@ MessageChannel::Clear()
|
|||
|
||||
// Free up any memory used by pending messages.
|
||||
mPending.clear();
|
||||
mPendingUrgentRequest = nullptr;
|
||||
mPendingRPCCall = nullptr;
|
||||
mRecvd = nullptr;
|
||||
mOutOfTurnReplies.clear();
|
||||
while (!mDeferred.empty()) {
|
||||
mDeferred.pop();
|
||||
|
@ -488,6 +542,47 @@ MessageChannel::MaybeInterceptSpecialIOMessage(const Message& aMsg)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
MessageChannel::ShouldDeferMessage(const Message& aMsg)
|
||||
{
|
||||
// Never defer messages that have the highest priority, even async
|
||||
// ones. This is safe because only the child can send these messages, so
|
||||
// they can never nest.
|
||||
if (aMsg.priority() == IPC::Message::PRIORITY_URGENT) {
|
||||
MOZ_ASSERT(mSide == ParentSide);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Unless they're urgent, we always defer async messages.
|
||||
if (!aMsg.is_sync()) {
|
||||
MOZ_ASSERT(aMsg.priority() == IPC::Message::PRIORITY_NORMAL);
|
||||
return true;
|
||||
}
|
||||
|
||||
int msgPrio = aMsg.priority();
|
||||
int waitingPrio = AwaitingSyncReplyPriority();
|
||||
|
||||
// Always defer if the priority of the incoming message is less than the
|
||||
// priority of the message we're awaiting.
|
||||
if (msgPrio < waitingPrio)
|
||||
return true;
|
||||
|
||||
// Never defer if the message has strictly greater priority.
|
||||
if (msgPrio > waitingPrio)
|
||||
return false;
|
||||
|
||||
// When both sides send sync messages of the same priority, we resolve the
|
||||
// race by dispatching in the child and deferring the incoming message in
|
||||
// the parent. However, the parent still needs to dispatch nested sync
|
||||
// messages.
|
||||
//
|
||||
// Deferring in the parent only sort of breaks message ordering. When the
|
||||
// child's message comes in, we can pretend the child hasn't quite
|
||||
// finished sending it yet. Since the message is sync, we know that the
|
||||
// child hasn't moved on yet.
|
||||
return mSide == ParentSide && aMsg.transaction_id() != mCurrentTransaction;
|
||||
}
|
||||
|
||||
void
|
||||
MessageChannel::OnMessageReceivedFromLink(const Message& aMsg)
|
||||
{
|
||||
|
@ -497,19 +592,17 @@ MessageChannel::OnMessageReceivedFromLink(const Message& aMsg)
|
|||
if (MaybeInterceptSpecialIOMessage(aMsg))
|
||||
return;
|
||||
|
||||
// Regardless of the Interrupt stack, if we're awaiting a sync or urgent reply,
|
||||
// Regardless of the Interrupt stack, if we're awaiting a sync reply,
|
||||
// we know that it needs to be immediately handled to unblock us.
|
||||
if ((AwaitingSyncReply() && aMsg.is_sync()) ||
|
||||
(AwaitingUrgentReply() && aMsg.is_urgent()) ||
|
||||
(AwaitingRPCReply() && aMsg.is_rpc()))
|
||||
{
|
||||
if (AwaitingSyncReply() && aMsg.is_sync() && aMsg.is_reply()) {
|
||||
MOZ_ASSERT(!mRecvd);
|
||||
mRecvd = new Message(aMsg);
|
||||
NotifyWorkerThread();
|
||||
return;
|
||||
}
|
||||
|
||||
// Urgent messages cannot be compressed.
|
||||
MOZ_ASSERT(!aMsg.compress() || !aMsg.is_urgent());
|
||||
// Prioritized messages cannot be compressed.
|
||||
MOZ_ASSERT(!aMsg.compress() || aMsg.priority() == IPC::Message::PRIORITY_NORMAL);
|
||||
|
||||
bool compress = (aMsg.compress() && !mPending.empty() &&
|
||||
mPending.back().type() == aMsg.type() &&
|
||||
|
@ -523,20 +616,18 @@ MessageChannel::OnMessageReceivedFromLink(const Message& aMsg)
|
|||
}
|
||||
|
||||
bool shouldWakeUp = AwaitingInterruptReply() ||
|
||||
// Allow incoming RPCs to be processed inside an urgent message.
|
||||
(AwaitingUrgentReply() && aMsg.is_rpc()) ||
|
||||
// Always process urgent messages while blocked.
|
||||
((AwaitingSyncReply() || AwaitingRPCReply()) && aMsg.is_urgent());
|
||||
(AwaitingSyncReply() && !ShouldDeferMessage(aMsg));
|
||||
|
||||
// There are four cases we're concerned about, relating to the state of the
|
||||
// There are three cases we're concerned about, relating to the state of the
|
||||
// main thread:
|
||||
//
|
||||
// (1) We are waiting on a sync|rpc reply - main thread is blocked on the
|
||||
// (1) We are waiting on a sync reply - main thread is blocked on the
|
||||
// IPC monitor.
|
||||
// - If the message is high priority, we wake up the main thread to
|
||||
// deliver the message. Otherwise, we leave it in the mPending queue,
|
||||
// posting a task to the main event loop, where it will be processed
|
||||
// once the synchronous reply has been received.
|
||||
// deliver the message depending on ShouldDeferMessage. Otherwise, we
|
||||
// leave it in the mPending queue, posting a task to the main event
|
||||
// loop, where it will be processed once the synchronous reply has been
|
||||
// received.
|
||||
//
|
||||
// (2) We are waiting on an Interrupt reply - main thread is blocked on the
|
||||
// IPC monitor.
|
||||
|
@ -549,47 +640,9 @@ MessageChannel::OnMessageReceivedFromLink(const Message& aMsg)
|
|||
// blocked. This is okay, since we always check for pending events before
|
||||
// blocking again.
|
||||
|
||||
if (shouldWakeUp && (AwaitingUrgentReply() && aMsg.is_rpc())) {
|
||||
// If we're receiving an RPC message while blocked on an urgent message,
|
||||
// we must defer any messages that were not sent as part of the child
|
||||
// answering the urgent message.
|
||||
//
|
||||
// We must also be sure that we will not accidentally defer any RPC
|
||||
// message that was sent while answering an urgent message. Otherwise,
|
||||
// we will deadlock.
|
||||
//
|
||||
// On the parent side, the current transaction can only transition from 0
|
||||
// to an ID, either by us issuing an urgent request while not blocked, or
|
||||
// by receiving an RPC request while not blocked. When we unblock, the
|
||||
// current transaction is reset to 0.
|
||||
//
|
||||
// When the child side receives an urgent message, any RPC messages sent
|
||||
// before issuing the urgent reply will carry the urgent message's
|
||||
// transaction ID.
|
||||
//
|
||||
// Since AwaitingUrgentReply() implies we are blocked, it also implies
|
||||
// that we are within a transaction that will not change until we are
|
||||
// completely unblocked (i.e, the transaction has completed).
|
||||
if (aMsg.transaction_id() != mCurrentRPCTransaction)
|
||||
shouldWakeUp = false;
|
||||
}
|
||||
|
||||
if (aMsg.is_urgent()) {
|
||||
MOZ_ASSERT(!mPendingUrgentRequest);
|
||||
mPendingUrgentRequest = new Message(aMsg);
|
||||
} else if (aMsg.is_rpc() && shouldWakeUp) {
|
||||
// Only use this slot if we need to wake up for an RPC call. Otherwise
|
||||
// we treat it like a normal async or sync message.
|
||||
MOZ_ASSERT(!mPendingRPCCall);
|
||||
mPendingRPCCall = new Message(aMsg);
|
||||
} else {
|
||||
mPending.push_back(aMsg);
|
||||
}
|
||||
mPending.push_back(aMsg);
|
||||
|
||||
if (shouldWakeUp) {
|
||||
// Always wake up Interrupt waiters, sync waiters for urgent messages,
|
||||
// RPC waiters for urgent messages, and urgent waiters for RPCs in the
|
||||
// same transaction.
|
||||
NotifyWorkerThread();
|
||||
} else {
|
||||
// Worker thread is either not blocked on a reply, or this is an
|
||||
|
@ -607,7 +660,7 @@ bool
|
|||
MessageChannel::Send(Message* aMsg, Message* aReply)
|
||||
{
|
||||
// See comment in DispatchUrgentMessage.
|
||||
MaybeScriptBlocker scriptBlocker(this);
|
||||
MaybeScriptBlocker scriptBlocker(this, true);
|
||||
|
||||
// Sanity checks.
|
||||
AssertWorkerThread();
|
||||
|
@ -622,11 +675,16 @@ MessageChannel::Send(Message* aMsg, Message* aReply)
|
|||
MonitorAutoLock lock(*mMonitor);
|
||||
|
||||
IPC_ASSERT(aMsg->is_sync(), "can only Send() sync messages here");
|
||||
IPC_ASSERT(!DispatchingSyncMessage(), "violation of sync handler invariant");
|
||||
IPC_ASSERT(!DispatchingUrgentMessage(), "sync messages forbidden while handling urgent message");
|
||||
IPC_ASSERT(!AwaitingSyncReply(), "nested sync messages are not supported");
|
||||
IPC_ASSERT(aMsg->priority() >= DispatchingSyncMessagePriority(),
|
||||
"can't send sync message of a lesser priority than what's being dispatched");
|
||||
IPC_ASSERT(mAwaitingSyncReplyPriority <= aMsg->priority(),
|
||||
"nested sync message sends must be of increasing priority");
|
||||
|
||||
AutoSetValue<bool> replies(mAwaitingSyncReply, true);
|
||||
AutoSetValue<int> prio(mAwaitingSyncReplyPriority, aMsg->priority());
|
||||
AutoEnterTransaction transact(this);
|
||||
aMsg->set_transaction_id(mCurrentTransaction);
|
||||
|
||||
AutoEnterPendingReply replies(mPendingSyncReplies);
|
||||
if (!SendAndWait(aMsg, aReply))
|
||||
return false;
|
||||
|
||||
|
@ -634,66 +692,22 @@ MessageChannel::Send(Message* aMsg, Message* aReply)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
MessageChannel::UrgentCall(Message* aMsg, Message* aReply)
|
||||
struct AutoDeferMessages
|
||||
{
|
||||
// See comment in DispatchUrgentMessage.
|
||||
MaybeScriptBlocker scriptBlocker(this);
|
||||
typedef IPC::Message Message;
|
||||
|
||||
AssertWorkerThread();
|
||||
mMonitor->AssertNotCurrentThreadOwns();
|
||||
IPC_ASSERT(mSide == ParentSide, "cannot send urgent requests from child");
|
||||
std::deque<Message>& mQueue;
|
||||
mozilla::Vector<Message> mDeferred;
|
||||
|
||||
#ifdef OS_WIN
|
||||
SyncStackFrame frame(this, false);
|
||||
#endif
|
||||
AutoDeferMessages(std::deque<Message>& queue) : mQueue(queue) {}
|
||||
~AutoDeferMessages() {
|
||||
mQueue.insert(mQueue.begin(), mDeferred.begin(), mDeferred.end());
|
||||
}
|
||||
|
||||
CxxStackFrame f(*this, OUT_MESSAGE, aMsg);
|
||||
|
||||
MonitorAutoLock lock(*mMonitor);
|
||||
|
||||
IPC_ASSERT(!AwaitingInterruptReply(), "urgent calls cannot be issued within Interrupt calls");
|
||||
IPC_ASSERT(!AwaitingSyncReply(), "urgent calls cannot be issued within sync sends");
|
||||
|
||||
AutoEnterRPCTransaction transact(this);
|
||||
aMsg->set_transaction_id(mCurrentRPCTransaction);
|
||||
|
||||
AutoEnterPendingReply replies(mPendingUrgentReplies);
|
||||
if (!SendAndWait(aMsg, aReply))
|
||||
return false;
|
||||
|
||||
NS_ABORT_IF_FALSE(aReply->is_urgent(), "reply is not urgent");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
MessageChannel::RPCCall(Message* aMsg, Message* aReply)
|
||||
{
|
||||
// See comment in DispatchUrgentMessage.
|
||||
MaybeScriptBlocker scriptBlocker(this);
|
||||
|
||||
AssertWorkerThread();
|
||||
mMonitor->AssertNotCurrentThreadOwns();
|
||||
IPC_ASSERT(mSide == ChildSide, "cannot send rpc messages from parent");
|
||||
|
||||
#ifdef OS_WIN
|
||||
SyncStackFrame frame(this, false);
|
||||
#endif
|
||||
|
||||
CxxStackFrame f(*this, OUT_MESSAGE, aMsg);
|
||||
|
||||
MonitorAutoLock lock(*mMonitor);
|
||||
|
||||
AutoEnterRPCTransaction transact(this);
|
||||
aMsg->set_transaction_id(mCurrentRPCTransaction);
|
||||
|
||||
AutoEnterPendingReply replies(mPendingRPCReplies);
|
||||
if (!SendAndWait(aMsg, aReply))
|
||||
return false;
|
||||
|
||||
NS_ABORT_IF_FALSE(aReply->is_rpc(), "expected rpc reply");
|
||||
return true;
|
||||
}
|
||||
void Defer(Message aMsg) {
|
||||
mDeferred.append(aMsg);
|
||||
}
|
||||
};
|
||||
|
||||
bool
|
||||
MessageChannel::SendAndWait(Message* aMsg, Message* aReply)
|
||||
|
@ -714,52 +728,44 @@ MessageChannel::SendAndWait(Message* aMsg, Message* aReply)
|
|||
|
||||
mLink->SendMessage(msg.forget());
|
||||
|
||||
AutoDeferMessages defer(mPending);
|
||||
|
||||
while (true) {
|
||||
// Wait for an event to occur.
|
||||
while (true) {
|
||||
if (mRecvd || mPendingUrgentRequest || mPendingRPCCall)
|
||||
break;
|
||||
|
||||
bool maybeTimedOut = !WaitForSyncNotify();
|
||||
|
||||
if (!Connected()) {
|
||||
ReportConnectionError("MessageChannel::SendAndWait");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (maybeTimedOut && !ShouldContinueFromTimeout())
|
||||
return false;
|
||||
}
|
||||
|
||||
// We need to make sure that all messages deposited in mPendingRPCCall
|
||||
// and mPendingUrgentRequest are dispatched before we leave this
|
||||
// function. Otherwise, there's nothing to wake us up and force us to
|
||||
// dispatch them.
|
||||
while (mPendingUrgentRequest) {
|
||||
if (!ProcessPendingUrgentRequest())
|
||||
return false;
|
||||
}
|
||||
|
||||
while (mPendingRPCCall) {
|
||||
if (!ProcessPendingRPCCall())
|
||||
return false;
|
||||
while (!mPending.empty()) {
|
||||
Message msg = mPending.front();
|
||||
mPending.pop_front();
|
||||
if (ShouldDeferMessage(msg))
|
||||
defer.Defer(msg);
|
||||
else
|
||||
ProcessPendingRequest(msg);
|
||||
}
|
||||
|
||||
// See if we've received a reply.
|
||||
if (mRecvd) {
|
||||
NS_ABORT_IF_FALSE(mRecvd->is_reply(), "expected reply");
|
||||
MOZ_ASSERT(mRecvd->is_reply(), "expected reply");
|
||||
|
||||
if (mRecvd->is_reply_error()) {
|
||||
mRecvd = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_ABORT_IF_FALSE(mRecvd->type() == replyType, "wrong reply type");
|
||||
NS_ABORT_IF_FALSE(mRecvd->seqno() == replySeqno, "wrong sequence number");
|
||||
MOZ_ASSERT(mRecvd->type() == replyType, "wrong reply type");
|
||||
MOZ_ASSERT(mRecvd->seqno() == replySeqno);
|
||||
|
||||
*aReply = *mRecvd;
|
||||
mRecvd = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool maybeTimedOut = !WaitForSyncNotify();
|
||||
|
||||
if (!Connected()) {
|
||||
ReportConnectionError("MessageChannel::SendAndWait");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (maybeTimedOut && !ShouldContinueFromTimeout())
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -767,16 +773,6 @@ MessageChannel::SendAndWait(Message* aMsg, Message* aReply)
|
|||
|
||||
bool
|
||||
MessageChannel::Call(Message* aMsg, Message* aReply)
|
||||
{
|
||||
if (aMsg->is_urgent())
|
||||
return UrgentCall(aMsg, aReply);
|
||||
if (aMsg->is_rpc())
|
||||
return RPCCall(aMsg, aReply);
|
||||
return InterruptCall(aMsg, aReply);
|
||||
}
|
||||
|
||||
bool
|
||||
MessageChannel::InterruptCall(Message* aMsg, Message* aReply)
|
||||
{
|
||||
AssertWorkerThread();
|
||||
mMonitor->AssertNotCurrentThreadOwns();
|
||||
|
@ -796,13 +792,12 @@ MessageChannel::InterruptCall(Message* aMsg, Message* aReply)
|
|||
}
|
||||
|
||||
// Sanity checks.
|
||||
IPC_ASSERT(!AwaitingSyncReply() && !AwaitingUrgentReply(),
|
||||
"cannot issue Interrupt call whiel blocked on sync or urgent");
|
||||
IPC_ASSERT(!DispatchingSyncMessage() || aMsg->priority() == IPC::Message::PRIORITY_HIGH,
|
||||
IPC_ASSERT(!AwaitingSyncReply(),
|
||||
"cannot issue Interrupt call while blocked on sync request");
|
||||
IPC_ASSERT(!DispatchingSyncMessage(),
|
||||
"violation of sync handler invariant");
|
||||
IPC_ASSERT(aMsg->is_interrupt(), "can only Call() Interrupt messages here");
|
||||
|
||||
|
||||
nsAutoPtr<Message> msg(aMsg);
|
||||
|
||||
msg->set_seqno(NextSeqno());
|
||||
|
@ -818,7 +813,7 @@ MessageChannel::InterruptCall(Message* aMsg, Message* aReply)
|
|||
// trying another loop iteration will be futile because
|
||||
// channel state will have been cleared
|
||||
if (!Connected()) {
|
||||
ReportConnectionError("MessageChannel::InterruptCall");
|
||||
ReportConnectionError("MessageChannel::Call");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -845,14 +840,8 @@ MessageChannel::InterruptCall(Message* aMsg, Message* aReply)
|
|||
Message recvd;
|
||||
MessageMap::iterator it;
|
||||
|
||||
if (mPendingUrgentRequest) {
|
||||
recvd = *mPendingUrgentRequest;
|
||||
mPendingUrgentRequest = nullptr;
|
||||
} else if (mPendingRPCCall) {
|
||||
recvd = *mPendingRPCCall;
|
||||
mPendingRPCCall = nullptr;
|
||||
} else if ((it = mOutOfTurnReplies.find(mInterruptStack.top().seqno()))
|
||||
!= mOutOfTurnReplies.end())
|
||||
if ((it = mOutOfTurnReplies.find(mInterruptStack.top().seqno()))
|
||||
!= mOutOfTurnReplies.end())
|
||||
{
|
||||
recvd = it->second;
|
||||
mOutOfTurnReplies.erase(it);
|
||||
|
@ -870,11 +859,8 @@ MessageChannel::InterruptCall(Message* aMsg, Message* aReply)
|
|||
|
||||
// If the message is not Interrupt, we can dispatch it as normal.
|
||||
if (!recvd.is_interrupt()) {
|
||||
// Other side should be blocked.
|
||||
IPC_ASSERT(!recvd.is_sync() || mPending.empty(), "other side should be blocked");
|
||||
|
||||
{
|
||||
AutoEnterRPCTransaction transaction(this, &recvd);
|
||||
AutoEnterTransaction transaction(this, &recvd);
|
||||
MonitorAutoUnlock unlock(*mMonitor);
|
||||
CxxStackFrame frame(*this, IN_MESSAGE, &recvd);
|
||||
DispatchMessage(recvd);
|
||||
|
@ -955,15 +941,13 @@ MessageChannel::InterruptEventOccurred()
|
|||
|
||||
return (!Connected() ||
|
||||
!mPending.empty() ||
|
||||
mPendingUrgentRequest ||
|
||||
mPendingRPCCall ||
|
||||
(!mOutOfTurnReplies.empty() &&
|
||||
mOutOfTurnReplies.find(mInterruptStack.top().seqno()) !=
|
||||
mOutOfTurnReplies.end()));
|
||||
}
|
||||
|
||||
bool
|
||||
MessageChannel::ProcessPendingUrgentRequest()
|
||||
MessageChannel::ProcessPendingRequest(Message aUrgent)
|
||||
{
|
||||
AssertWorkerThread();
|
||||
mMonitor->AssertCurrentThreadOwns();
|
||||
|
@ -978,57 +962,16 @@ MessageChannel::ProcessPendingUrgentRequest()
|
|||
// to save the reply.
|
||||
nsAutoPtr<Message> savedReply(mRecvd.forget());
|
||||
|
||||
// We're the child process. We should not be receiving RPC calls.
|
||||
IPC_ASSERT(!mPendingRPCCall, "unexpected RPC call");
|
||||
|
||||
nsAutoPtr<Message> recvd(mPendingUrgentRequest.forget());
|
||||
{
|
||||
// In order to send the parent RPC messages and guarantee it will
|
||||
// wake up, we must re-use its transaction.
|
||||
AutoEnterRPCTransaction transaction(this, recvd);
|
||||
AutoEnterTransaction transaction(this, &aUrgent);
|
||||
|
||||
MonitorAutoUnlock unlock(*mMonitor);
|
||||
DispatchUrgentMessage(*recvd);
|
||||
DispatchMessage(aUrgent);
|
||||
}
|
||||
if (!Connected()) {
|
||||
ReportConnectionError("MessageChannel::DispatchUrgentMessage");
|
||||
return false;
|
||||
}
|
||||
|
||||
// In between having dispatched our reply to the parent process, and
|
||||
// re-acquiring the monitor, the parent process could have already
|
||||
// processed that reply and sent the reply to our sync message. If so,
|
||||
// our saved reply should be empty.
|
||||
IPC_ASSERT(!mRecvd || !savedReply, "unknown reply");
|
||||
if (!mRecvd)
|
||||
mRecvd = savedReply.forget();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
MessageChannel::ProcessPendingRPCCall()
|
||||
{
|
||||
AssertWorkerThread();
|
||||
mMonitor->AssertCurrentThreadOwns();
|
||||
|
||||
// See comment above re: mRecvd replies and incoming calls.
|
||||
nsAutoPtr<Message> savedReply(mRecvd.forget());
|
||||
|
||||
IPC_ASSERT(!mPendingUrgentRequest, "unexpected urgent message");
|
||||
|
||||
nsAutoPtr<Message> recvd(mPendingRPCCall.forget());
|
||||
{
|
||||
// If we are not currently in a transaction, this will begin one,
|
||||
// and the link thread will not wake us up for any RPC messages not
|
||||
// apart of this transaction. If we are already in a transaction,
|
||||
// then this will assert that we're still in the same transaction.
|
||||
AutoEnterRPCTransaction transaction(this, recvd);
|
||||
|
||||
MonitorAutoUnlock unlock(*mMonitor);
|
||||
DispatchRPCMessage(*recvd);
|
||||
}
|
||||
if (!Connected()) {
|
||||
ReportConnectionError("MessageChannel::DispatchRPCMessage");
|
||||
ReportConnectionError("MessageChannel::ProcessPendingRequest");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1053,18 +996,6 @@ MessageChannel::DequeueOne(Message *recvd)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (mPendingUrgentRequest) {
|
||||
*recvd = *mPendingUrgentRequest;
|
||||
mPendingUrgentRequest = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mPendingRPCCall) {
|
||||
*recvd = *mPendingRPCCall;
|
||||
mPendingRPCCall = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!mDeferred.empty())
|
||||
MaybeUndeferIncall();
|
||||
|
||||
|
@ -1097,8 +1028,8 @@ MessageChannel::OnMaybeDequeueOne()
|
|||
|
||||
{
|
||||
// We should not be in a transaction yet if we're not blocked.
|
||||
MOZ_ASSERT(mCurrentRPCTransaction == 0);
|
||||
AutoEnterRPCTransaction transaction(this, &recvd);
|
||||
MOZ_ASSERT(mCurrentTransaction == 0);
|
||||
AutoEnterTransaction transaction(this, &recvd);
|
||||
|
||||
MonitorAutoUnlock unlock(*mMonitor);
|
||||
|
||||
|
@ -1113,12 +1044,8 @@ MessageChannel::DispatchMessage(const Message &aMsg)
|
|||
{
|
||||
if (aMsg.is_sync())
|
||||
DispatchSyncMessage(aMsg);
|
||||
else if (aMsg.is_urgent())
|
||||
DispatchUrgentMessage(aMsg);
|
||||
else if (aMsg.is_interrupt())
|
||||
DispatchInterruptMessage(aMsg, 0);
|
||||
else if (aMsg.is_rpc())
|
||||
DispatchRPCMessage(aMsg);
|
||||
else
|
||||
DispatchAsyncMessage(aMsg);
|
||||
}
|
||||
|
@ -1130,72 +1057,36 @@ MessageChannel::DispatchSyncMessage(const Message& aMsg)
|
|||
|
||||
Message *reply = nullptr;
|
||||
|
||||
mDispatchingSyncMessage = true;
|
||||
Result rv = mListener->OnMessageReceived(aMsg, reply);
|
||||
mDispatchingSyncMessage = false;
|
||||
|
||||
if (!MaybeHandleError(rv, aMsg, "DispatchSyncMessage")) {
|
||||
delete reply;
|
||||
reply = new Message();
|
||||
reply->set_sync();
|
||||
reply->set_reply();
|
||||
reply->set_reply_error();
|
||||
}
|
||||
reply->set_seqno(aMsg.seqno());
|
||||
|
||||
MonitorAutoLock lock(*mMonitor);
|
||||
if (ChannelConnected == mChannelState)
|
||||
mLink->SendMessage(reply);
|
||||
}
|
||||
|
||||
void
|
||||
MessageChannel::DispatchUrgentMessage(const Message& aMsg)
|
||||
{
|
||||
AssertWorkerThread();
|
||||
MOZ_ASSERT(aMsg.is_urgent());
|
||||
|
||||
Message *reply = nullptr;
|
||||
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
int prio = aMsg.priority();
|
||||
|
||||
// We don't want to run any code that might run a nested event loop here, so
|
||||
// we avoid running event handlers. Once we've sent the response to the
|
||||
// urgent message, it's okay to run event handlers again since the parent is
|
||||
// no longer blocked.
|
||||
//
|
||||
// We also put script blockers at the start of every synchronous send
|
||||
// call. That way we won't run any scripts while waiting for a response to
|
||||
// another message. Running scripts could cause us to send more sync
|
||||
// messages, and the other side wouldn't know what to do if it received a
|
||||
// sync message while dispatching another sync message. (In practice, the
|
||||
// other side would queue the second sync message, while we would need it to
|
||||
// dispatch that message before sending the reply to the original sync
|
||||
// message. Otherwise the replies would come out of order.)
|
||||
//
|
||||
// We omit the script blocker for InterruptCall since interrupt messages are
|
||||
// designed to handle this sort of re-entry. (For example, if the child
|
||||
// sends an intr message to the parent, the child will process any queued
|
||||
// async messages from the parent while waiting for the intr response. In
|
||||
// doing so, the child could trigger sync messages to be sent to the parent
|
||||
// while the parent is still dispatching the intr message. If the parent
|
||||
// sends an intr reply while the child is waiting for a sync response, the
|
||||
// intr reply will be queued in mPending. Once the sync reply is received,
|
||||
// InterruptCall will find the intr reply in mPending and run it.) The
|
||||
// situation where we run event handlers while waiting for an intr reply is
|
||||
// no different than the one where we process async messages while waiting
|
||||
// for an intr reply.
|
||||
MaybeScriptBlocker scriptBlocker(this);
|
||||
MOZ_ASSERT_IF(prio > IPC::Message::PRIORITY_NORMAL, NS_IsMainThread());
|
||||
MaybeScriptBlocker scriptBlocker(this, prio > IPC::Message::PRIORITY_NORMAL);
|
||||
|
||||
gDispatchingUrgentMessageCount++;
|
||||
mDispatchingUrgentMessageCount++;
|
||||
Result rv = mListener->OnCallReceived(aMsg, reply);
|
||||
mDispatchingUrgentMessageCount--;
|
||||
gDispatchingUrgentMessageCount--;
|
||||
IPC_ASSERT(prio >= mDispatchingSyncMessagePriority,
|
||||
"priority inversion while dispatching sync message");
|
||||
IPC_ASSERT(prio >= mAwaitingSyncReplyPriority,
|
||||
"dispatching a message of lower priority while waiting for a response");
|
||||
|
||||
if (!MaybeHandleError(rv, aMsg, "DispatchUrgentMessage")) {
|
||||
bool dummy;
|
||||
bool& blockingVar = ShouldBlockScripts() ? gParentIsBlocked : dummy;
|
||||
|
||||
Result rv;
|
||||
{
|
||||
AutoSetValue<bool> blocked(blockingVar, true);
|
||||
AutoSetValue<bool> sync(mDispatchingSyncMessage, true);
|
||||
AutoSetValue<int> prioSet(mDispatchingSyncMessagePriority, prio);
|
||||
rv = mListener->OnMessageReceived(aMsg, reply);
|
||||
}
|
||||
|
||||
if (!MaybeHandleError(rv, aMsg, "DispatchSyncMessage")) {
|
||||
delete reply;
|
||||
reply = new Message();
|
||||
reply->set_urgent();
|
||||
reply->set_sync();
|
||||
reply->set_priority(aMsg.priority());
|
||||
reply->set_reply();
|
||||
reply->set_reply_error();
|
||||
}
|
||||
|
@ -1206,33 +1097,11 @@ MessageChannel::DispatchUrgentMessage(const Message& aMsg)
|
|||
mLink->SendMessage(reply);
|
||||
}
|
||||
|
||||
void
|
||||
MessageChannel::DispatchRPCMessage(const Message& aMsg)
|
||||
{
|
||||
AssertWorkerThread();
|
||||
MOZ_ASSERT(aMsg.is_rpc());
|
||||
|
||||
Message *reply = nullptr;
|
||||
|
||||
if (!MaybeHandleError(mListener->OnCallReceived(aMsg, reply), aMsg, "DispatchRPCMessage")) {
|
||||
delete reply;
|
||||
reply = new Message();
|
||||
reply->set_rpc();
|
||||
reply->set_reply();
|
||||
reply->set_reply_error();
|
||||
}
|
||||
reply->set_seqno(aMsg.seqno());
|
||||
|
||||
MonitorAutoLock lock(*mMonitor);
|
||||
if (ChannelConnected == mChannelState)
|
||||
mLink->SendMessage(reply);
|
||||
}
|
||||
|
||||
void
|
||||
MessageChannel::DispatchAsyncMessage(const Message& aMsg)
|
||||
{
|
||||
AssertWorkerThread();
|
||||
MOZ_ASSERT(!aMsg.is_interrupt() && !aMsg.is_sync() && !aMsg.is_urgent());
|
||||
MOZ_ASSERT(!aMsg.is_interrupt() && !aMsg.is_sync());
|
||||
|
||||
if (aMsg.routing_id() == MSG_ROUTING_NONE) {
|
||||
NS_RUNTIMEABORT("unhandled special message!");
|
||||
|
@ -1346,6 +1215,7 @@ MessageChannel::MaybeUndeferIncall()
|
|||
IPC_ASSERT(0 < mRemoteStackDepthGuess, "fatal logic error");
|
||||
--mRemoteStackDepthGuess;
|
||||
|
||||
MOZ_ASSERT(call.priority() == IPC::Message::PRIORITY_NORMAL);
|
||||
mPending.push_back(call);
|
||||
}
|
||||
|
||||
|
@ -1618,7 +1488,7 @@ MessageChannel::OnChannelErrorFromLink()
|
|||
if (InterruptStackDepth() > 0)
|
||||
NotifyWorkerThread();
|
||||
|
||||
if (AwaitingSyncReply() || AwaitingRPCReply() || AwaitingUrgentReply())
|
||||
if (AwaitingSyncReply())
|
||||
NotifyWorkerThread();
|
||||
|
||||
if (ChannelClosing != mChannelState) {
|
||||
|
@ -1856,9 +1726,9 @@ MessageChannel::DumpInterruptStack(const char* const pfx) const
|
|||
}
|
||||
|
||||
bool
|
||||
ProcessingUrgentMessages()
|
||||
ParentProcessIsBlocked()
|
||||
{
|
||||
return gDispatchingUrgentMessageCount > 0;
|
||||
return gParentIsBlocked;
|
||||
}
|
||||
|
||||
} // ipc
|
||||
|
|
|
@ -226,14 +226,9 @@ class MessageChannel : HasResultCodes
|
|||
// up to process urgent calls from the parent.
|
||||
bool SendAndWait(Message* aMsg, Message* aReply);
|
||||
|
||||
bool RPCCall(Message* aMsg, Message* aReply);
|
||||
bool InterruptCall(Message* aMsg, Message* aReply);
|
||||
bool UrgentCall(Message* aMsg, Message* aReply);
|
||||
|
||||
bool InterruptEventOccurred();
|
||||
|
||||
bool ProcessPendingUrgentRequest();
|
||||
bool ProcessPendingRPCCall();
|
||||
bool ProcessPendingRequest(Message aUrgent);
|
||||
|
||||
void MaybeUndeferIncall();
|
||||
void EnqueuePendingMessages();
|
||||
|
@ -327,15 +322,11 @@ class MessageChannel : HasResultCodes
|
|||
// Returns true if we're blocking waiting for a reply.
|
||||
bool AwaitingSyncReply() const {
|
||||
mMonitor->AssertCurrentThreadOwns();
|
||||
return mPendingSyncReplies > 0;
|
||||
return mAwaitingSyncReply;
|
||||
}
|
||||
bool AwaitingUrgentReply() const {
|
||||
int AwaitingSyncReplyPriority() const {
|
||||
mMonitor->AssertCurrentThreadOwns();
|
||||
return mPendingUrgentReplies > 0;
|
||||
}
|
||||
bool AwaitingRPCReply() const {
|
||||
mMonitor->AssertCurrentThreadOwns();
|
||||
return mPendingRPCReplies > 0;
|
||||
return mAwaitingSyncReplyPriority;
|
||||
}
|
||||
bool AwaitingInterruptReply() const {
|
||||
mMonitor->AssertCurrentThreadOwns();
|
||||
|
@ -344,12 +335,13 @@ class MessageChannel : HasResultCodes
|
|||
|
||||
// Returns true if we're dispatching a sync message's callback.
|
||||
bool DispatchingSyncMessage() const {
|
||||
AssertWorkerThread();
|
||||
return mDispatchingSyncMessage;
|
||||
}
|
||||
|
||||
// Returns true if we're dispatching an urgent message's callback.
|
||||
bool DispatchingUrgentMessage() const {
|
||||
return mDispatchingUrgentMessageCount > 0;
|
||||
int DispatchingSyncMessagePriority() const {
|
||||
AssertWorkerThread();
|
||||
return mDispatchingSyncMessagePriority;
|
||||
}
|
||||
|
||||
bool Connected() const;
|
||||
|
@ -367,6 +359,7 @@ class MessageChannel : HasResultCodes
|
|||
// Tell the IO thread to close the channel and wait for it to ACK.
|
||||
void SynchronouslyClose();
|
||||
|
||||
bool ShouldDeferMessage(const Message& aMsg);
|
||||
void OnMessageReceivedFromLink(const Message& aMsg);
|
||||
void OnChannelErrorFromLink();
|
||||
|
||||
|
@ -460,29 +453,30 @@ class MessageChannel : HasResultCodes
|
|||
|
||||
static bool sIsPumpingMessages;
|
||||
|
||||
class AutoEnterPendingReply {
|
||||
template<class T>
|
||||
class AutoSetValue {
|
||||
public:
|
||||
explicit AutoEnterPendingReply(size_t &replyVar)
|
||||
: mReplyVar(replyVar)
|
||||
explicit AutoSetValue(T &var, const T &newValue)
|
||||
: mVar(var), mPrev(var)
|
||||
{
|
||||
mReplyVar++;
|
||||
mVar = newValue;
|
||||
}
|
||||
~AutoEnterPendingReply() {
|
||||
mReplyVar--;
|
||||
~AutoSetValue() {
|
||||
mVar = mPrev;
|
||||
}
|
||||
private:
|
||||
size_t& mReplyVar;
|
||||
T& mVar;
|
||||
T mPrev;
|
||||
};
|
||||
|
||||
// Worker-thread only; type we're expecting for the reply to a sync
|
||||
// out-message. This will never be greater than 1.
|
||||
size_t mPendingSyncReplies;
|
||||
// Worker thread only.
|
||||
bool mAwaitingSyncReply;
|
||||
int mAwaitingSyncReplyPriority;
|
||||
|
||||
// Worker-thread only; Number of urgent and rpc replies we're waiting on.
|
||||
// These are mutually exclusive since one channel cannot have outcalls of
|
||||
// both kinds.
|
||||
size_t mPendingUrgentReplies;
|
||||
size_t mPendingRPCReplies;
|
||||
// Set while we are dispatching a synchronous message. Only for use on the
|
||||
// worker thread.
|
||||
bool mDispatchingSyncMessage;
|
||||
int mDispatchingSyncMessagePriority;
|
||||
|
||||
// When we send an urgent request from the parent process, we could race
|
||||
// with an RPC message that was issued by the child beforehand. In this
|
||||
|
@ -498,40 +492,40 @@ class MessageChannel : HasResultCodes
|
|||
// messages the parent receives, not apart of this transaction, are
|
||||
// deferred. When issuing RPC/urgent requests on top of a started
|
||||
// transaction, the initiating transaction ID is used.
|
||||
//
|
||||
//
|
||||
// To ensure IDs are unique, we use sequence numbers for transaction IDs,
|
||||
// which grow in opposite directions from child to parent.
|
||||
|
||||
// The current transaction ID.
|
||||
int32_t mCurrentRPCTransaction;
|
||||
int32_t mCurrentTransaction;
|
||||
|
||||
class AutoEnterRPCTransaction
|
||||
class AutoEnterTransaction
|
||||
{
|
||||
public:
|
||||
explicit AutoEnterRPCTransaction(MessageChannel *aChan)
|
||||
explicit AutoEnterTransaction(MessageChannel *aChan)
|
||||
: mChan(aChan),
|
||||
mOldTransaction(mChan->mCurrentRPCTransaction)
|
||||
mOldTransaction(mChan->mCurrentTransaction)
|
||||
{
|
||||
mChan->mMonitor->AssertCurrentThreadOwns();
|
||||
if (mChan->mCurrentRPCTransaction == 0)
|
||||
mChan->mCurrentRPCTransaction = mChan->NextSeqno();
|
||||
if (mChan->mCurrentTransaction == 0)
|
||||
mChan->mCurrentTransaction = mChan->NextSeqno();
|
||||
}
|
||||
AutoEnterRPCTransaction(MessageChannel *aChan, Message *message)
|
||||
explicit AutoEnterTransaction(MessageChannel *aChan, Message *message)
|
||||
: mChan(aChan),
|
||||
mOldTransaction(mChan->mCurrentRPCTransaction)
|
||||
mOldTransaction(mChan->mCurrentTransaction)
|
||||
{
|
||||
mChan->mMonitor->AssertCurrentThreadOwns();
|
||||
|
||||
if (!message->is_rpc() && !message->is_urgent())
|
||||
if (!message->is_sync())
|
||||
return;
|
||||
|
||||
MOZ_ASSERT_IF(mChan->mSide == ParentSide,
|
||||
!mOldTransaction || mOldTransaction == message->transaction_id());
|
||||
mChan->mCurrentRPCTransaction = message->transaction_id();
|
||||
MOZ_ASSERT_IF(mChan->mSide == ParentSide && mOldTransaction != message->transaction_id(),
|
||||
!mOldTransaction || message->priority() > mChan->AwaitingSyncReplyPriority());
|
||||
mChan->mCurrentTransaction = message->transaction_id();
|
||||
}
|
||||
~AutoEnterRPCTransaction() {
|
||||
~AutoEnterTransaction() {
|
||||
mChan->mMonitor->AssertCurrentThreadOwns();
|
||||
mChan->mCurrentRPCTransaction = mOldTransaction;
|
||||
mChan->mCurrentTransaction = mOldTransaction;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -543,12 +537,6 @@ class MessageChannel : HasResultCodes
|
|||
// on the I/O thread and then read and cleared by the worker thread.
|
||||
nsAutoPtr<Message> mRecvd;
|
||||
|
||||
// Set while we are dispatching a synchronous message.
|
||||
bool mDispatchingSyncMessage;
|
||||
|
||||
// Count of the recursion depth of dispatching urgent messages.
|
||||
size_t mDispatchingUrgentMessageCount;
|
||||
|
||||
// Queue of all incoming messages, except for replies to sync and urgent
|
||||
// messages, which are delivered directly to mRecvd, and any pending urgent
|
||||
// incall, which is stored in mPendingUrgentRequest.
|
||||
|
@ -587,18 +575,6 @@ class MessageChannel : HasResultCodes
|
|||
//
|
||||
MessageQueue mPending;
|
||||
|
||||
// Note that these two pointers are mutually exclusive. One channel cannot
|
||||
// send both urgent requests (parent -> child) and RPC calls (child->parent).
|
||||
// Also note that since initiating either requires blocking, they cannot
|
||||
// queue up on the other side. One message slot is enough.
|
||||
//
|
||||
// Normally, all other message types are deferred into into mPending, and
|
||||
// only these two types have special treatment (since they wake up blocked
|
||||
// requests). However, when an RPC in-call races with an urgent out-call,
|
||||
// the RPC message will be put into mPending instead of its slot below.
|
||||
nsAutoPtr<Message> mPendingUrgentRequest;
|
||||
nsAutoPtr<Message> mPendingRPCCall;
|
||||
|
||||
// Stack of all the out-calls on which this channel is awaiting responses.
|
||||
// Each stack refers to a different protocol and the stacks are mutually
|
||||
// exclusive: multiple outcalls of the same kind cannot be initiated while
|
||||
|
@ -676,7 +652,7 @@ class MessageChannel : HasResultCodes
|
|||
};
|
||||
|
||||
bool
|
||||
ProcessingUrgentMessages();
|
||||
ParentProcessIsBlocked();
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
|
||||
import sys
|
||||
|
||||
NORMAL_PRIORITY = 1
|
||||
HIGH_PRIORITY = 2
|
||||
URGENT_PRIORITY = 3
|
||||
|
||||
class Visitor:
|
||||
def defaultVisit(self, node):
|
||||
raise Exception, "INTERNAL ERROR: no visitor for node type `%s'"% (
|
||||
|
@ -214,8 +218,6 @@ class INTR(PrettyPrinted):
|
|||
pretty = 'intr'
|
||||
class SYNC(PrettyPrinted):
|
||||
pretty = 'sync'
|
||||
class RPC(PrettyPrinted):
|
||||
pretty = 'rpc'
|
||||
|
||||
class INOUT(PrettyPrinted):
|
||||
pretty = 'inout'
|
||||
|
@ -234,6 +236,7 @@ class Protocol(NamespacedNode):
|
|||
def __init__(self, loc):
|
||||
NamespacedNode.__init__(self, loc)
|
||||
self.sendSemantics = ASYNC
|
||||
self.priority = NORMAL_PRIORITY
|
||||
self.spawnsStmts = [ ]
|
||||
self.bridgesStmts = [ ]
|
||||
self.opensStmts = [ ]
|
||||
|
@ -293,6 +296,7 @@ class MessageDecl(Node):
|
|||
Node.__init__(self, loc)
|
||||
self.name = None
|
||||
self.sendSemantics = ASYNC
|
||||
self.priority = NORMAL_PRIORITY
|
||||
self.direction = None
|
||||
self.inParams = [ ]
|
||||
self.outParams = [ ]
|
||||
|
@ -304,9 +308,6 @@ class MessageDecl(Node):
|
|||
def addOutParams(self, outParamsList):
|
||||
self.outParams += outParamsList
|
||||
|
||||
def hasReply(self):
|
||||
return self.sendSemantics is SYNC or self.sendSemantics is INTR
|
||||
|
||||
class Transition(Node):
|
||||
def __init__(self, loc, trigger, msg, toStates):
|
||||
Node.__init__(self, loc)
|
||||
|
|
|
@ -277,13 +277,13 @@ def _putInNamespaces(cxxthing, namespaces):
|
|||
|
||||
def _sendPrefix(msgtype):
|
||||
"""Prefix of the name of the C++ method that sends |msgtype|."""
|
||||
if msgtype.isInterrupt() or msgtype.isRpc():
|
||||
if msgtype.isInterrupt():
|
||||
return 'Call'
|
||||
return 'Send'
|
||||
|
||||
def _recvPrefix(msgtype):
|
||||
"""Prefix of the name of the C++ method that handles |msgtype|."""
|
||||
if msgtype.isInterrupt() or msgtype.isRpc():
|
||||
if msgtype.isInterrupt():
|
||||
return 'Answer'
|
||||
return 'Recv'
|
||||
|
||||
|
@ -2984,7 +2984,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
|||
ExprCall(ExprSelect(p.channelVar(), '.', 'Close'))))
|
||||
self.cls.addstmts([ closemeth, Whitespace.NL ])
|
||||
|
||||
if ptype.talksSync() or ptype.talksInterrupt():
|
||||
if ptype.isSync() or ptype.isInterrupt():
|
||||
# SetReplyTimeoutMs()
|
||||
timeoutvar = ExprVar('aTimeoutMs')
|
||||
settimeout = MethodDefn(MethodDecl(
|
||||
|
@ -3053,9 +3053,11 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
|||
|
||||
msgtype = ExprCall(ExprSelect(msgvar, '.', 'type'), [ ])
|
||||
self.asyncSwitch = StmtSwitch(msgtype)
|
||||
if toplevel.talksSync():
|
||||
self.syncSwitch = None
|
||||
self.interruptSwitch = None
|
||||
if toplevel.isSync() or toplevel.isInterrupt():
|
||||
self.syncSwitch = StmtSwitch(msgtype)
|
||||
if toplevel.talksRpc():
|
||||
if toplevel.isInterrupt():
|
||||
self.interruptSwitch = StmtSwitch(msgtype)
|
||||
|
||||
# implement Send*() methods and add dispatcher cases to
|
||||
|
@ -3072,9 +3074,9 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
|||
default = StmtBlock()
|
||||
default.addstmt(StmtReturn(_Result.NotKnown))
|
||||
self.asyncSwitch.addcase(DefaultLabel(), default)
|
||||
if toplevel.talksSync():
|
||||
if toplevel.isSync() or toplevel.isInterrupt():
|
||||
self.syncSwitch.addcase(DefaultLabel(), default)
|
||||
if toplevel.talksRpc():
|
||||
if toplevel.isInterrupt():
|
||||
self.interruptSwitch.addcase(DefaultLabel(), default)
|
||||
|
||||
# FIXME/bug 535053: only manager protocols and non-manager
|
||||
|
@ -3151,10 +3153,6 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
|||
hasReply=0, dispatches=dispatches),
|
||||
Whitespace.NL
|
||||
])
|
||||
if not toplevel.talksRpc():
|
||||
self.interruptSwitch = None
|
||||
if not toplevel.talksSync():
|
||||
self.syncSwitch = None
|
||||
self.cls.addstmts([
|
||||
makeHandlerMethod('OnMessageReceived', self.syncSwitch,
|
||||
hasReply=1, dispatches=dispatches),
|
||||
|
@ -3190,7 +3188,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
|||
self.cls.addstmts([ gettypetag, Whitespace.NL ])
|
||||
|
||||
# OnReplyTimeout()
|
||||
if toplevel.talksSync() or toplevel.talksInterrupt():
|
||||
if toplevel.isSync() or toplevel.isInterrupt():
|
||||
ontimeout = MethodDefn(
|
||||
MethodDecl('OnReplyTimeout', ret=Type.BOOL))
|
||||
|
||||
|
@ -3278,7 +3276,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
|||
# User-facing shmem methods
|
||||
self.cls.addstmts(self.makeShmemIface())
|
||||
|
||||
if (ptype.isToplevel() and ptype.talksInterrupt()):
|
||||
if (ptype.isToplevel() and ptype.isInterrupt()):
|
||||
|
||||
processnative = MethodDefn(
|
||||
MethodDecl('ProcessNativeEventsInInterruptCall', ret=Type.VOID))
|
||||
|
@ -4780,22 +4778,22 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
|||
def visitMessageDecl(self, md):
|
||||
isctor = md.decl.type.isCtor()
|
||||
isdtor = md.decl.type.isDtor()
|
||||
sems = md.decl.type.sendSemantics
|
||||
decltype = md.decl.type
|
||||
sendmethod = None
|
||||
helpermethod = None
|
||||
recvlbl, recvcase = None, None
|
||||
|
||||
def addRecvCase(lbl, case):
|
||||
if sems is ipdl.ast.ASYNC:
|
||||
if decltype.isAsync():
|
||||
self.asyncSwitch.addcase(lbl, case)
|
||||
elif sems is ipdl.ast.SYNC:
|
||||
elif decltype.isSync():
|
||||
self.syncSwitch.addcase(lbl, case)
|
||||
elif sems is ipdl.ast.INTR or sems is ipdl.ast.RPC:
|
||||
elif decltype.isInterrupt():
|
||||
self.interruptSwitch.addcase(lbl, case)
|
||||
else: assert 0
|
||||
|
||||
if self.sendsMessage(md):
|
||||
isasync = (sems is ipdl.ast.ASYNC)
|
||||
isasync = decltype.isAsync()
|
||||
|
||||
if isctor:
|
||||
self.cls.addstmts([ self.genHelperCtor(md), Whitespace.NL ])
|
||||
|
@ -5185,21 +5183,14 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
|||
if md.decl.type.isSync():
|
||||
stmts.append(StmtExpr(ExprCall(
|
||||
ExprSelect(var, '->', 'set_sync'))))
|
||||
elif md.decl.type.isRpc():
|
||||
# We use urgent messages from the parent to the child and
|
||||
# RPC messages from the child to the parent. However,
|
||||
# replies should always be sent using the same semantics
|
||||
# as the original message, so we need to flip.
|
||||
if (self.side == 'parent') ^ reply:
|
||||
stmts.append(StmtExpr(ExprCall(
|
||||
ExprSelect(var, '->', 'set_urgent'))))
|
||||
else:
|
||||
stmts.append(StmtExpr(ExprCall(
|
||||
ExprSelect(var, '->', 'set_rpc'))))
|
||||
elif md.decl.type.isInterrupt():
|
||||
stmts.append(StmtExpr(ExprCall(
|
||||
ExprSelect(var, '->', 'set_interrupt'))))
|
||||
|
||||
stmts.append(StmtExpr(ExprCall(
|
||||
ExprSelect(var, '->', 'set_priority'),
|
||||
args=[ ExprLiteral.Int(md.decl.type.priority) ])))
|
||||
|
||||
if reply:
|
||||
stmts.append(StmtExpr(ExprCall(
|
||||
ExprSelect(var, '->', 'set_reply'))))
|
||||
|
|
|
@ -127,19 +127,21 @@ reserved = set((
|
|||
'delete', # reserve 'delete' to prevent its use
|
||||
'from',
|
||||
'goto',
|
||||
'high',
|
||||
'include',
|
||||
'intr',
|
||||
'manager',
|
||||
'manages',
|
||||
'namespace',
|
||||
'normal',
|
||||
'nullable',
|
||||
'opens',
|
||||
'or',
|
||||
'parent',
|
||||
'prio',
|
||||
'protocol',
|
||||
'recv',
|
||||
'returns',
|
||||
'rpc',
|
||||
'send',
|
||||
'spawns',
|
||||
'start',
|
||||
|
@ -147,9 +149,11 @@ reserved = set((
|
|||
'struct',
|
||||
'sync',
|
||||
'union',
|
||||
'upto',
|
||||
'urgent',
|
||||
'using'))
|
||||
tokens = [
|
||||
'COLONCOLON', 'ID', 'STRING'
|
||||
'COLONCOLON', 'ID', 'STRING',
|
||||
] + [ r.upper() for r in reserved ]
|
||||
|
||||
t_COLONCOLON = '::'
|
||||
|
@ -349,11 +353,12 @@ def p_ComponentTypes(p):
|
|||
p[0] = p[1]
|
||||
|
||||
def p_ProtocolDefn(p):
|
||||
"""ProtocolDefn : OptionalSendSemanticsQual PROTOCOL ID '{' ProtocolBody '}' ';'"""
|
||||
"""ProtocolDefn : OptionalProtocolSendSemanticsQual PROTOCOL ID '{' ProtocolBody '}' ';'"""
|
||||
protocol = p[5]
|
||||
protocol.loc = locFromTok(p, 2)
|
||||
protocol.name = p[3]
|
||||
protocol.sendSemantics = p[1]
|
||||
protocol.priorityRange = p[1][0]
|
||||
protocol.sendSemantics = p[1][1]
|
||||
p[0] = protocol
|
||||
|
||||
if Parser.current.type == 'header':
|
||||
|
@ -495,7 +500,8 @@ def p_MessageDirectionLabel(p):
|
|||
def p_MessageDecl(p):
|
||||
"""MessageDecl : OptionalSendSemanticsQual MessageBody"""
|
||||
msg = p[2]
|
||||
msg.sendSemantics = p[1]
|
||||
msg.priority = p[1][0]
|
||||
msg.sendSemantics = p[1][1]
|
||||
|
||||
if Parser.current.direction is None:
|
||||
_error(msg.loc, 'missing message direction')
|
||||
|
@ -615,24 +621,67 @@ def p_State(p):
|
|||
|
||||
##--------------------
|
||||
## Minor stuff
|
||||
def p_Priority(p):
|
||||
"""Priority : NORMAL
|
||||
| HIGH
|
||||
| URGENT"""
|
||||
prios = {'normal': 1,
|
||||
'high': 2,
|
||||
'urgent': 3}
|
||||
p[0] = prios[p[1]]
|
||||
|
||||
def p_OptionalSendSemanticsQual(p):
|
||||
"""OptionalSendSemanticsQual : SendSemanticsQual
|
||||
| """
|
||||
if 2 == len(p): p[0] = p[1]
|
||||
else: p[0] = ASYNC
|
||||
else: p[0] = [ NORMAL_PRIORITY, ASYNC ]
|
||||
|
||||
def p_SendSemanticsQual(p):
|
||||
"""SendSemanticsQual : ASYNC
|
||||
| INTR
|
||||
| RPC
|
||||
| SYNC"""
|
||||
s = p[1]
|
||||
if 'async' == s: p[0] = ASYNC
|
||||
elif 'intr' == s: p[0] = INTR
|
||||
elif 'sync' == s: p[0] = SYNC
|
||||
elif 'rpc' == s: p[0] = RPC
|
||||
| SYNC
|
||||
| PRIO '(' Priority ')' ASYNC
|
||||
| PRIO '(' Priority ')' SYNC
|
||||
| INTR"""
|
||||
if p[1] == 'prio':
|
||||
mtype = p[5]
|
||||
prio = p[3]
|
||||
else:
|
||||
assert 0
|
||||
mtype = p[1]
|
||||
prio = NORMAL_PRIORITY
|
||||
|
||||
if mtype == 'async': mtype = ASYNC
|
||||
elif mtype == 'sync': mtype = SYNC
|
||||
elif mtype == 'intr': mtype = INTR
|
||||
else: assert 0
|
||||
|
||||
p[0] = [ prio, mtype ]
|
||||
|
||||
def p_OptionalProtocolSendSemanticsQual(p):
|
||||
"""OptionalProtocolSendSemanticsQual : ProtocolSendSemanticsQual
|
||||
| """
|
||||
if 2 == len(p): p[0] = p[1]
|
||||
else: p[0] = [ (NORMAL_PRIORITY, NORMAL_PRIORITY), ASYNC ]
|
||||
|
||||
def p_ProtocolSendSemanticsQual(p):
|
||||
"""ProtocolSendSemanticsQual : ASYNC
|
||||
| SYNC
|
||||
| PRIO '(' Priority UPTO Priority ')' ASYNC
|
||||
| PRIO '(' Priority UPTO Priority ')' SYNC
|
||||
| PRIO '(' Priority UPTO Priority ')' INTR
|
||||
| INTR"""
|
||||
if p[1] == 'prio':
|
||||
mtype = p[7]
|
||||
prio = (p[3], p[5])
|
||||
else:
|
||||
mtype = p[1]
|
||||
prio = (NORMAL_PRIORITY, NORMAL_PRIORITY)
|
||||
|
||||
if mtype == 'async': mtype = ASYNC
|
||||
elif mtype == 'sync': mtype = SYNC
|
||||
elif mtype == 'intr': mtype = INTR
|
||||
else: assert 0
|
||||
|
||||
p[0] = [ prio, mtype ]
|
||||
|
||||
def p_ParamList(p):
|
||||
"""ParamList : ParamList ',' Param
|
||||
|
|
|
@ -6,8 +6,10 @@
|
|||
import os, sys
|
||||
|
||||
from ipdl.ast import CxxInclude, Decl, Loc, QualifiedId, State, StructDecl, TransitionStmt
|
||||
from ipdl.ast import TypeSpec, UnionDecl, UsingStmt, Visitor, ASYNC, SYNC, INTR
|
||||
from ipdl.ast import IN, OUT, INOUT, ANSWER, CALL, RECV, SEND, RPC
|
||||
from ipdl.ast import TypeSpec, UnionDecl, UsingStmt, Visitor
|
||||
from ipdl.ast import ASYNC, SYNC, INTR
|
||||
from ipdl.ast import IN, OUT, INOUT, ANSWER, CALL, RECV, SEND
|
||||
from ipdl.ast import NORMAL_PRIORITY, HIGH_PRIORITY, URGENT_PRIORITY
|
||||
import ipdl.builtin as builtin
|
||||
|
||||
_DELETE_MSG = '__delete__'
|
||||
|
@ -204,24 +206,29 @@ class IPDLType(Type):
|
|||
def isChmod(self): return False
|
||||
def isFD(self): return False
|
||||
|
||||
def isAsync(self): return self.sendSemantics is ASYNC
|
||||
def isSync(self): return self.sendSemantics is SYNC
|
||||
def isAsync(self): return self.sendSemantics == ASYNC
|
||||
def isSync(self): return self.sendSemantics == SYNC
|
||||
def isInterrupt(self): return self.sendSemantics is INTR
|
||||
def isRpc(self): return self.sendSemantics is RPC
|
||||
|
||||
def talksAsync(self): return True
|
||||
def talksSync(self): return self.isSync() or self.isRpc() or self.isInterrupt()
|
||||
def talksRpc(self): return self.isRpc() or self.isInterrupt()
|
||||
def talksInterrupt(self): return self.isInterrupt()
|
||||
def hasReply(self): return (self.isSync() or self.isInterrupt())
|
||||
|
||||
def hasReply(self): return (self.isSync()
|
||||
or self.isInterrupt()
|
||||
or self.isRpc())
|
||||
@classmethod
|
||||
def convertsTo(cls, lesser, greater):
|
||||
if (lesser.priorityRange[0] < greater.priorityRange[0] or
|
||||
lesser.priorityRange[1] > greater.priorityRange[1]):
|
||||
return False
|
||||
|
||||
if lesser.isAsync():
|
||||
return True
|
||||
elif lesser.isSync() and not greater.isAsync():
|
||||
return True
|
||||
elif greater.isInterrupt():
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def needsMoreJuiceThan(self, o):
|
||||
return (o.isAsync() and not self.isAsync()
|
||||
or o.isSync() and self.isRpc()
|
||||
or o.isRpc() and self.isInterrupt())
|
||||
return not IPDLType.convertsTo(self, o)
|
||||
|
||||
class StateType(IPDLType):
|
||||
def __init__(self, protocol, name, start=False):
|
||||
|
@ -235,11 +242,13 @@ class StateType(IPDLType):
|
|||
return self.name()
|
||||
|
||||
class MessageType(IPDLType):
|
||||
def __init__(self, sendSemantics, direction,
|
||||
def __init__(self, priority, sendSemantics, direction,
|
||||
ctor=False, dtor=False, cdtype=None, compress=False):
|
||||
assert not (ctor and dtor)
|
||||
assert not (ctor or dtor) or type is not None
|
||||
|
||||
self.priority = priority
|
||||
self.priorityRange = (priority, priority)
|
||||
self.sendSemantics = sendSemantics
|
||||
self.direction = direction
|
||||
self.params = [ ]
|
||||
|
@ -275,8 +284,9 @@ class Bridge:
|
|||
return hash(self.parent) + hash(self.child)
|
||||
|
||||
class ProtocolType(IPDLType):
|
||||
def __init__(self, qname, sendSemantics, stateless=False):
|
||||
def __init__(self, qname, priorityRange, sendSemantics, stateless=False):
|
||||
self.qname = qname
|
||||
self.priorityRange = priorityRange
|
||||
self.sendSemantics = sendSemantics
|
||||
self.spawns = set() # ProtocolType
|
||||
self.opens = set() # ProtocolType
|
||||
|
@ -684,7 +694,7 @@ class GatherDecls(TcheckVisitor):
|
|||
fullname = str(qname)
|
||||
p.decl = self.declare(
|
||||
loc=p.loc,
|
||||
type=ProtocolType(qname, p.sendSemantics,
|
||||
type=ProtocolType(qname, p.priorityRange, p.sendSemantics,
|
||||
stateless=(0 == len(p.transitionStmts))),
|
||||
shortname=p.name,
|
||||
fullname=fullname)
|
||||
|
@ -1083,7 +1093,7 @@ class GatherDecls(TcheckVisitor):
|
|||
# enter message scope
|
||||
self.symtab.enterScope(md)
|
||||
|
||||
msgtype = MessageType(md.sendSemantics, md.direction,
|
||||
msgtype = MessageType(md.priority, md.sendSemantics, md.direction,
|
||||
ctor=isctor, dtor=isdtor, cdtype=cdtype,
|
||||
compress=(md.compress == 'compress'))
|
||||
|
||||
|
@ -1457,7 +1467,22 @@ class CheckTypes(TcheckVisitor):
|
|||
|
||||
loc = md.decl.loc
|
||||
|
||||
if mtype.isSync() and (mtype.isOut() or mtype.isInout()):
|
||||
if mtype.priority == HIGH_PRIORITY and not mtype.isSync():
|
||||
self.error(
|
||||
loc,
|
||||
"high priority messages must be sync (here, message `%s' in protocol `%s')",
|
||||
mname, pname)
|
||||
|
||||
if mtype.priority == URGENT_PRIORITY and (mtype.isOut() or mtype.isInout()):
|
||||
self.error(
|
||||
loc,
|
||||
"urgent parent-to-child messages are verboten (here, message `%s' in protocol `%s')",
|
||||
mname, pname)
|
||||
|
||||
# We allow high priority sync messages to be sent from the
|
||||
# parent. Normal and urgent sync messages can only come from
|
||||
# the child.
|
||||
if mtype.isSync() and mtype.priority == NORMAL_PRIORITY and (mtype.isOut() or mtype.isInout()):
|
||||
self.error(
|
||||
loc,
|
||||
"sync parent-to-child messages are verboten (here, message `%s' in protocol `%s')",
|
||||
|
|
|
@ -19,7 +19,7 @@ include $(topsrcdir)/config/rules.mk
|
|||
|
||||
IPDLUNITTEST_BIN = $(DEPTH)/dist/bin/ipdlunittest$(BIN_SUFFIX)
|
||||
|
||||
IPDLUnitTests.cpp : Makefile.in $(GENTESTER) $(TESTER_TEMPLATE) $(IPDLTESTHDRS)
|
||||
IPDLUnitTests.cpp : Makefile.in moz.build $(GENTESTER) $(TESTER_TEMPLATE) $(IPDLTESTHDRS)
|
||||
$(PYTHON) $(GENTESTER) $(TESTER_TEMPLATE) -t $(IPDLTESTS) -e $(EXTRA_PROTOCOLS) > $@
|
||||
|
||||
check-proc::
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
namespace mozilla {
|
||||
namespace _ipdltest {
|
||||
|
||||
prio(normal upto urgent) sync protocol PTestHighestPrio
|
||||
{
|
||||
parent:
|
||||
prio(urgent) async Msg1();
|
||||
sync Msg2();
|
||||
prio(urgent) async Msg3();
|
||||
prio(urgent) sync Msg4();
|
||||
|
||||
child:
|
||||
async Start();
|
||||
prio(high) sync StartInner();
|
||||
};
|
||||
|
||||
}
|
||||
}
|
|
@ -1,26 +1,25 @@
|
|||
namespace mozilla {
|
||||
namespace _ipdltest {
|
||||
|
||||
intr protocol PTestRPC
|
||||
prio(normal upto high) sync protocol PTestRPC
|
||||
{
|
||||
parent:
|
||||
rpc Test1_Start() returns (uint32_t result);
|
||||
rpc Test1_InnerEvent() returns (uint32_t result);
|
||||
prio(high) sync Test1_Start() returns (uint32_t result);
|
||||
prio(high) sync Test1_InnerEvent() returns (uint32_t result);
|
||||
async Test2_Start();
|
||||
rpc Test2_OutOfOrder();
|
||||
prio(high) sync Test2_Msg2();
|
||||
prio(high) sync Test2_FirstUrgent();
|
||||
prio(high) sync Test2_SecondUrgent();
|
||||
sync Test3_Start() returns (uint32_t result);
|
||||
rpc Test3_InnerEvent() returns (uint32_t result);
|
||||
intr Test4_Start() returns (uint32_t result);
|
||||
rpc Test4_Inner() returns (uint32_t result);
|
||||
prio(high) sync Test3_InnerEvent() returns (uint32_t result);
|
||||
|
||||
child:
|
||||
async Start();
|
||||
rpc Test1_InnerQuery() returns (uint32_t result);
|
||||
rpc Test1_NoReenter() returns (uint32_t result);
|
||||
rpc Test2_FirstUrgent();
|
||||
rpc Test2_SecondUrgent();
|
||||
rpc Test3_WakeUp() returns (uint32_t result);
|
||||
rpc Test4_WakeUp() returns (uint32_t result);
|
||||
prio(high) sync Test1_InnerQuery() returns (uint32_t result);
|
||||
prio(high) sync Test1_NoReenter() returns (uint32_t result);
|
||||
prio(high) sync Test2_Msg1();
|
||||
prio(high) sync Test2_Msg3();
|
||||
prio(high) sync Test3_WakeUp() returns (uint32_t result);
|
||||
};
|
||||
|
||||
} // namespace _ipdltest
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
namespace mozilla {
|
||||
namespace _ipdltest {
|
||||
|
||||
intr protocol PTestUrgency
|
||||
prio(normal upto high) sync protocol PTestUrgency
|
||||
{
|
||||
parent:
|
||||
sync Test1() returns (uint32_t result);
|
||||
|
@ -11,8 +11,8 @@ parent:
|
|||
|
||||
child:
|
||||
async Start();
|
||||
rpc Reply1() returns (uint32_t result);
|
||||
rpc Reply2() returns (uint32_t result);
|
||||
prio(high) sync Reply1() returns (uint32_t result);
|
||||
prio(high) sync Reply2() returns (uint32_t result);
|
||||
};
|
||||
|
||||
} // namespace _ipdltest
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: sw=4 ts=4 et :
|
||||
*/
|
||||
/* 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 "TestHighestPrio.h"
|
||||
|
||||
#include "IPDLUnitTests.h" // fail etc.
|
||||
#if defined(OS_POSIX)
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace _ipdltest {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// parent
|
||||
|
||||
TestHighestPrioParent::TestHighestPrioParent()
|
||||
: msg_num_(0)
|
||||
{
|
||||
MOZ_COUNT_CTOR(TestHighestPrioParent);
|
||||
}
|
||||
|
||||
TestHighestPrioParent::~TestHighestPrioParent()
|
||||
{
|
||||
MOZ_COUNT_DTOR(TestHighestPrioParent);
|
||||
}
|
||||
|
||||
void
|
||||
TestHighestPrioParent::Main()
|
||||
{
|
||||
if (!SendStart())
|
||||
fail("sending Start");
|
||||
}
|
||||
|
||||
bool
|
||||
TestHighestPrioParent::RecvMsg1()
|
||||
{
|
||||
MOZ_ASSERT(msg_num_ == 0);
|
||||
msg_num_ = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TestHighestPrioParent::RecvMsg2()
|
||||
{
|
||||
|
||||
MOZ_ASSERT(msg_num_ == 1);
|
||||
msg_num_ = 2;
|
||||
|
||||
if (!SendStartInner())
|
||||
fail("sending StartInner");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TestHighestPrioParent::RecvMsg3()
|
||||
{
|
||||
MOZ_ASSERT(msg_num_ == 2);
|
||||
msg_num_ = 3;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TestHighestPrioParent::RecvMsg4()
|
||||
{
|
||||
MOZ_ASSERT(msg_num_ == 3);
|
||||
msg_num_ = 4;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// child
|
||||
|
||||
|
||||
TestHighestPrioChild::TestHighestPrioChild()
|
||||
{
|
||||
MOZ_COUNT_CTOR(TestHighestPrioChild);
|
||||
}
|
||||
|
||||
TestHighestPrioChild::~TestHighestPrioChild()
|
||||
{
|
||||
MOZ_COUNT_DTOR(TestHighestPrioChild);
|
||||
}
|
||||
|
||||
bool
|
||||
TestHighestPrioChild::RecvStart()
|
||||
{
|
||||
if (!SendMsg1())
|
||||
fail("sending Msg1");
|
||||
|
||||
if (!SendMsg2())
|
||||
fail("sending Msg2");
|
||||
|
||||
Close();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TestHighestPrioChild::RecvStartInner()
|
||||
{
|
||||
if (!SendMsg3())
|
||||
fail("sending Msg3");
|
||||
|
||||
if (!SendMsg4())
|
||||
fail("sending Msg4");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace _ipdltest
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,68 @@
|
|||
#ifndef mozilla__ipdltest_TestHighestPrio_h
|
||||
#define mozilla__ipdltest_TestHighestPrio_h 1
|
||||
|
||||
#include "mozilla/_ipdltest/IPDLUnitTests.h"
|
||||
|
||||
#include "mozilla/_ipdltest/PTestHighestPrioParent.h"
|
||||
#include "mozilla/_ipdltest/PTestHighestPrioChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace _ipdltest {
|
||||
|
||||
|
||||
class TestHighestPrioParent :
|
||||
public PTestHighestPrioParent
|
||||
{
|
||||
public:
|
||||
TestHighestPrioParent();
|
||||
virtual ~TestHighestPrioParent();
|
||||
|
||||
static bool RunTestInProcesses() { return true; }
|
||||
static bool RunTestInThreads() { return false; }
|
||||
|
||||
void Main();
|
||||
|
||||
bool RecvMsg1() MOZ_OVERRIDE;
|
||||
bool RecvMsg2() MOZ_OVERRIDE;
|
||||
bool RecvMsg3() MOZ_OVERRIDE;
|
||||
bool RecvMsg4() MOZ_OVERRIDE;
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE
|
||||
{
|
||||
if (NormalShutdown != why)
|
||||
fail("unexpected destruction!");
|
||||
if (msg_num_ != 4)
|
||||
fail("missed IPC call");
|
||||
passed("ok");
|
||||
QuitParent();
|
||||
}
|
||||
|
||||
private:
|
||||
int msg_num_;
|
||||
};
|
||||
|
||||
|
||||
class TestHighestPrioChild :
|
||||
public PTestHighestPrioChild
|
||||
{
|
||||
public:
|
||||
TestHighestPrioChild();
|
||||
virtual ~TestHighestPrioChild();
|
||||
|
||||
bool RecvStart() MOZ_OVERRIDE;
|
||||
bool RecvStartInner() MOZ_OVERRIDE;
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE
|
||||
{
|
||||
if (NormalShutdown != why)
|
||||
fail("unexpected destruction!");
|
||||
QuitChild();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace _ipdltest
|
||||
} // namespace mozilla
|
||||
|
||||
|
||||
#endif // ifndef mozilla__ipdltest_TestHighestPrio_h
|
|
@ -14,8 +14,6 @@ namespace _ipdltest {
|
|||
// parent
|
||||
|
||||
TestRPCParent::TestRPCParent()
|
||||
: reentered_(false),
|
||||
resolved_first_cpow_(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(TestRPCParent);
|
||||
}
|
||||
|
@ -33,11 +31,11 @@ TestRPCParent::Main()
|
|||
}
|
||||
|
||||
bool
|
||||
TestRPCParent::AnswerTest1_Start(uint32_t* aResult)
|
||||
TestRPCParent::RecvTest1_Start(uint32_t* aResult)
|
||||
{
|
||||
uint32_t result;
|
||||
if (!CallTest1_InnerQuery(&result))
|
||||
fail("CallTest1_InnerQuery");
|
||||
if (!SendTest1_InnerQuery(&result))
|
||||
fail("SendTest1_InnerQuery");
|
||||
if (result != 300)
|
||||
fail("Wrong result (expected 300)");
|
||||
|
||||
|
@ -46,11 +44,11 @@ TestRPCParent::AnswerTest1_Start(uint32_t* aResult)
|
|||
}
|
||||
|
||||
bool
|
||||
TestRPCParent::AnswerTest1_InnerEvent(uint32_t* aResult)
|
||||
TestRPCParent::RecvTest1_InnerEvent(uint32_t* aResult)
|
||||
{
|
||||
uint32_t result;
|
||||
if (!CallTest1_NoReenter(&result))
|
||||
fail("CallTest1_NoReenter");
|
||||
if (!SendTest1_NoReenter(&result))
|
||||
fail("SendTest1_NoReenter");
|
||||
if (result != 400)
|
||||
fail("Wrong result (expected 400)");
|
||||
|
||||
|
@ -61,65 +59,56 @@ TestRPCParent::AnswerTest1_InnerEvent(uint32_t* aResult)
|
|||
bool
|
||||
TestRPCParent::RecvTest2_Start()
|
||||
{
|
||||
// Send a CPOW. During this time, we must NOT process the RPC message, as
|
||||
// we could start receiving CPOW replies out-of-order.
|
||||
if (!CallTest2_FirstUrgent())
|
||||
fail("CallTest2_FirstUrgent");
|
||||
if (!SendTest2_Msg1())
|
||||
fail("SendTest2_Msg1");
|
||||
|
||||
MOZ_ASSERT(!reentered_);
|
||||
resolved_first_cpow_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TestRPCParent::AnswerTest2_OutOfOrder()
|
||||
TestRPCParent::RecvTest2_Msg2()
|
||||
{
|
||||
// Send a CPOW. If this RPC call was initiated while waiting for the first
|
||||
// CPOW to resolve, replies will be processed out of order, and we'll crash.
|
||||
if (!CallTest2_SecondUrgent())
|
||||
fail("CallTest2_SecondUrgent");
|
||||
if (!SendTest2_Msg3())
|
||||
fail("SendTest2_Msg3");
|
||||
|
||||
reentered_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TestRPCParent::RecvTest2_FirstUrgent()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TestRPCParent::RecvTest2_SecondUrgent()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TestRPCParent::RecvTest3_Start(uint32_t* aResult)
|
||||
{
|
||||
if (!CallTest3_WakeUp(aResult))
|
||||
fail("CallTest3_WakeUp");
|
||||
if (!SendTest3_WakeUp(aResult))
|
||||
fail("SendTest3_WakeUp");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TestRPCParent::AnswerTest3_InnerEvent(uint32_t* aResult)
|
||||
TestRPCParent::RecvTest3_InnerEvent(uint32_t* aResult)
|
||||
{
|
||||
*aResult = 200;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TestRPCParent::AnswerTest4_Start(uint32_t* aResult)
|
||||
{
|
||||
if (!CallTest4_WakeUp(aResult))
|
||||
fail("CallTest4_WakeUp");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TestRPCParent::AnswerTest4_Inner(uint32_t* aResult)
|
||||
{
|
||||
*aResult = 700;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// child
|
||||
|
||||
|
||||
TestRPCChild::TestRPCChild()
|
||||
: reentered_(false),
|
||||
resolved_first_cpow_(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(TestRPCChild);
|
||||
}
|
||||
|
@ -133,16 +122,16 @@ bool
|
|||
TestRPCChild::RecvStart()
|
||||
{
|
||||
uint32_t result;
|
||||
if (!CallTest1_Start(&result))
|
||||
fail("CallTest1_Start");
|
||||
if (!SendTest1_Start(&result))
|
||||
fail("SendTest1_Start");
|
||||
if (result != 100)
|
||||
fail("Wrong result (expected 100)");
|
||||
|
||||
if (!SendTest2_Start())
|
||||
fail("SendTest2_Start");
|
||||
|
||||
if (!CallTest2_OutOfOrder())
|
||||
fail("CallTest2_OutOfOrder");
|
||||
if (!SendTest2_Msg2())
|
||||
fail("SendTest2_Msg2");
|
||||
|
||||
result = 0;
|
||||
if (!SendTest3_Start(&result))
|
||||
|
@ -150,22 +139,16 @@ TestRPCChild::RecvStart()
|
|||
if (result != 200)
|
||||
fail("Wrong result (expected 200)");
|
||||
|
||||
// See bug 937216 (RPC calls within interrupts).
|
||||
if (!CallTest4_Start(&result))
|
||||
fail("SendTest4_Start");
|
||||
if (result != 700)
|
||||
fail("Wrong result (expected 700)");
|
||||
|
||||
Close();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TestRPCChild::AnswerTest1_InnerQuery(uint32_t* aResult)
|
||||
TestRPCChild::RecvTest1_InnerQuery(uint32_t* aResult)
|
||||
{
|
||||
uint32_t result;
|
||||
if (!CallTest1_InnerEvent(&result))
|
||||
fail("CallTest1_InnerEvent");
|
||||
if (!SendTest1_InnerEvent(&result))
|
||||
fail("SendTest1_InnerEvent");
|
||||
if (result != 200)
|
||||
fail("Wrong result (expected 200)");
|
||||
|
||||
|
@ -174,38 +157,43 @@ TestRPCChild::AnswerTest1_InnerQuery(uint32_t* aResult)
|
|||
}
|
||||
|
||||
bool
|
||||
TestRPCChild::AnswerTest1_NoReenter(uint32_t* aResult)
|
||||
TestRPCChild::RecvTest1_NoReenter(uint32_t* aResult)
|
||||
{
|
||||
*aResult = 400;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TestRPCChild::AnswerTest2_FirstUrgent()
|
||||
bool TestRPCChild::RecvTest2_Msg1()
|
||||
{
|
||||
MOZ_ASSERT(resolved_first_cpow_);
|
||||
|
||||
// Send a CPOW. If this RPC call was initiated while waiting for the first
|
||||
// CPOW to resolve, replies will be processed out of order, and we'll crash.
|
||||
if (!SendTest2_SecondUrgent())
|
||||
fail("SendTest2_SecondUrgent");
|
||||
|
||||
reentered_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TestRPCChild::AnswerTest2_SecondUrgent()
|
||||
TestRPCChild::RecvTest2_Msg3()
|
||||
{
|
||||
// Send a CPOW. During this time, we must NOT process the RPC message, as
|
||||
// we could start receiving CPOW replies out-of-order.
|
||||
if (!SendTest2_FirstUrgent())
|
||||
fail("SendTest2_FirstUrgent");
|
||||
|
||||
MOZ_ASSERT(!reentered_);
|
||||
resolved_first_cpow_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TestRPCChild::AnswerTest3_WakeUp(uint32_t* aResult)
|
||||
TestRPCChild::RecvTest3_WakeUp(uint32_t* aResult)
|
||||
{
|
||||
if (!CallTest3_InnerEvent(aResult))
|
||||
fail("CallTest3_InnerEvent");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TestRPCChild::AnswerTest4_WakeUp(uint32_t* aResult)
|
||||
{
|
||||
if (!CallTest4_Inner(aResult))
|
||||
fail("CallTest4_Inner");
|
||||
if (!SendTest3_InnerEvent(aResult))
|
||||
fail("SendTest3_InnerEvent");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -22,30 +22,22 @@ public:
|
|||
|
||||
void Main();
|
||||
|
||||
bool AnswerTest1_Start(uint32_t* aResult) MOZ_OVERRIDE;
|
||||
bool AnswerTest1_InnerEvent(uint32_t* aResult) MOZ_OVERRIDE;
|
||||
bool RecvTest1_Start(uint32_t* aResult) MOZ_OVERRIDE;
|
||||
bool RecvTest1_InnerEvent(uint32_t* aResult) MOZ_OVERRIDE;
|
||||
bool RecvTest2_Start() MOZ_OVERRIDE;
|
||||
bool AnswerTest2_OutOfOrder() MOZ_OVERRIDE;
|
||||
bool RecvTest2_Msg2() MOZ_OVERRIDE;
|
||||
bool RecvTest2_FirstUrgent() MOZ_OVERRIDE;
|
||||
bool RecvTest2_SecondUrgent() MOZ_OVERRIDE;
|
||||
bool RecvTest3_Start(uint32_t* aResult) MOZ_OVERRIDE;
|
||||
bool AnswerTest3_InnerEvent(uint32_t* aResult) MOZ_OVERRIDE;
|
||||
bool AnswerTest4_Start(uint32_t* aResult) MOZ_OVERRIDE;
|
||||
bool AnswerTest4_Inner(uint32_t* aResult) MOZ_OVERRIDE;
|
||||
bool RecvTest3_InnerEvent(uint32_t* aResult) MOZ_OVERRIDE;
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE
|
||||
{
|
||||
if (NormalShutdown != why)
|
||||
fail("unexpected destruction!");
|
||||
if (!reentered_)
|
||||
fail("never processed raced RPC call!");
|
||||
if (!resolved_first_cpow_)
|
||||
fail("never resolved first CPOW!");
|
||||
passed("ok");
|
||||
QuitParent();
|
||||
}
|
||||
|
||||
private:
|
||||
bool reentered_;
|
||||
bool resolved_first_cpow_;
|
||||
};
|
||||
|
||||
|
||||
|
@ -57,12 +49,11 @@ public:
|
|||
virtual ~TestRPCChild();
|
||||
|
||||
bool RecvStart() MOZ_OVERRIDE;
|
||||
bool AnswerTest1_InnerQuery(uint32_t* aResult) MOZ_OVERRIDE;
|
||||
bool AnswerTest1_NoReenter(uint32_t* aResult) MOZ_OVERRIDE;
|
||||
bool AnswerTest2_FirstUrgent() MOZ_OVERRIDE;
|
||||
bool AnswerTest2_SecondUrgent() MOZ_OVERRIDE;
|
||||
bool AnswerTest3_WakeUp(uint32_t* aResult) MOZ_OVERRIDE;
|
||||
bool AnswerTest4_WakeUp(uint32_t* aResult) MOZ_OVERRIDE;
|
||||
bool RecvTest1_InnerQuery(uint32_t* aResult) MOZ_OVERRIDE;
|
||||
bool RecvTest1_NoReenter(uint32_t* aResult) MOZ_OVERRIDE;
|
||||
bool RecvTest2_Msg1() MOZ_OVERRIDE;
|
||||
bool RecvTest2_Msg3() MOZ_OVERRIDE;
|
||||
bool RecvTest3_WakeUp(uint32_t* aResult) MOZ_OVERRIDE;
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE
|
||||
{
|
||||
|
@ -70,6 +61,10 @@ public:
|
|||
fail("unexpected destruction!");
|
||||
QuitChild();
|
||||
}
|
||||
|
||||
private:
|
||||
bool reentered_;
|
||||
bool resolved_first_cpow_;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ TestUrgencyParent::Main()
|
|||
bool
|
||||
TestUrgencyParent::RecvTest1(uint32_t *value)
|
||||
{
|
||||
if (!CallReply1(value))
|
||||
if (!SendReply1(value))
|
||||
fail("sending Reply1");
|
||||
if (*value != 99)
|
||||
fail("bad value");
|
||||
|
@ -60,7 +60,7 @@ TestUrgencyParent::RecvTest2()
|
|||
{
|
||||
uint32_t value;
|
||||
inreply_ = true;
|
||||
if (!CallReply2(&value))
|
||||
if (!SendReply2(&value))
|
||||
fail("sending Reply2");
|
||||
inreply_ = false;
|
||||
if (value != 500)
|
||||
|
@ -130,10 +130,10 @@ TestUrgencyChild::RecvStart()
|
|||
}
|
||||
|
||||
bool
|
||||
TestUrgencyChild::AnswerReply1(uint32_t *reply)
|
||||
TestUrgencyChild::RecvReply1(uint32_t *reply)
|
||||
{
|
||||
if (test_ != kFirstTestBegin)
|
||||
fail("wrong test # in AnswerReply1");
|
||||
fail("wrong test # in RecvReply1");
|
||||
|
||||
*reply = 99;
|
||||
test_ = kFirstTestGotReply;
|
||||
|
@ -141,10 +141,10 @@ TestUrgencyChild::AnswerReply1(uint32_t *reply)
|
|||
}
|
||||
|
||||
bool
|
||||
TestUrgencyChild::AnswerReply2(uint32_t *reply)
|
||||
TestUrgencyChild::RecvReply2(uint32_t *reply)
|
||||
{
|
||||
if (test_ != kSecondTestBegin)
|
||||
fail("wrong test # in AnswerReply2");
|
||||
fail("wrong test # in RecvReply2");
|
||||
|
||||
// sleep for 5 seconds so the parent process tries to deliver more messages.
|
||||
Sleep(5000);
|
||||
|
|
|
@ -52,10 +52,8 @@ public:
|
|||
virtual ~TestUrgencyChild();
|
||||
|
||||
bool RecvStart();
|
||||
bool AnswerReply1(uint32_t *reply);
|
||||
bool AnswerReply2(uint32_t *reply);
|
||||
bool AnswerTest4_Reenter();
|
||||
bool AnswerFinalTest_Hang();
|
||||
bool RecvReply1(uint32_t *reply);
|
||||
bool RecvReply2(uint32_t *reply);
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE
|
||||
{
|
||||
|
|
|
@ -22,6 +22,7 @@ SOURCES += [
|
|||
'TestDesc.cpp',
|
||||
'TestFailedCtor.cpp',
|
||||
'TestHangs.cpp',
|
||||
'TestHighestPrio.cpp',
|
||||
'TestInterruptErrorCleanup.cpp',
|
||||
'TestInterruptRaces.cpp',
|
||||
'TestInterruptShutdownRace.cpp',
|
||||
|
@ -82,6 +83,7 @@ IPDL_SOURCES += [
|
|||
'PTestFailedCtorSubsub.ipdl',
|
||||
'PTestHandle.ipdl',
|
||||
'PTestHangs.ipdl',
|
||||
'PTestHighestPrio.ipdl',
|
||||
'PTestIndirectProtocolParam.ipdlh',
|
||||
'PTestIndirectProtocolParamFirst.ipdl',
|
||||
'PTestIndirectProtocolParamManage.ipdl',
|
||||
|
|
|
@ -9,7 +9,7 @@ include protocol PTestShellCommand;
|
|||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
intr protocol PTestShell
|
||||
async protocol PTestShell
|
||||
{
|
||||
manager PContent;
|
||||
|
||||
|
|
|
@ -35,91 +35,91 @@ class JavaScriptBase : public WrapperOwner, public WrapperAnswer, public Base
|
|||
|
||||
/*** IPC handlers ***/
|
||||
|
||||
bool AnswerPreventExtensions(const uint64_t &objId, ReturnStatus *rs) {
|
||||
return Answer::AnswerPreventExtensions(ObjectId::deserialize(objId), rs);
|
||||
bool RecvPreventExtensions(const uint64_t &objId, ReturnStatus *rs) {
|
||||
return Answer::RecvPreventExtensions(ObjectId::deserialize(objId), rs);
|
||||
}
|
||||
bool AnswerGetPropertyDescriptor(const uint64_t &objId, const JSIDVariant &id,
|
||||
bool RecvGetPropertyDescriptor(const uint64_t &objId, const JSIDVariant &id,
|
||||
ReturnStatus *rs,
|
||||
PPropertyDescriptor *out) {
|
||||
return Answer::AnswerGetPropertyDescriptor(ObjectId::deserialize(objId), id, rs, out);
|
||||
return Answer::RecvGetPropertyDescriptor(ObjectId::deserialize(objId), id, rs, out);
|
||||
}
|
||||
bool AnswerGetOwnPropertyDescriptor(const uint64_t &objId,
|
||||
bool RecvGetOwnPropertyDescriptor(const uint64_t &objId,
|
||||
const JSIDVariant &id,
|
||||
ReturnStatus *rs,
|
||||
PPropertyDescriptor *out) {
|
||||
return Answer::AnswerGetOwnPropertyDescriptor(ObjectId::deserialize(objId), id, rs, out);
|
||||
return Answer::RecvGetOwnPropertyDescriptor(ObjectId::deserialize(objId), id, rs, out);
|
||||
}
|
||||
bool AnswerDefineProperty(const uint64_t &objId, const JSIDVariant &id,
|
||||
bool RecvDefineProperty(const uint64_t &objId, const JSIDVariant &id,
|
||||
const PPropertyDescriptor &flags,
|
||||
ReturnStatus *rs) {
|
||||
return Answer::AnswerDefineProperty(ObjectId::deserialize(objId), id, flags, rs);
|
||||
return Answer::RecvDefineProperty(ObjectId::deserialize(objId), id, flags, rs);
|
||||
}
|
||||
bool AnswerDelete(const uint64_t &objId, const JSIDVariant &id,
|
||||
bool RecvDelete(const uint64_t &objId, const JSIDVariant &id,
|
||||
ReturnStatus *rs, bool *success) {
|
||||
return Answer::AnswerDelete(ObjectId::deserialize(objId), id, rs, success);
|
||||
return Answer::RecvDelete(ObjectId::deserialize(objId), id, rs, success);
|
||||
}
|
||||
|
||||
bool AnswerHas(const uint64_t &objId, const JSIDVariant &id,
|
||||
bool RecvHas(const uint64_t &objId, const JSIDVariant &id,
|
||||
ReturnStatus *rs, bool *bp) {
|
||||
return Answer::AnswerHas(ObjectId::deserialize(objId), id, rs, bp);
|
||||
return Answer::RecvHas(ObjectId::deserialize(objId), id, rs, bp);
|
||||
}
|
||||
bool AnswerHasOwn(const uint64_t &objId, const JSIDVariant &id,
|
||||
bool RecvHasOwn(const uint64_t &objId, const JSIDVariant &id,
|
||||
ReturnStatus *rs, bool *bp) {
|
||||
return Answer::AnswerHasOwn(ObjectId::deserialize(objId), id, rs, bp);
|
||||
return Answer::RecvHasOwn(ObjectId::deserialize(objId), id, rs, bp);
|
||||
}
|
||||
bool AnswerGet(const uint64_t &objId, const ObjectVariant &receiverVar,
|
||||
bool RecvGet(const uint64_t &objId, const ObjectVariant &receiverVar,
|
||||
const JSIDVariant &id,
|
||||
ReturnStatus *rs, JSVariant *result) {
|
||||
return Answer::AnswerGet(ObjectId::deserialize(objId), receiverVar, id, rs, result);
|
||||
return Answer::RecvGet(ObjectId::deserialize(objId), receiverVar, id, rs, result);
|
||||
}
|
||||
bool AnswerSet(const uint64_t &objId, const ObjectVariant &receiverVar,
|
||||
bool RecvSet(const uint64_t &objId, const ObjectVariant &receiverVar,
|
||||
const JSIDVariant &id, const bool &strict,
|
||||
const JSVariant &value, ReturnStatus *rs, JSVariant *result) {
|
||||
return Answer::AnswerSet(ObjectId::deserialize(objId), receiverVar, id, strict, value, rs, result);
|
||||
return Answer::RecvSet(ObjectId::deserialize(objId), receiverVar, id, strict, value, rs, result);
|
||||
}
|
||||
|
||||
bool AnswerIsExtensible(const uint64_t &objId, ReturnStatus *rs,
|
||||
bool RecvIsExtensible(const uint64_t &objId, ReturnStatus *rs,
|
||||
bool *result) {
|
||||
return Answer::AnswerIsExtensible(ObjectId::deserialize(objId), rs, result);
|
||||
return Answer::RecvIsExtensible(ObjectId::deserialize(objId), rs, result);
|
||||
}
|
||||
bool AnswerCallOrConstruct(const uint64_t &objId, const nsTArray<JSParam> &argv,
|
||||
bool RecvCallOrConstruct(const uint64_t &objId, const nsTArray<JSParam> &argv,
|
||||
const bool &construct, ReturnStatus *rs, JSVariant *result,
|
||||
nsTArray<JSParam> *outparams) {
|
||||
return Answer::AnswerCallOrConstruct(ObjectId::deserialize(objId), argv, construct, rs, result, outparams);
|
||||
return Answer::RecvCallOrConstruct(ObjectId::deserialize(objId), argv, construct, rs, result, outparams);
|
||||
}
|
||||
bool AnswerHasInstance(const uint64_t &objId, const JSVariant &v, ReturnStatus *rs, bool *bp) {
|
||||
return Answer::AnswerHasInstance(ObjectId::deserialize(objId), v, rs, bp);
|
||||
bool RecvHasInstance(const uint64_t &objId, const JSVariant &v, ReturnStatus *rs, bool *bp) {
|
||||
return Answer::RecvHasInstance(ObjectId::deserialize(objId), v, rs, bp);
|
||||
}
|
||||
bool AnswerObjectClassIs(const uint64_t &objId, const uint32_t &classValue,
|
||||
bool RecvObjectClassIs(const uint64_t &objId, const uint32_t &classValue,
|
||||
bool *result) {
|
||||
return Answer::AnswerObjectClassIs(ObjectId::deserialize(objId), classValue, result);
|
||||
return Answer::RecvObjectClassIs(ObjectId::deserialize(objId), classValue, result);
|
||||
}
|
||||
bool AnswerClassName(const uint64_t &objId, nsString *result) {
|
||||
return Answer::AnswerClassName(ObjectId::deserialize(objId), result);
|
||||
bool RecvClassName(const uint64_t &objId, nsString *result) {
|
||||
return Answer::RecvClassName(ObjectId::deserialize(objId), result);
|
||||
}
|
||||
bool AnswerRegExpToShared(const uint64_t &objId, ReturnStatus *rs, nsString *source, uint32_t *flags) {
|
||||
return Answer::AnswerRegExpToShared(ObjectId::deserialize(objId), rs, source, flags);
|
||||
bool RecvRegExpToShared(const uint64_t &objId, ReturnStatus *rs, nsString *source, uint32_t *flags) {
|
||||
return Answer::RecvRegExpToShared(ObjectId::deserialize(objId), rs, source, flags);
|
||||
}
|
||||
|
||||
bool AnswerGetPropertyNames(const uint64_t &objId, const uint32_t &flags,
|
||||
bool RecvGetPropertyNames(const uint64_t &objId, const uint32_t &flags,
|
||||
ReturnStatus *rs, nsTArray<nsString> *names) {
|
||||
return Answer::AnswerGetPropertyNames(ObjectId::deserialize(objId), flags, rs, names);
|
||||
return Answer::RecvGetPropertyNames(ObjectId::deserialize(objId), flags, rs, names);
|
||||
}
|
||||
bool AnswerInstanceOf(const uint64_t &objId, const JSIID &iid,
|
||||
bool RecvInstanceOf(const uint64_t &objId, const JSIID &iid,
|
||||
ReturnStatus *rs, bool *instanceof) {
|
||||
return Answer::AnswerInstanceOf(ObjectId::deserialize(objId), iid, rs, instanceof);
|
||||
return Answer::RecvInstanceOf(ObjectId::deserialize(objId), iid, rs, instanceof);
|
||||
}
|
||||
bool AnswerDOMInstanceOf(const uint64_t &objId, const int &prototypeID, const int &depth,
|
||||
bool RecvDOMInstanceOf(const uint64_t &objId, const int &prototypeID, const int &depth,
|
||||
ReturnStatus *rs, bool *instanceof) {
|
||||
return Answer::AnswerDOMInstanceOf(ObjectId::deserialize(objId), prototypeID, depth, rs, instanceof);
|
||||
return Answer::RecvDOMInstanceOf(ObjectId::deserialize(objId), prototypeID, depth, rs, instanceof);
|
||||
}
|
||||
|
||||
bool AnswerIsCallable(const uint64_t &objId, bool *result) {
|
||||
return Answer::AnswerIsCallable(ObjectId::deserialize(objId), result);
|
||||
bool RecvIsCallable(const uint64_t &objId, bool *result) {
|
||||
return Answer::RecvIsCallable(ObjectId::deserialize(objId), result);
|
||||
}
|
||||
|
||||
bool AnswerIsConstructor(const uint64_t &objId, bool *result) {
|
||||
return Answer::AnswerIsConstructor(ObjectId::deserialize(objId), result);
|
||||
bool RecvIsConstructor(const uint64_t &objId, bool *result) {
|
||||
return Answer::RecvIsConstructor(ObjectId::deserialize(objId), result);
|
||||
}
|
||||
|
||||
bool RecvDropObject(const uint64_t &objId) {
|
||||
|
@ -131,93 +131,93 @@ class JavaScriptBase : public WrapperOwner, public WrapperAnswer, public Base
|
|||
bool SendDropObject(const ObjectId &objId) {
|
||||
return Base::SendDropObject(objId.serialize());
|
||||
}
|
||||
bool CallPreventExtensions(const ObjectId &objId, ReturnStatus *rs) {
|
||||
return Base::CallPreventExtensions(objId.serialize(), rs);
|
||||
bool SendPreventExtensions(const ObjectId &objId, ReturnStatus *rs) {
|
||||
return Base::SendPreventExtensions(objId.serialize(), rs);
|
||||
}
|
||||
bool CallGetPropertyDescriptor(const ObjectId &objId, const JSIDVariant &id,
|
||||
bool SendGetPropertyDescriptor(const ObjectId &objId, const JSIDVariant &id,
|
||||
ReturnStatus *rs,
|
||||
PPropertyDescriptor *out) {
|
||||
return Base::CallGetPropertyDescriptor(objId.serialize(), id, rs, out);
|
||||
return Base::SendGetPropertyDescriptor(objId.serialize(), id, rs, out);
|
||||
}
|
||||
bool CallGetOwnPropertyDescriptor(const ObjectId &objId,
|
||||
bool SendGetOwnPropertyDescriptor(const ObjectId &objId,
|
||||
const JSIDVariant &id,
|
||||
ReturnStatus *rs,
|
||||
PPropertyDescriptor *out) {
|
||||
return Base::CallGetOwnPropertyDescriptor(objId.serialize(), id, rs, out);
|
||||
return Base::SendGetOwnPropertyDescriptor(objId.serialize(), id, rs, out);
|
||||
}
|
||||
bool CallDefineProperty(const ObjectId &objId, const JSIDVariant &id,
|
||||
bool SendDefineProperty(const ObjectId &objId, const JSIDVariant &id,
|
||||
const PPropertyDescriptor &flags,
|
||||
ReturnStatus *rs) {
|
||||
return Base::CallDefineProperty(objId.serialize(), id, flags, rs);
|
||||
return Base::SendDefineProperty(objId.serialize(), id, flags, rs);
|
||||
}
|
||||
bool CallDelete(const ObjectId &objId, const JSIDVariant &id,
|
||||
bool SendDelete(const ObjectId &objId, const JSIDVariant &id,
|
||||
ReturnStatus *rs, bool *success) {
|
||||
return Base::CallDelete(objId.serialize(), id, rs, success);
|
||||
return Base::SendDelete(objId.serialize(), id, rs, success);
|
||||
}
|
||||
|
||||
bool CallHas(const ObjectId &objId, const JSIDVariant &id,
|
||||
bool SendHas(const ObjectId &objId, const JSIDVariant &id,
|
||||
ReturnStatus *rs, bool *bp) {
|
||||
return Base::CallHas(objId.serialize(), id, rs, bp);
|
||||
return Base::SendHas(objId.serialize(), id, rs, bp);
|
||||
}
|
||||
bool CallHasOwn(const ObjectId &objId, const JSIDVariant &id,
|
||||
bool SendHasOwn(const ObjectId &objId, const JSIDVariant &id,
|
||||
ReturnStatus *rs, bool *bp) {
|
||||
return Base::CallHasOwn(objId.serialize(), id, rs, bp);
|
||||
return Base::SendHasOwn(objId.serialize(), id, rs, bp);
|
||||
}
|
||||
bool CallGet(const ObjectId &objId, const ObjectVariant &receiverVar,
|
||||
bool SendGet(const ObjectId &objId, const ObjectVariant &receiverVar,
|
||||
const JSIDVariant &id,
|
||||
ReturnStatus *rs, JSVariant *result) {
|
||||
return Base::CallGet(objId.serialize(), receiverVar, id, rs, result);
|
||||
return Base::SendGet(objId.serialize(), receiverVar, id, rs, result);
|
||||
}
|
||||
bool CallSet(const ObjectId &objId, const ObjectVariant &receiverVar,
|
||||
bool SendSet(const ObjectId &objId, const ObjectVariant &receiverVar,
|
||||
const JSIDVariant &id, const bool &strict,
|
||||
const JSVariant &value, ReturnStatus *rs, JSVariant *result) {
|
||||
return Base::CallSet(objId.serialize(), receiverVar, id, strict, value, rs, result);
|
||||
return Base::SendSet(objId.serialize(), receiverVar, id, strict, value, rs, result);
|
||||
}
|
||||
|
||||
bool CallIsExtensible(const ObjectId &objId, ReturnStatus *rs,
|
||||
bool SendIsExtensible(const ObjectId &objId, ReturnStatus *rs,
|
||||
bool *result) {
|
||||
return Base::CallIsExtensible(objId.serialize(), rs, result);
|
||||
return Base::SendIsExtensible(objId.serialize(), rs, result);
|
||||
}
|
||||
bool CallCallOrConstruct(const ObjectId &objId, const nsTArray<JSParam> &argv,
|
||||
bool SendCallOrConstruct(const ObjectId &objId, const nsTArray<JSParam> &argv,
|
||||
const bool &construct, ReturnStatus *rs, JSVariant *result,
|
||||
nsTArray<JSParam> *outparams) {
|
||||
return Base::CallCallOrConstruct(objId.serialize(), argv, construct, rs, result, outparams);
|
||||
return Base::SendCallOrConstruct(objId.serialize(), argv, construct, rs, result, outparams);
|
||||
}
|
||||
bool CallHasInstance(const ObjectId &objId, const JSVariant &v, ReturnStatus *rs, bool *bp) {
|
||||
return Base::CallHasInstance(objId.serialize(), v, rs, bp);
|
||||
bool SendHasInstance(const ObjectId &objId, const JSVariant &v, ReturnStatus *rs, bool *bp) {
|
||||
return Base::SendHasInstance(objId.serialize(), v, rs, bp);
|
||||
}
|
||||
bool CallObjectClassIs(const ObjectId &objId, const uint32_t &classValue,
|
||||
bool SendObjectClassIs(const ObjectId &objId, const uint32_t &classValue,
|
||||
bool *result) {
|
||||
return Base::CallObjectClassIs(objId.serialize(), classValue, result);
|
||||
return Base::SendObjectClassIs(objId.serialize(), classValue, result);
|
||||
}
|
||||
bool CallClassName(const ObjectId &objId, nsString *result) {
|
||||
return Base::CallClassName(objId.serialize(), result);
|
||||
bool SendClassName(const ObjectId &objId, nsString *result) {
|
||||
return Base::SendClassName(objId.serialize(), result);
|
||||
}
|
||||
|
||||
bool CallRegExpToShared(const ObjectId &objId, ReturnStatus *rs,
|
||||
bool SendRegExpToShared(const ObjectId &objId, ReturnStatus *rs,
|
||||
nsString *source, uint32_t *flags) {
|
||||
return Base::CallRegExpToShared(objId.serialize(), rs, source, flags);
|
||||
return Base::SendRegExpToShared(objId.serialize(), rs, source, flags);
|
||||
}
|
||||
|
||||
bool CallGetPropertyNames(const ObjectId &objId, const uint32_t &flags,
|
||||
bool SendGetPropertyNames(const ObjectId &objId, const uint32_t &flags,
|
||||
ReturnStatus *rs, nsTArray<nsString> *names) {
|
||||
return Base::CallGetPropertyNames(objId.serialize(), flags, rs, names);
|
||||
return Base::SendGetPropertyNames(objId.serialize(), flags, rs, names);
|
||||
}
|
||||
bool CallInstanceOf(const ObjectId &objId, const JSIID &iid,
|
||||
bool SendInstanceOf(const ObjectId &objId, const JSIID &iid,
|
||||
ReturnStatus *rs, bool *instanceof) {
|
||||
return Base::CallInstanceOf(objId.serialize(), iid, rs, instanceof);
|
||||
return Base::SendInstanceOf(objId.serialize(), iid, rs, instanceof);
|
||||
}
|
||||
bool CallDOMInstanceOf(const ObjectId &objId, const int &prototypeID, const int &depth,
|
||||
bool SendDOMInstanceOf(const ObjectId &objId, const int &prototypeID, const int &depth,
|
||||
ReturnStatus *rs, bool *instanceof) {
|
||||
return Base::CallDOMInstanceOf(objId.serialize(), prototypeID, depth, rs, instanceof);
|
||||
return Base::SendDOMInstanceOf(objId.serialize(), prototypeID, depth, rs, instanceof);
|
||||
}
|
||||
|
||||
bool CallIsCallable(const ObjectId &objId, bool *result) {
|
||||
return Base::CallIsCallable(objId.serialize(), result);
|
||||
bool SendIsCallable(const ObjectId &objId, bool *result) {
|
||||
return Base::SendIsCallable(objId.serialize(), result);
|
||||
}
|
||||
|
||||
bool CallIsConstructor(const ObjectId &objId, bool *result) {
|
||||
return Base::CallIsConstructor(objId.serialize(), result);
|
||||
bool SendIsConstructor(const ObjectId &objId, bool *result) {
|
||||
return Base::SendIsConstructor(objId.serialize(), result);
|
||||
}
|
||||
|
||||
/* The following code is needed to suppress a bogus MSVC warning (C4250). */
|
||||
|
|
|
@ -15,7 +15,7 @@ using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
|
|||
namespace mozilla {
|
||||
namespace jsipc {
|
||||
|
||||
intr protocol PJavaScript
|
||||
prio(normal upto high) sync protocol PJavaScript
|
||||
{
|
||||
manager PContent or PContentBridge;
|
||||
|
||||
|
@ -24,30 +24,30 @@ both:
|
|||
async DropObject(uint64_t objId);
|
||||
|
||||
// These roughly map to the ProxyHandler hooks that CPOWs need.
|
||||
rpc PreventExtensions(uint64_t objId) returns (ReturnStatus rs);
|
||||
rpc GetPropertyDescriptor(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, PPropertyDescriptor result);
|
||||
rpc GetOwnPropertyDescriptor(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, PPropertyDescriptor result);
|
||||
rpc DefineProperty(uint64_t objId, JSIDVariant id, PPropertyDescriptor descriptor) returns (ReturnStatus rs);
|
||||
rpc Delete(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, bool successful);
|
||||
prio(high) sync PreventExtensions(uint64_t objId) returns (ReturnStatus rs);
|
||||
prio(high) sync GetPropertyDescriptor(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, PPropertyDescriptor result);
|
||||
prio(high) sync GetOwnPropertyDescriptor(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, PPropertyDescriptor result);
|
||||
prio(high) sync DefineProperty(uint64_t objId, JSIDVariant id, PPropertyDescriptor descriptor) returns (ReturnStatus rs);
|
||||
prio(high) sync Delete(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, bool successful);
|
||||
|
||||
rpc Has(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, bool has);
|
||||
rpc HasOwn(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, bool has);
|
||||
rpc Get(uint64_t objId, ObjectVariant receiver, JSIDVariant id) returns (ReturnStatus rs, JSVariant result);
|
||||
rpc Set(uint64_t objId, ObjectVariant receiver, JSIDVariant id, bool strict, JSVariant value) returns (ReturnStatus rs, JSVariant result);
|
||||
prio(high) sync Has(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, bool has);
|
||||
prio(high) sync HasOwn(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, bool has);
|
||||
prio(high) sync Get(uint64_t objId, ObjectVariant receiver, JSIDVariant id) returns (ReturnStatus rs, JSVariant result);
|
||||
prio(high) sync Set(uint64_t objId, ObjectVariant receiver, JSIDVariant id, bool strict, JSVariant value) returns (ReturnStatus rs, JSVariant result);
|
||||
|
||||
rpc IsExtensible(uint64_t objId) returns (ReturnStatus rs, bool result);
|
||||
rpc CallOrConstruct(uint64_t objId, JSParam[] argv, bool construct) returns (ReturnStatus rs, JSVariant result, JSParam[] outparams);
|
||||
rpc HasInstance(uint64_t objId, JSVariant v) returns (ReturnStatus rs, bool has);
|
||||
rpc ObjectClassIs(uint64_t objId, uint32_t classValue) returns (bool result);
|
||||
rpc ClassName(uint64_t objId) returns (nsString name);
|
||||
rpc RegExpToShared(uint64_t objId) returns (ReturnStatus rs, nsString source, uint32_t flags);
|
||||
prio(high) sync IsExtensible(uint64_t objId) returns (ReturnStatus rs, bool result);
|
||||
prio(high) sync CallOrConstruct(uint64_t objId, JSParam[] argv, bool construct) returns (ReturnStatus rs, JSVariant result, JSParam[] outparams);
|
||||
prio(high) sync HasInstance(uint64_t objId, JSVariant v) returns (ReturnStatus rs, bool has);
|
||||
prio(high) sync ObjectClassIs(uint64_t objId, uint32_t classValue) returns (bool result);
|
||||
prio(high) sync ClassName(uint64_t objId) returns (nsString name);
|
||||
prio(high) sync RegExpToShared(uint64_t objId) returns (ReturnStatus rs, nsString source, uint32_t flags);
|
||||
|
||||
rpc GetPropertyNames(uint64_t objId, uint32_t flags) returns (ReturnStatus rs, nsString[] names);
|
||||
rpc InstanceOf(uint64_t objId, JSIID iid) returns (ReturnStatus rs, bool instanceof);
|
||||
rpc DOMInstanceOf(uint64_t objId, int prototypeID, int depth) returns (ReturnStatus rs, bool instanceof);
|
||||
prio(high) sync GetPropertyNames(uint64_t objId, uint32_t flags) returns (ReturnStatus rs, nsString[] names);
|
||||
prio(high) sync InstanceOf(uint64_t objId, JSIID iid) returns (ReturnStatus rs, bool instanceof);
|
||||
prio(high) sync DOMInstanceOf(uint64_t objId, int prototypeID, int depth) returns (ReturnStatus rs, bool instanceof);
|
||||
|
||||
rpc IsCallable(uint64_t objId) returns (bool result);
|
||||
rpc IsConstructor(uint64_t objId) returns (bool result);
|
||||
prio(high) sync IsCallable(uint64_t objId) returns (bool result);
|
||||
prio(high) sync IsConstructor(uint64_t objId) returns (bool result);
|
||||
|
||||
parent:
|
||||
async __delete__();
|
||||
|
|
|
@ -58,7 +58,7 @@ WrapperAnswer::ok(ReturnStatus *rs)
|
|||
}
|
||||
|
||||
bool
|
||||
WrapperAnswer::AnswerPreventExtensions(const ObjectId &objId, ReturnStatus *rs)
|
||||
WrapperAnswer::RecvPreventExtensions(const ObjectId &objId, ReturnStatus *rs)
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
JSAutoRequest request(cx);
|
||||
|
@ -87,8 +87,8 @@ EmptyDesc(PPropertyDescriptor *desc)
|
|||
}
|
||||
|
||||
bool
|
||||
WrapperAnswer::AnswerGetPropertyDescriptor(const ObjectId &objId, const JSIDVariant &idVar,
|
||||
ReturnStatus *rs, PPropertyDescriptor *out)
|
||||
WrapperAnswer::RecvGetPropertyDescriptor(const ObjectId &objId, const JSIDVariant &idVar,
|
||||
ReturnStatus *rs, PPropertyDescriptor *out)
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
JSAutoRequest request(cx);
|
||||
|
@ -121,8 +121,8 @@ WrapperAnswer::AnswerGetPropertyDescriptor(const ObjectId &objId, const JSIDVari
|
|||
}
|
||||
|
||||
bool
|
||||
WrapperAnswer::AnswerGetOwnPropertyDescriptor(const ObjectId &objId, const JSIDVariant &idVar,
|
||||
ReturnStatus *rs, PPropertyDescriptor *out)
|
||||
WrapperAnswer::RecvGetOwnPropertyDescriptor(const ObjectId &objId, const JSIDVariant &idVar,
|
||||
ReturnStatus *rs, PPropertyDescriptor *out)
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
JSAutoRequest request(cx);
|
||||
|
@ -155,8 +155,8 @@ WrapperAnswer::AnswerGetOwnPropertyDescriptor(const ObjectId &objId, const JSIDV
|
|||
}
|
||||
|
||||
bool
|
||||
WrapperAnswer::AnswerDefineProperty(const ObjectId &objId, const JSIDVariant &idVar,
|
||||
const PPropertyDescriptor &descriptor, ReturnStatus *rs)
|
||||
WrapperAnswer::RecvDefineProperty(const ObjectId &objId, const JSIDVariant &idVar,
|
||||
const PPropertyDescriptor &descriptor, ReturnStatus *rs)
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
JSAutoRequest request(cx);
|
||||
|
@ -193,8 +193,8 @@ WrapperAnswer::AnswerDefineProperty(const ObjectId &objId, const JSIDVariant &id
|
|||
}
|
||||
|
||||
bool
|
||||
WrapperAnswer::AnswerDelete(const ObjectId &objId, const JSIDVariant &idVar, ReturnStatus *rs,
|
||||
bool *success)
|
||||
WrapperAnswer::RecvDelete(const ObjectId &objId, const JSIDVariant &idVar, ReturnStatus *rs,
|
||||
bool *success)
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
JSAutoRequest request(cx);
|
||||
|
@ -220,7 +220,7 @@ WrapperAnswer::AnswerDelete(const ObjectId &objId, const JSIDVariant &idVar, Ret
|
|||
}
|
||||
|
||||
bool
|
||||
WrapperAnswer::AnswerHas(const ObjectId &objId, const JSIDVariant &idVar, ReturnStatus *rs, bool *bp)
|
||||
WrapperAnswer::RecvHas(const ObjectId &objId, const JSIDVariant &idVar, ReturnStatus *rs, bool *bp)
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
JSAutoRequest request(cx);
|
||||
|
@ -248,8 +248,8 @@ WrapperAnswer::AnswerHas(const ObjectId &objId, const JSIDVariant &idVar, Return
|
|||
}
|
||||
|
||||
bool
|
||||
WrapperAnswer::AnswerHasOwn(const ObjectId &objId, const JSIDVariant &idVar, ReturnStatus *rs,
|
||||
bool *bp)
|
||||
WrapperAnswer::RecvHasOwn(const ObjectId &objId, const JSIDVariant &idVar, ReturnStatus *rs,
|
||||
bool *bp)
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
JSAutoRequest request(cx);
|
||||
|
@ -277,8 +277,8 @@ WrapperAnswer::AnswerHasOwn(const ObjectId &objId, const JSIDVariant &idVar, Ret
|
|||
}
|
||||
|
||||
bool
|
||||
WrapperAnswer::AnswerGet(const ObjectId &objId, const ObjectVariant &receiverVar,
|
||||
const JSIDVariant &idVar, ReturnStatus *rs, JSVariant *result)
|
||||
WrapperAnswer::RecvGet(const ObjectId &objId, const ObjectVariant &receiverVar,
|
||||
const JSIDVariant &idVar, ReturnStatus *rs, JSVariant *result)
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
JSAutoRequest request(cx);
|
||||
|
@ -314,9 +314,9 @@ WrapperAnswer::AnswerGet(const ObjectId &objId, const ObjectVariant &receiverVar
|
|||
}
|
||||
|
||||
bool
|
||||
WrapperAnswer::AnswerSet(const ObjectId &objId, const ObjectVariant &receiverVar,
|
||||
const JSIDVariant &idVar, const bool &strict, const JSVariant &value,
|
||||
ReturnStatus *rs, JSVariant *result)
|
||||
WrapperAnswer::RecvSet(const ObjectId &objId, const ObjectVariant &receiverVar,
|
||||
const JSIDVariant &idVar, const bool &strict, const JSVariant &value,
|
||||
ReturnStatus *rs, JSVariant *result)
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
JSAutoRequest request(cx);
|
||||
|
@ -357,7 +357,7 @@ WrapperAnswer::AnswerSet(const ObjectId &objId, const ObjectVariant &receiverVar
|
|||
}
|
||||
|
||||
bool
|
||||
WrapperAnswer::AnswerIsExtensible(const ObjectId &objId, ReturnStatus *rs, bool *result)
|
||||
WrapperAnswer::RecvIsExtensible(const ObjectId &objId, ReturnStatus *rs, bool *result)
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
JSAutoRequest request(cx);
|
||||
|
@ -381,12 +381,12 @@ WrapperAnswer::AnswerIsExtensible(const ObjectId &objId, ReturnStatus *rs, bool
|
|||
}
|
||||
|
||||
bool
|
||||
WrapperAnswer::AnswerCallOrConstruct(const ObjectId &objId,
|
||||
const nsTArray<JSParam> &argv,
|
||||
const bool &construct,
|
||||
ReturnStatus *rs,
|
||||
JSVariant *result,
|
||||
nsTArray<JSParam> *outparams)
|
||||
WrapperAnswer::RecvCallOrConstruct(const ObjectId &objId,
|
||||
const nsTArray<JSParam> &argv,
|
||||
const bool &construct,
|
||||
ReturnStatus *rs,
|
||||
JSVariant *result,
|
||||
nsTArray<JSParam> *outparams)
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
JSAutoRequest request(cx);
|
||||
|
@ -488,7 +488,7 @@ WrapperAnswer::AnswerCallOrConstruct(const ObjectId &objId,
|
|||
}
|
||||
|
||||
bool
|
||||
WrapperAnswer::AnswerHasInstance(const ObjectId &objId, const JSVariant &vVar, ReturnStatus *rs, bool *bp)
|
||||
WrapperAnswer::RecvHasInstance(const ObjectId &objId, const JSVariant &vVar, ReturnStatus *rs, bool *bp)
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
JSAutoRequest request(cx);
|
||||
|
@ -512,8 +512,8 @@ WrapperAnswer::AnswerHasInstance(const ObjectId &objId, const JSVariant &vVar, R
|
|||
}
|
||||
|
||||
bool
|
||||
WrapperAnswer::AnswerObjectClassIs(const ObjectId &objId, const uint32_t &classValue,
|
||||
bool *result)
|
||||
WrapperAnswer::RecvObjectClassIs(const ObjectId &objId, const uint32_t &classValue,
|
||||
bool *result)
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
JSAutoRequest request(cx);
|
||||
|
@ -534,7 +534,7 @@ WrapperAnswer::AnswerObjectClassIs(const ObjectId &objId, const uint32_t &classV
|
|||
}
|
||||
|
||||
bool
|
||||
WrapperAnswer::AnswerClassName(const ObjectId &objId, nsString *name)
|
||||
WrapperAnswer::RecvClassName(const ObjectId &objId, nsString *name)
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
JSAutoRequest request(cx);
|
||||
|
@ -554,8 +554,8 @@ WrapperAnswer::AnswerClassName(const ObjectId &objId, nsString *name)
|
|||
}
|
||||
|
||||
bool
|
||||
WrapperAnswer::AnswerRegExpToShared(const ObjectId &objId, ReturnStatus *rs,
|
||||
nsString *source, uint32_t *flags)
|
||||
WrapperAnswer::RecvRegExpToShared(const ObjectId &objId, ReturnStatus *rs,
|
||||
nsString *source, uint32_t *flags)
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
RootedObject obj(cx, findObjectById(cx, objId));
|
||||
|
@ -579,8 +579,8 @@ WrapperAnswer::AnswerRegExpToShared(const ObjectId &objId, ReturnStatus *rs,
|
|||
}
|
||||
|
||||
bool
|
||||
WrapperAnswer::AnswerGetPropertyNames(const ObjectId &objId, const uint32_t &flags,
|
||||
ReturnStatus *rs, nsTArray<nsString> *names)
|
||||
WrapperAnswer::RecvGetPropertyNames(const ObjectId &objId, const uint32_t &flags,
|
||||
ReturnStatus *rs, nsTArray<nsString> *names)
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
JSAutoRequest request(cx);
|
||||
|
@ -609,8 +609,8 @@ WrapperAnswer::AnswerGetPropertyNames(const ObjectId &objId, const uint32_t &fla
|
|||
}
|
||||
|
||||
bool
|
||||
WrapperAnswer::AnswerInstanceOf(const ObjectId &objId, const JSIID &iid, ReturnStatus *rs,
|
||||
bool *instanceof)
|
||||
WrapperAnswer::RecvInstanceOf(const ObjectId &objId, const JSIID &iid, ReturnStatus *rs,
|
||||
bool *instanceof)
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
JSAutoRequest request(cx);
|
||||
|
@ -636,8 +636,8 @@ WrapperAnswer::AnswerInstanceOf(const ObjectId &objId, const JSIID &iid, ReturnS
|
|||
}
|
||||
|
||||
bool
|
||||
WrapperAnswer::AnswerDOMInstanceOf(const ObjectId &objId, const int &prototypeID,
|
||||
const int &depth, ReturnStatus *rs, bool *instanceof)
|
||||
WrapperAnswer::RecvDOMInstanceOf(const ObjectId &objId, const int &prototypeID,
|
||||
const int &depth, ReturnStatus *rs, bool *instanceof)
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
JSAutoRequest request(cx);
|
||||
|
@ -661,7 +661,7 @@ WrapperAnswer::AnswerDOMInstanceOf(const ObjectId &objId, const int &prototypeID
|
|||
}
|
||||
|
||||
bool
|
||||
WrapperAnswer::AnswerIsCallable(const ObjectId &objId, bool *result)
|
||||
WrapperAnswer::RecvIsCallable(const ObjectId &objId, bool *result)
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
JSAutoRequest request(cx);
|
||||
|
@ -681,7 +681,7 @@ WrapperAnswer::AnswerIsCallable(const ObjectId &objId, bool *result)
|
|||
}
|
||||
|
||||
bool
|
||||
WrapperAnswer::AnswerIsConstructor(const ObjectId &objId, bool *result)
|
||||
WrapperAnswer::RecvIsConstructor(const ObjectId &objId, bool *result)
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
JSAutoRequest request(cx);
|
||||
|
|
|
@ -18,51 +18,51 @@ class WrapperAnswer : public virtual JavaScriptShared
|
|||
public:
|
||||
explicit WrapperAnswer(JSRuntime *rt) : JavaScriptShared(rt) {}
|
||||
|
||||
bool AnswerPreventExtensions(const ObjectId &objId, ReturnStatus *rs);
|
||||
bool AnswerGetPropertyDescriptor(const ObjectId &objId, const JSIDVariant &id,
|
||||
ReturnStatus *rs,
|
||||
PPropertyDescriptor *out);
|
||||
bool AnswerGetOwnPropertyDescriptor(const ObjectId &objId,
|
||||
const JSIDVariant &id,
|
||||
ReturnStatus *rs,
|
||||
PPropertyDescriptor *out);
|
||||
bool AnswerDefineProperty(const ObjectId &objId, const JSIDVariant &id,
|
||||
const PPropertyDescriptor &flags,
|
||||
ReturnStatus *rs);
|
||||
bool AnswerDelete(const ObjectId &objId, const JSIDVariant &id,
|
||||
ReturnStatus *rs, bool *success);
|
||||
bool RecvPreventExtensions(const ObjectId &objId, ReturnStatus *rs);
|
||||
bool RecvGetPropertyDescriptor(const ObjectId &objId, const JSIDVariant &id,
|
||||
ReturnStatus *rs,
|
||||
PPropertyDescriptor *out);
|
||||
bool RecvGetOwnPropertyDescriptor(const ObjectId &objId,
|
||||
const JSIDVariant &id,
|
||||
ReturnStatus *rs,
|
||||
PPropertyDescriptor *out);
|
||||
bool RecvDefineProperty(const ObjectId &objId, const JSIDVariant &id,
|
||||
const PPropertyDescriptor &flags,
|
||||
ReturnStatus *rs);
|
||||
bool RecvDelete(const ObjectId &objId, const JSIDVariant &id,
|
||||
ReturnStatus *rs, bool *success);
|
||||
|
||||
bool AnswerHas(const ObjectId &objId, const JSIDVariant &id,
|
||||
ReturnStatus *rs, bool *bp);
|
||||
bool AnswerHasOwn(const ObjectId &objId, const JSIDVariant &id,
|
||||
ReturnStatus *rs, bool *bp);
|
||||
bool AnswerGet(const ObjectId &objId, const ObjectVariant &receiverVar,
|
||||
const JSIDVariant &id,
|
||||
ReturnStatus *rs, JSVariant *result);
|
||||
bool AnswerSet(const ObjectId &objId, const ObjectVariant &receiverVar,
|
||||
const JSIDVariant &id, const bool &strict,
|
||||
const JSVariant &value, ReturnStatus *rs, JSVariant *result);
|
||||
bool RecvHas(const ObjectId &objId, const JSIDVariant &id,
|
||||
ReturnStatus *rs, bool *bp);
|
||||
bool RecvHasOwn(const ObjectId &objId, const JSIDVariant &id,
|
||||
ReturnStatus *rs, bool *bp);
|
||||
bool RecvGet(const ObjectId &objId, const ObjectVariant &receiverVar,
|
||||
const JSIDVariant &id,
|
||||
ReturnStatus *rs, JSVariant *result);
|
||||
bool RecvSet(const ObjectId &objId, const ObjectVariant &receiverVar,
|
||||
const JSIDVariant &id, const bool &strict,
|
||||
const JSVariant &value, ReturnStatus *rs, JSVariant *result);
|
||||
|
||||
bool AnswerIsExtensible(const ObjectId &objId, ReturnStatus *rs,
|
||||
bool *result);
|
||||
bool AnswerCallOrConstruct(const ObjectId &objId, const nsTArray<JSParam> &argv,
|
||||
const bool &construct, ReturnStatus *rs, JSVariant *result,
|
||||
nsTArray<JSParam> *outparams);
|
||||
bool AnswerHasInstance(const ObjectId &objId, const JSVariant &v, ReturnStatus *rs, bool *bp);
|
||||
bool AnswerObjectClassIs(const ObjectId &objId, const uint32_t &classValue,
|
||||
bool *result);
|
||||
bool AnswerClassName(const ObjectId &objId, nsString *result);
|
||||
bool AnswerRegExpToShared(const ObjectId &objId, ReturnStatus *rs, nsString *source, uint32_t *flags);
|
||||
bool RecvIsExtensible(const ObjectId &objId, ReturnStatus *rs,
|
||||
bool *result);
|
||||
bool RecvCallOrConstruct(const ObjectId &objId, const nsTArray<JSParam> &argv,
|
||||
const bool &construct, ReturnStatus *rs, JSVariant *result,
|
||||
nsTArray<JSParam> *outparams);
|
||||
bool RecvHasInstance(const ObjectId &objId, const JSVariant &v, ReturnStatus *rs, bool *bp);
|
||||
bool RecvObjectClassIs(const ObjectId &objId, const uint32_t &classValue,
|
||||
bool *result);
|
||||
bool RecvClassName(const ObjectId &objId, nsString *result);
|
||||
bool RecvRegExpToShared(const ObjectId &objId, ReturnStatus *rs, nsString *source, uint32_t *flags);
|
||||
|
||||
bool AnswerGetPropertyNames(const ObjectId &objId, const uint32_t &flags,
|
||||
ReturnStatus *rs, nsTArray<nsString> *names);
|
||||
bool AnswerInstanceOf(const ObjectId &objId, const JSIID &iid,
|
||||
ReturnStatus *rs, bool *instanceof);
|
||||
bool AnswerDOMInstanceOf(const ObjectId &objId, const int &prototypeID, const int &depth,
|
||||
ReturnStatus *rs, bool *instanceof);
|
||||
bool RecvGetPropertyNames(const ObjectId &objId, const uint32_t &flags,
|
||||
ReturnStatus *rs, nsTArray<nsString> *names);
|
||||
bool RecvInstanceOf(const ObjectId &objId, const JSIID &iid,
|
||||
ReturnStatus *rs, bool *instanceof);
|
||||
bool RecvDOMInstanceOf(const ObjectId &objId, const int &prototypeID, const int &depth,
|
||||
ReturnStatus *rs, bool *instanceof);
|
||||
|
||||
bool AnswerIsCallable(const ObjectId &objId, bool *result);
|
||||
bool AnswerIsConstructor(const ObjectId &objId, bool *result);
|
||||
bool RecvIsCallable(const ObjectId &objId, bool *result);
|
||||
bool RecvIsConstructor(const ObjectId &objId, bool *result);
|
||||
|
||||
bool RecvDropObject(const ObjectId &objId);
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@ WrapperOwner::preventExtensions(JSContext *cx, HandleObject proxy)
|
|||
ObjectId objId = idOf(proxy);
|
||||
|
||||
ReturnStatus status;
|
||||
if (!CallPreventExtensions(objId, &status))
|
||||
if (!SendPreventExtensions(objId, &status))
|
||||
return ipcfail(cx);
|
||||
|
||||
LOG_STACK();
|
||||
|
@ -151,7 +151,7 @@ WrapperOwner::getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId
|
|||
|
||||
ReturnStatus status;
|
||||
PPropertyDescriptor result;
|
||||
if (!CallGetPropertyDescriptor(objId, idVar, &status, &result))
|
||||
if (!SendGetPropertyDescriptor(objId, idVar, &status, &result))
|
||||
return ipcfail(cx);
|
||||
|
||||
LOG_STACK();
|
||||
|
@ -181,7 +181,7 @@ WrapperOwner::getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, Handle
|
|||
|
||||
ReturnStatus status;
|
||||
PPropertyDescriptor result;
|
||||
if (!CallGetOwnPropertyDescriptor(objId, idVar, &status, &result))
|
||||
if (!SendGetOwnPropertyDescriptor(objId, idVar, &status, &result))
|
||||
return ipcfail(cx);
|
||||
|
||||
LOG_STACK();
|
||||
|
@ -214,7 +214,7 @@ WrapperOwner::defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
|||
return false;
|
||||
|
||||
ReturnStatus status;
|
||||
if (!CallDefineProperty(objId, idVar, descriptor, &status))
|
||||
if (!SendDefineProperty(objId, idVar, descriptor, &status))
|
||||
return ipcfail(cx);
|
||||
|
||||
LOG_STACK();
|
||||
|
@ -251,7 +251,7 @@ WrapperOwner::delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp)
|
|||
return false;
|
||||
|
||||
ReturnStatus status;
|
||||
if (!CallDelete(objId, idVar, &status, bp))
|
||||
if (!SendDelete(objId, idVar, &status, bp))
|
||||
return ipcfail(cx);
|
||||
|
||||
LOG_STACK();
|
||||
|
@ -287,7 +287,7 @@ WrapperOwner::has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp)
|
|||
return false;
|
||||
|
||||
ReturnStatus status;
|
||||
if (!CallHas(objId, idVar, &status, bp))
|
||||
if (!SendHas(objId, idVar, &status, bp))
|
||||
return ipcfail(cx);
|
||||
|
||||
LOG_STACK();
|
||||
|
@ -311,7 +311,7 @@ WrapperOwner::hasOwn(JSContext *cx, HandleObject proxy, HandleId id, bool *bp)
|
|||
return false;
|
||||
|
||||
ReturnStatus status;
|
||||
if (!CallHasOwn(objId, idVar, &status, bp))
|
||||
if (!SendHasOwn(objId, idVar, &status, bp))
|
||||
return ipcfail(cx);
|
||||
|
||||
LOG_STACK();
|
||||
|
@ -396,7 +396,7 @@ WrapperOwner::get(JSContext *cx, HandleObject proxy, HandleObject receiver,
|
|||
|
||||
JSVariant val;
|
||||
ReturnStatus status;
|
||||
if (!CallGet(objId, receiverVar, idVar, &status, &val))
|
||||
if (!SendGet(objId, receiverVar, idVar, &status, &val))
|
||||
return ipcfail(cx);
|
||||
|
||||
LOG_STACK();
|
||||
|
@ -451,7 +451,7 @@ WrapperOwner::set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiv
|
|||
|
||||
ReturnStatus status;
|
||||
JSVariant result;
|
||||
if (!CallSet(objId, receiverVar, idVar, strict, val, &status, &result))
|
||||
if (!SendSet(objId, receiverVar, idVar, strict, val, &status, &result))
|
||||
return ipcfail(cx);
|
||||
|
||||
LOG_STACK();
|
||||
|
@ -486,7 +486,7 @@ WrapperOwner::isExtensible(JSContext *cx, HandleObject proxy, bool *extensible)
|
|||
ObjectId objId = idOf(proxy);
|
||||
|
||||
ReturnStatus status;
|
||||
if (!CallIsExtensible(objId, &status, extensible))
|
||||
if (!SendIsExtensible(objId, &status, extensible))
|
||||
return ipcfail(cx);
|
||||
|
||||
LOG_STACK();
|
||||
|
@ -550,7 +550,7 @@ WrapperOwner::callOrConstruct(JSContext *cx, HandleObject proxy, const CallArgs
|
|||
JSVariant result;
|
||||
ReturnStatus status;
|
||||
InfallibleTArray<JSParam> outparams;
|
||||
if (!CallCallOrConstruct(objId, vals, construct, &status, &result, &outparams))
|
||||
if (!SendCallOrConstruct(objId, vals, construct, &status, &result, &outparams))
|
||||
return ipcfail(cx);
|
||||
|
||||
LOG_STACK();
|
||||
|
@ -600,7 +600,7 @@ WrapperOwner::hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue
|
|||
|
||||
ReturnStatus status;
|
||||
JSVariant result;
|
||||
if (!CallHasInstance(objId, vVar, &status, bp))
|
||||
if (!SendHasInstance(objId, vVar, &status, bp))
|
||||
return ipcfail(cx);
|
||||
|
||||
LOG_STACK();
|
||||
|
@ -622,7 +622,7 @@ WrapperOwner::objectClassIs(JSContext *cx, HandleObject proxy, js::ESClassValue
|
|||
// This function is assumed infallible, so we just return false if the IPC
|
||||
// channel fails.
|
||||
bool result;
|
||||
if (!CallObjectClassIs(objId, classValue, &result))
|
||||
if (!SendObjectClassIs(objId, classValue, &result))
|
||||
return false;
|
||||
|
||||
LOG_STACK();
|
||||
|
@ -645,7 +645,7 @@ WrapperOwner::className(JSContext *cx, HandleObject proxy)
|
|||
ObjectId objId = idOf(proxy);
|
||||
|
||||
nsString name;
|
||||
if (!CallClassName(objId, &name))
|
||||
if (!SendClassName(objId, &name))
|
||||
return "<error>";
|
||||
|
||||
LOG_STACK();
|
||||
|
@ -667,7 +667,7 @@ WrapperOwner::regexp_toShared(JSContext *cx, HandleObject proxy, RegExpGuard *g)
|
|||
ReturnStatus status;
|
||||
nsString source;
|
||||
unsigned flags = 0;
|
||||
if (!CallRegExpToShared(objId, &status, &source, &flags))
|
||||
if (!SendRegExpToShared(objId, &status, &source, &flags))
|
||||
return ipcfail(cx);
|
||||
|
||||
LOG_STACK();
|
||||
|
@ -711,7 +711,7 @@ WrapperOwner::isCallable(JSObject *obj)
|
|||
ObjectId objId = idOf(obj);
|
||||
|
||||
bool callable = false;
|
||||
if (!CallIsCallable(objId, &callable)) {
|
||||
if (!SendIsCallable(objId, &callable)) {
|
||||
NS_WARNING("IPC isCallable() failed");
|
||||
return false;
|
||||
}
|
||||
|
@ -734,7 +734,7 @@ WrapperOwner::isConstructor(JSObject *obj)
|
|||
ObjectId objId = idOf(obj);
|
||||
|
||||
bool constructor = false;
|
||||
if (!CallIsConstructor(objId, &constructor)) {
|
||||
if (!SendIsConstructor(objId, &constructor)) {
|
||||
NS_WARNING("IPC isConstructor() failed");
|
||||
return false;
|
||||
}
|
||||
|
@ -777,7 +777,7 @@ WrapperOwner::getPropertyNames(JSContext *cx, HandleObject proxy, uint32_t flags
|
|||
|
||||
ReturnStatus status;
|
||||
InfallibleTArray<nsString> names;
|
||||
if (!CallGetPropertyNames(objId, flags, &status, &names))
|
||||
if (!SendGetPropertyNames(objId, flags, &status, &names))
|
||||
return ipcfail(cx);
|
||||
|
||||
LOG_STACK();
|
||||
|
@ -841,7 +841,7 @@ WrapperOwner::instanceOf(JSObject *obj, const nsID *id, bool *bp)
|
|||
ConvertID(*id, &iid);
|
||||
|
||||
ReturnStatus status;
|
||||
if (!CallInstanceOf(objId, iid, &status, bp))
|
||||
if (!SendInstanceOf(objId, iid, &status, bp))
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
if (status.type() != ReturnStatus::TReturnSuccess)
|
||||
|
@ -856,7 +856,7 @@ WrapperOwner::domInstanceOf(JSContext *cx, JSObject *obj, int prototypeID, int d
|
|||
ObjectId objId = idOf(obj);
|
||||
|
||||
ReturnStatus status;
|
||||
if (!CallDOMInstanceOf(objId, prototypeID, depth, &status, bp))
|
||||
if (!SendDOMInstanceOf(objId, prototypeID, depth, &status, bp))
|
||||
return ipcfail(cx);
|
||||
|
||||
LOG_STACK();
|
||||
|
|
|
@ -107,53 +107,53 @@ class WrapperOwner : public virtual JavaScriptShared
|
|||
/*** Dummy call handlers ***/
|
||||
public:
|
||||
virtual bool SendDropObject(const ObjectId &objId) = 0;
|
||||
virtual bool CallPreventExtensions(const ObjectId &objId, ReturnStatus *rs) = 0;
|
||||
virtual bool CallGetPropertyDescriptor(const ObjectId &objId, const JSIDVariant &id,
|
||||
virtual bool SendPreventExtensions(const ObjectId &objId, ReturnStatus *rs) = 0;
|
||||
virtual bool SendGetPropertyDescriptor(const ObjectId &objId, const JSIDVariant &id,
|
||||
ReturnStatus *rs,
|
||||
PPropertyDescriptor *out) = 0;
|
||||
virtual bool CallGetOwnPropertyDescriptor(const ObjectId &objId,
|
||||
virtual bool SendGetOwnPropertyDescriptor(const ObjectId &objId,
|
||||
const JSIDVariant &id,
|
||||
ReturnStatus *rs,
|
||||
PPropertyDescriptor *out) = 0;
|
||||
virtual bool CallDefineProperty(const ObjectId &objId, const JSIDVariant &id,
|
||||
virtual bool SendDefineProperty(const ObjectId &objId, const JSIDVariant &id,
|
||||
const PPropertyDescriptor &flags,
|
||||
ReturnStatus *rs) = 0;
|
||||
virtual bool CallDelete(const ObjectId &objId, const JSIDVariant &id,
|
||||
virtual bool SendDelete(const ObjectId &objId, const JSIDVariant &id,
|
||||
ReturnStatus *rs, bool *success) = 0;
|
||||
|
||||
virtual bool CallHas(const ObjectId &objId, const JSIDVariant &id,
|
||||
virtual bool SendHas(const ObjectId &objId, const JSIDVariant &id,
|
||||
ReturnStatus *rs, bool *bp) = 0;
|
||||
virtual bool CallHasOwn(const ObjectId &objId, const JSIDVariant &id,
|
||||
virtual bool SendHasOwn(const ObjectId &objId, const JSIDVariant &id,
|
||||
ReturnStatus *rs, bool *bp) = 0;
|
||||
virtual bool CallGet(const ObjectId &objId, const ObjectVariant &receiverVar,
|
||||
virtual bool SendGet(const ObjectId &objId, const ObjectVariant &receiverVar,
|
||||
const JSIDVariant &id,
|
||||
ReturnStatus *rs, JSVariant *result) = 0;
|
||||
virtual bool CallSet(const ObjectId &objId, const ObjectVariant &receiverVar,
|
||||
virtual bool SendSet(const ObjectId &objId, const ObjectVariant &receiverVar,
|
||||
const JSIDVariant &id, const bool &strict,
|
||||
const JSVariant &value, ReturnStatus *rs, JSVariant *result) = 0;
|
||||
|
||||
virtual bool CallIsExtensible(const ObjectId &objId, ReturnStatus *rs,
|
||||
virtual bool SendIsExtensible(const ObjectId &objId, ReturnStatus *rs,
|
||||
bool *result) = 0;
|
||||
virtual bool CallCallOrConstruct(const ObjectId &objId, const nsTArray<JSParam> &argv,
|
||||
virtual bool SendCallOrConstruct(const ObjectId &objId, const nsTArray<JSParam> &argv,
|
||||
const bool &construct, ReturnStatus *rs, JSVariant *result,
|
||||
nsTArray<JSParam> *outparams) = 0;
|
||||
virtual bool CallHasInstance(const ObjectId &objId, const JSVariant &v,
|
||||
virtual bool SendHasInstance(const ObjectId &objId, const JSVariant &v,
|
||||
ReturnStatus *rs, bool *bp) = 0;
|
||||
virtual bool CallObjectClassIs(const ObjectId &objId, const uint32_t &classValue,
|
||||
virtual bool SendObjectClassIs(const ObjectId &objId, const uint32_t &classValue,
|
||||
bool *result) = 0;
|
||||
virtual bool CallClassName(const ObjectId &objId, nsString *result) = 0;
|
||||
virtual bool CallRegExpToShared(const ObjectId &objId, ReturnStatus *rs, nsString *source,
|
||||
virtual bool SendClassName(const ObjectId &objId, nsString *result) = 0;
|
||||
virtual bool SendRegExpToShared(const ObjectId &objId, ReturnStatus *rs, nsString *source,
|
||||
uint32_t *flags) = 0;
|
||||
|
||||
virtual bool CallGetPropertyNames(const ObjectId &objId, const uint32_t &flags,
|
||||
virtual bool SendGetPropertyNames(const ObjectId &objId, const uint32_t &flags,
|
||||
ReturnStatus *rs, nsTArray<nsString> *names) = 0;
|
||||
virtual bool CallInstanceOf(const ObjectId &objId, const JSIID &iid,
|
||||
virtual bool SendInstanceOf(const ObjectId &objId, const JSIID &iid,
|
||||
ReturnStatus *rs, bool *instanceof) = 0;
|
||||
virtual bool CallDOMInstanceOf(const ObjectId &objId, const int &prototypeID, const int &depth,
|
||||
virtual bool SendDOMInstanceOf(const ObjectId &objId, const int &prototypeID, const int &depth,
|
||||
ReturnStatus *rs, bool *instanceof) = 0;
|
||||
|
||||
virtual bool CallIsCallable(const ObjectId &objId, bool *result) = 0;
|
||||
virtual bool CallIsConstructor(const ObjectId &objId, bool *result) = 0;
|
||||
virtual bool SendIsCallable(const ObjectId &objId, bool *result) = 0;
|
||||
virtual bool SendIsConstructor(const ObjectId &objId, bool *result) = 0;
|
||||
};
|
||||
|
||||
bool
|
||||
|
|
|
@ -4333,7 +4333,7 @@ inline static mozilla::HangMonitor::ActivityType ActivityTypeForMessage(UINT msg
|
|||
// and http://msdn.microsoft.com/en-us/library/ms633573%28VS.85%29.aspx
|
||||
LRESULT CALLBACK nsWindow::WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(!ipc::ProcessingUrgentMessages());
|
||||
MOZ_RELEASE_ASSERT(!ipc::ParentProcessIsBlocked());
|
||||
|
||||
HangMonitor::NotifyActivity(ActivityTypeForMessage(msg));
|
||||
|
||||
|
|
|
@ -147,7 +147,7 @@ ScreenProxy::EnsureCacheIsValid()
|
|||
// Kick off a synchronous IPC call to the parent to get the
|
||||
// most up-to-date information.
|
||||
ScreenDetails details;
|
||||
unused << mScreenManager->CallScreenRefresh(mId, &details, &success);
|
||||
unused << mScreenManager->SendScreenRefresh(mId, &details, &success);
|
||||
if (!success) {
|
||||
NS_WARNING("Updating a ScreenProxy in the child process failed on parent side.");
|
||||
return false;
|
||||
|
|
|
@ -28,7 +28,7 @@ nsScreenManagerProxy::nsScreenManagerProxy()
|
|||
, mCacheWillInvalidate(false)
|
||||
{
|
||||
bool success = false;
|
||||
unused << ContentChild::GetSingleton()->CallPScreenManagerConstructor(
|
||||
unused << ContentChild::GetSingleton()->SendPScreenManagerConstructor(
|
||||
this,
|
||||
&mNumberOfScreens,
|
||||
&mSystemDefaultScale,
|
||||
|
@ -64,7 +64,7 @@ nsScreenManagerProxy::GetPrimaryScreen(nsIScreen** outScreen)
|
|||
if (!mPrimaryScreen) {
|
||||
ScreenDetails details;
|
||||
bool success = false;
|
||||
unused << CallGetPrimaryScreen(&details, &success);
|
||||
unused << SendGetPrimaryScreen(&details, &success);
|
||||
if (!success) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ nsScreenManagerProxy::ScreenForRect(int32_t inLeft,
|
|||
{
|
||||
bool success = false;
|
||||
ScreenDetails details;
|
||||
unused << CallScreenForRect(inLeft, inTop, inWidth, inHeight, &details, &success);
|
||||
unused << SendScreenForRect(inLeft, inTop, inWidth, inHeight, &details, &success);
|
||||
if (!success) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ nsScreenManagerProxy::ScreenForNativeWidget(void* aWidget,
|
|||
// for it.
|
||||
bool success = false;
|
||||
ScreenDetails details;
|
||||
unused << CallScreenForBrowser(tabChild, &details, &success);
|
||||
unused << SendScreenForBrowser(tabChild, &details, &success);
|
||||
if (!success) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ nsScreenManagerProxy::EnsureCacheIsValid()
|
|||
bool success = false;
|
||||
// Kick off a synchronous IPC call to the parent to get the
|
||||
// most up-to-date information.
|
||||
unused << CallRefresh(&mNumberOfScreens, &mSystemDefaultScale, &success);
|
||||
unused << SendRefresh(&mNumberOfScreens, &mSystemDefaultScale, &success);
|
||||
if (!success) {
|
||||
NS_WARNING("Refreshing nsScreenManagerProxy failed in the parent process.");
|
||||
return false;
|
||||
|
|
|
@ -727,7 +727,7 @@ nsThread::ProcessNextEvent(bool aMayWait, bool* aResult)
|
|||
|
||||
// If we're on the main thread, we shouldn't be dispatching CPOWs.
|
||||
MOZ_RELEASE_ASSERT(mIsMainThread != MAIN_THREAD ||
|
||||
!ipc::ProcessingUrgentMessages());
|
||||
!ipc::ParentProcessIsBlocked());
|
||||
|
||||
if (NS_WARN_IF(PR_GetCurrentThread() != mThread)) {
|
||||
return NS_ERROR_NOT_SAME_THREAD;
|
||||
|
|
Загрузка…
Ссылка в новой задаче