bug 525342: make IPDL dtors part of the destructed actor's protocol instead of the manager's. r=bsmedberg

This commit is contained in:
Chris Jones 2009-12-03 02:16:14 -06:00
Родитель adf54bbb48
Коммит dfa19ba299
91 изменённых файлов: 642 добавлений и 425 удалений

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

@ -998,7 +998,7 @@ nsFrameLoader::Destroy()
#ifdef MOZ_IPC
if (mChildProcess) {
mChildProcess->SetOwnerElement(nsnull);
ContentProcessParent::GetSingleton()->SendPIFrameEmbeddingDestructor(mChildProcess);
PIFrameEmbeddingParent::Send__delete__(mChildProcess);
mChildProcess = nsnull;
}
#endif

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

@ -57,6 +57,9 @@ public:
void DrawToCanvas(PRUint32 aWidth, PRUint32 aHeight,
const nsCString& aData);
virtual bool Recv__delete__(const PRUint32& w, const PRUint32& h,
const nsCString& data);
private:
nsCOMPtr<nsICanvasRenderingContextInternal> mCanvas;
nsRefPtr<gfxContext> mCanvasContext;

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

@ -75,3 +75,11 @@ void DocumentRendererParent::DrawToCanvas(PRUint32 aWidth, PRUint32 aHeight,
gfxRect damageRect = mCanvasContext->UserToDevice(gfxRect(0, 0, aWidth, aHeight));
mCanvas->Redraw(damageRect);
}
bool
DocumentRendererParent::Recv__delete__(const PRUint32& w, const PRUint32& h,
const nsCString& data)
{
DrawToCanvas(w, h, data);
return true;
}

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

@ -98,7 +98,7 @@ ContentProcessParent::CreateTestShell()
bool
ContentProcessParent::DestroyTestShell(TestShellParent* aTestShell)
{
return SendPTestShellDestructor(aTestShell);
return PTestShellParent::Send__delete__(aTestShell);
}
ContentProcessParent::ContentProcessParent()

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

@ -53,16 +53,13 @@ sync protocol PContentProcess
child:
PIFrameEmbedding();
~PIFrameEmbedding();
PTestShell();
~PTestShell();
Quit();
parent:
PNecko();
~PNecko();
};
}

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

@ -43,6 +43,9 @@ namespace ipc {
protocol PDocumentRenderer
{
manager PIFrameEmbedding;
parent:
__delete__(PRUint32 w, PRUint32 h, nsCString data);
};
} // namespace ipc

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

@ -43,8 +43,6 @@ include protocol "PDocumentRenderer.ipdl";
include "mozilla/TabTypes.h";
include "TabMessageUtils.h";
using PRUint32;
using PRInt32;
using MagicWindowHandle;
using RemoteDOMEvent;
@ -56,6 +54,9 @@ async protocol PIFrameEmbedding
manager PContentProcess;
manages PDocumentRenderer;
child:
__delete__();
parent:
/**
* When child sends this message, parent should move focus to
@ -96,10 +97,6 @@ child:
activateFrameEvent(nsString aType, bool capture);
PDocumentRenderer(PRInt32 x, PRInt32 y, PRInt32 w, PRInt32 h, nsString bgcolor, PRUint32 flags, bool flush);
parent:
~PDocumentRenderer(PRUint32 w, PRUint32 h, nsCString data);
};
}

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

@ -361,13 +361,9 @@ TabChild::AllocPDocumentRenderer(
}
bool
TabChild::DeallocPDocumentRenderer(
mozilla::ipc::PDocumentRendererChild* __a,
const PRUint32& w,
const PRUint32& h,
const nsCString& data)
TabChild::DeallocPDocumentRenderer(PDocumentRendererChild* actor)
{
delete __a;
delete actor;
return true;
}
@ -402,7 +398,7 @@ TabChild::RecvPDocumentRendererConstructor(
if (!ret)
return true; // silently ignore
return SendPDocumentRendererDestructor(__a, width, height, data);
return PDocumentRendererChild::Send__delete__(__a, width, height, data);
}
bool

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

@ -105,11 +105,7 @@ public:
const nsString& bgcolor,
const PRUint32& flags,
const bool& flush);
virtual bool DeallocPDocumentRenderer(
mozilla::ipc::PDocumentRendererChild* __a,
const PRUint32& w,
const PRUint32& h,
const nsCString& data);
virtual bool DeallocPDocumentRenderer(PDocumentRendererChild* actor);
virtual bool RecvPDocumentRendererConstructor(
mozilla::ipc::PDocumentRendererChild *__a,
const PRInt32& x,

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

@ -123,22 +123,9 @@ TabParent::AllocPDocumentRenderer(const PRInt32& x,
}
bool
TabParent::DeallocPDocumentRenderer(mozilla::ipc::PDocumentRendererParent* __a,
const PRUint32& w, const PRUint32& h, const nsCString& data)
TabParent::DeallocPDocumentRenderer(PDocumentRendererParent* actor)
{
NS_ENSURE_ARG_POINTER(__a);
delete __a;
return true;
}
bool
TabParent::RecvPDocumentRendererDestructor(PDocumentRendererParent* __a,
const PRUint32& w, const PRUint32& h, const nsCString& data)
{
NS_ENSURE_ARG_POINTER(__a);
DocumentRendererParent *renderer = static_cast<DocumentRendererParent *>(__a);
renderer->DrawToCanvas(w, h, data);
delete actor;
return true;
}

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

@ -74,16 +74,7 @@ public:
const nsString& bgcolor,
const PRUint32& flags,
const bool& flush);
virtual bool DeallocPDocumentRenderer(
mozilla::ipc::PDocumentRendererParent* __a,
const PRUint32& w,
const PRUint32& h,
const nsCString& data);
virtual bool RecvPDocumentRendererDestructor(
mozilla::ipc::PDocumentRendererParent* __a,
const PRUint32& w,
const PRUint32& h,
const nsCString& data);
virtual bool DeallocPDocumentRenderer(PDocumentRendererParent* actor);
protected:
nsIDOMElement* mFrameElement;
};

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

@ -127,6 +127,16 @@ BrowserStreamChild::AnswerNPP_StreamAsFile(const nsCString& fname)
return true;
}
bool
BrowserStreamChild::Answer__delete__(const NPError& reason,
const bool& artificial)
{
AssertPluginThread();
if (!artificial)
NPP_DestroyStream(reason);
return true;
}
NPError
BrowserStreamChild::NPN_RequestRead(NPByteRange* aRangeList)
{

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

@ -71,6 +71,9 @@ public:
int32_t* consumed);
virtual bool AnswerNPP_StreamAsFile(const nsCString& fname);
virtual bool Answer__delete__(const NPError& reason,
const bool& artificial);
void EnsureCorrectInstance(PluginInstanceChild* i)
{

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

@ -44,6 +44,15 @@ BrowserStreamParent::AnswerNPN_RequestRead(const IPCByteRanges& ranges,
return true;
}
bool
BrowserStreamParent::Answer__delete__(const NPError& reason,
const bool& artificial)
{
if (!artificial)
NPN_DestroyStream(reason);
return true;
}
int32_t
BrowserStreamParent::WriteReady()
{

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

@ -61,12 +61,16 @@ public:
virtual bool AnswerNPN_RequestRead(const IPCByteRanges& ranges,
NPError* result);
virtual bool
Answer__delete__(const NPError& reason, const bool& artificial);
int32_t WriteReady();
int32_t Write(int32_t offset, int32_t len, void* buffer);
void StreamAsFile(const char* fname);
NPError NPN_DestroyStream(NPError reason);
private:
NPError NPN_DestroyStream(NPError reason);
PluginInstanceParent* mNPP;
NPStream* mStream;
};

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

@ -43,6 +43,7 @@ using mozilla::plugins::Buffer;
using mozilla::plugins::IPCByteRanges;
using NPError;
using NPReason;
namespace mozilla {
namespace plugins {
@ -68,6 +69,14 @@ child:
parent:
rpc NPN_RequestRead(IPCByteRanges ranges)
returns (NPError result);
both:
/**
* ~PBrowserStream is for both NPN_DestroyStream and NPP_DestroyStream.
* @param artificial True when the stream is closed as a by-product of
* some other call (such as a failure in NPP_Write).
*/
rpc __delete__(NPReason reason, bool artificial);
};
} // namespace plugins

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

@ -48,7 +48,6 @@ include "mozilla/plugins/PluginMessageUtils.h";
using NPError;
using NPRemoteWindow;
using NPRemoteEvent;
using NPReason;
using NPRect;
namespace mozilla {
@ -64,6 +63,9 @@ rpc protocol PPluginInstance
manages PStreamNotify;
child:
rpc __delete__()
returns (NPError rv);
rpc NPP_SetWindow(NPRemoteWindow window)
returns (NPError rv);
@ -119,15 +121,8 @@ parent:
rpc NPN_PopPopupsEnabledState()
returns (bool aSuccess);
child:
/**
* Represents NPP_URLNotify
*/
rpc ~PStreamNotify(NPReason reason);
both:
rpc PPluginScriptableObject();
rpc ~PPluginScriptableObject();
child:
/* NPP_NewStream */
@ -141,28 +136,11 @@ child:
returns (NPError rv,
uint16_t stype);
both:
/**
* ~PBrowserStream is for both NPN_DestroyStream and NPP_DestroyStream.
* @param artificial True when the stream is closed as a by-product of
* some other call (such as a failure in NPP_Write).
*/
rpc ~PBrowserStream(NPReason reason,
bool artificial);
parent:
/* NPN_NewStream */
rpc PPluginStream(nsCString mimeType,
nsCString target)
returns (NPError result);
both:
/**
* ~PPluginStream is for both NPN_DestroyStream and NPP_DestroyStream.
* @param artificial True when the stream is closed as a by-product of
* some other call (such as a failure in NPN_Write).
*/
rpc ~PPluginStream(NPReason reason, bool artificial);
};
} // namespace plugins

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

@ -63,9 +63,6 @@ child:
nsCString[] aValues)
returns (NPError rv);
rpc ~PPluginInstance()
returns (NPError rv);
rpc NP_Shutdown()
returns (NPError rv);

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

@ -64,6 +64,9 @@ rpc protocol PPluginScriptableObject
{
manager PPluginInstance;
both:
rpc __delete__();
parent:
rpc NPN_Evaluate(nsCString aScript)
returns (Variant aResult,

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

@ -41,6 +41,7 @@ include "mozilla/plugins/PluginMessageUtils.h";
using mozilla::plugins::Buffer;
using NPError;
using NPReason;
namespace mozilla {
namespace plugins {
@ -55,6 +56,14 @@ rpc protocol PPluginStream
parent:
rpc NPN_Write(Buffer data) returns (int32_t written);
both:
/**
* ~PPluginStream is for both NPN_DestroyStream and NPP_DestroyStream.
* @param artificial True when the stream is closed as a by-product of
* some other call (such as a failure in NPN_Write).
*/
rpc __delete__(NPReason reason, bool artificial);
};
} // namespace plugins

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

@ -2,6 +2,10 @@
include protocol "PPluginInstance.ipdl";
include "npapi.h";
using NPReason;
namespace mozilla {
namespace plugins {
@ -11,6 +15,12 @@ namespace plugins {
rpc protocol PStreamNotify
{
manager PPluginInstance;
child:
/**
* Represents NPP_URLNotify
*/
rpc __delete__(NPReason reason);
};
} // namespace plugins

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

@ -87,6 +87,14 @@ PluginInstanceChild::~PluginInstanceChild()
#endif
}
bool
PluginInstanceChild::Answer__delete__(NPError* rv)
{
return static_cast<PluginModuleChild*>(Manager())->
PluginInstanceDestroyed(this, rv);
}
NPError
PluginInstanceChild::NPN_GetValue(NPNVariable aVar,
void* aValue)
@ -721,7 +729,7 @@ PluginInstanceChild::AllocPPluginScriptableObject()
bool
PluginInstanceChild::DeallocPPluginScriptableObject(
PPluginScriptableObjectChild* aObject)
PPluginScriptableObjectChild* aObject)
{
AssertPluginThread();
@ -788,20 +796,7 @@ PluginInstanceChild::AllocPBrowserStream(const nsCString& url,
}
bool
PluginInstanceChild::AnswerPBrowserStreamDestructor(PBrowserStreamChild* stream,
const NPError& reason,
const bool& artificial)
{
AssertPluginThread();
if (!artificial)
static_cast<BrowserStreamChild*>(stream)->NPP_DestroyStream(reason);
return true;
}
bool
PluginInstanceChild::DeallocPBrowserStream(PBrowserStreamChild* stream,
const NPError& reason,
const bool& artificial)
PluginInstanceChild::DeallocPBrowserStream(PBrowserStreamChild* stream)
{
AssertPluginThread();
delete stream;
@ -818,21 +813,7 @@ PluginInstanceChild::AllocPPluginStream(const nsCString& mimeType,
}
bool
PluginInstanceChild::AnswerPPluginStreamDestructor(PPluginStreamChild* stream,
const NPReason& reason,
const bool& artificial)
{
AssertPluginThread();
if (!artificial) {
static_cast<PluginStreamChild*>(stream)->NPP_DestroyStream(reason);
}
return true;
}
bool
PluginInstanceChild::DeallocPPluginStream(PPluginStreamChild* stream,
const NPError& reason,
const bool& artificial)
PluginInstanceChild::DeallocPPluginStream(PPluginStreamChild* stream)
{
AssertPluginThread();
delete stream;
@ -853,22 +834,27 @@ PluginInstanceChild::AllocPStreamNotify(const nsCString& url,
}
bool
PluginInstanceChild::AnswerPStreamNotifyDestructor(PStreamNotifyChild* notifyData,
const NPReason& reason)
StreamNotifyChild::Answer__delete__(const NPReason& reason)
{
AssertPluginThread();
return static_cast<PluginInstanceChild*>(Manager())
->NotifyStream(this, reason);
}
StreamNotifyChild* sn = static_cast<StreamNotifyChild*>(notifyData);
if (sn->mClosure)
mPluginIface->urlnotify(&mData, sn->mURL.get(), reason, sn->mClosure);
bool
PluginInstanceChild::NotifyStream(StreamNotifyChild* notifyData,
NPReason reason)
{
if (notifyData->mClosure)
mPluginIface->urlnotify(&mData, notifyData->mURL.get(), reason,
notifyData->mClosure);
return true;
}
bool
PluginInstanceChild::DeallocPStreamNotify(PStreamNotifyChild* notifyData,
const NPReason& reason)
PluginInstanceChild::DeallocPStreamNotify(PStreamNotifyChild* notifyData)
{
AssertPluginThread();
delete notifyData;
return true;
}
@ -914,14 +900,14 @@ PluginInstanceChild::NPN_NewStream(NPMIMEType aMIMEType, const char* aWindow,
{
AssertPluginThread();
PluginStreamChild* ps = new PluginStreamChild(this);
PluginStreamChild* ps = new PluginStreamChild();
NPError result;
CallPPluginStreamConstructor(ps, nsDependentCString(aMIMEType),
NullableString(aWindow), &result);
if (NPERR_NO_ERROR != result) {
*aStream = NULL;
CallPPluginStreamDestructor(ps, NPERR_GENERIC_ERROR, true);
PPluginStreamChild::Call__delete__(ps, NPERR_GENERIC_ERROR, true);
return result;
}

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

@ -41,6 +41,7 @@
#include "mozilla/plugins/PPluginInstanceChild.h"
#include "mozilla/plugins/PluginScriptableObjectChild.h"
#include "mozilla/plugins/StreamNotifyChild.h"
#if defined(OS_WIN)
#include "mozilla/gfx/SharedDIBWin.h"
#endif
@ -73,6 +74,8 @@ class PluginInstanceChild : public PPluginInstanceChild
protected:
virtual bool AnswerNPP_SetWindow(const NPRemoteWindow& window, NPError* rv);
virtual bool Answer__delete__(NPError* rv);
virtual bool
AnswerNPP_GetValue_NPPVpluginWindow(bool* windowed, NPError* rv);
@ -108,14 +111,7 @@ protected:
uint16_t *stype);
virtual bool
AnswerPBrowserStreamDestructor(PBrowserStreamChild* stream,
const NPError& reason,
const bool& artificial);
virtual bool
DeallocPBrowserStream(PBrowserStreamChild* stream,
const NPError& reason,
const bool& artificial);
DeallocPBrowserStream(PBrowserStreamChild* stream);
virtual PPluginStreamChild*
AllocPPluginStream(const nsCString& mimeType,
@ -123,14 +119,7 @@ protected:
NPError* result);
virtual bool
AnswerPPluginStreamDestructor(PPluginStreamChild* stream,
const NPReason& reason,
const bool& artificial);
virtual bool
DeallocPPluginStream(PPluginStreamChild* stream,
const NPReason& reason,
const bool& artificial);
DeallocPPluginStream(PPluginStreamChild* stream);
virtual PStreamNotifyChild*
AllocPStreamNotify(const nsCString& url, const nsCString& target,
@ -139,12 +128,7 @@ protected:
NPError* result);
NS_OVERRIDE virtual bool
AnswerPStreamNotifyDestructor(PStreamNotifyChild* notifyData,
const NPReason& reason);
NS_OVERRIDE virtual bool
DeallocPStreamNotify(PStreamNotifyChild* notifyData,
const NPReason& reason);
DeallocPStreamNotify(PStreamNotifyChild* notifyData);
public:
PluginInstanceChild(const NPPluginFuncs* aPluginIface);
@ -177,6 +161,8 @@ public:
bool
InternalInvalidateRect(NPRect* aInvalidRect);
bool NotifyStream(StreamNotifyChild* notifyData, NPReason reason);
private:
#if defined(OS_WIN)

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

@ -114,20 +114,7 @@ PluginInstanceParent::AllocPBrowserStream(const nsCString& url,
}
bool
PluginInstanceParent::AnswerPBrowserStreamDestructor(PBrowserStreamParent* stream,
const NPError& reason,
const bool& artificial)
{
if (!artificial) {
static_cast<BrowserStreamParent*>(stream)->NPN_DestroyStream(reason);
}
return true;
}
bool
PluginInstanceParent::DeallocPBrowserStream(PBrowserStreamParent* stream,
const NPError& reason,
const bool& artificial)
PluginInstanceParent::DeallocPBrowserStream(PBrowserStreamParent* stream)
{
delete stream;
return true;
@ -142,13 +129,8 @@ PluginInstanceParent::AllocPPluginStream(const nsCString& mimeType,
}
bool
PluginInstanceParent::DeallocPPluginStream(PPluginStreamParent* stream,
const NPError& reason,
const bool& artificial)
PluginInstanceParent::DeallocPPluginStream(PPluginStreamParent* stream)
{
if (!artificial) {
static_cast<PluginStreamParent*>(stream)->NPN_DestroyStream(reason);
}
delete stream;
return true;
}
@ -310,14 +292,13 @@ PluginInstanceParent::AnswerPStreamNotifyConstructor(PStreamNotifyParent* actor,
}
if (*result != NPERR_NO_ERROR)
CallPStreamNotifyDestructor(actor, NPERR_GENERIC_ERROR);
PStreamNotifyParent::Call__delete__(actor, NPERR_GENERIC_ERROR);
return true;
}
bool
PluginInstanceParent::DeallocPStreamNotify(PStreamNotifyParent* notifyData,
const NPReason& reason)
PluginInstanceParent::DeallocPStreamNotify(PStreamNotifyParent* notifyData)
{
delete notifyData;
return true;
@ -547,7 +528,7 @@ PluginInstanceParent::NPP_NewStream(NPMIMEType type, NPStream* stream,
return NPERR_GENERIC_ERROR;
if (NPERR_NO_ERROR != err)
CallPBrowserStreamDestructor(bs, NPERR_GENERIC_ERROR, true);
PBrowserStreamParent::Call__delete__(bs, NPERR_GENERIC_ERROR, true);
return err;
}
@ -564,7 +545,7 @@ PluginInstanceParent::NPP_DestroyStream(NPStream* stream, NPReason reason)
if (sp->mNPP != this)
NS_RUNTIMEABORT("Mismatched plugin data");
CallPBrowserStreamDestructor(sp, reason, false);
PBrowserStreamParent::Call__delete__(sp, reason, false);
return NPERR_NO_ERROR;
}
else {
@ -573,7 +554,7 @@ PluginInstanceParent::NPP_DestroyStream(NPStream* stream, NPReason reason)
if (sp->mInstance != this)
NS_RUNTIMEABORT("Mismatched plugin data");
CallPPluginStreamDestructor(sp, reason, false);
PPluginStreamParent::Call__delete__(sp, reason, false);
return NPERR_NO_ERROR;
}
}
@ -645,7 +626,7 @@ PluginInstanceParent::NPP_URLNotify(const char* url, NPReason reason,
PStreamNotifyParent* streamNotify =
static_cast<PStreamNotifyParent*>(notifyData);
CallPStreamNotifyDestructor(streamNotify, reason);
PStreamNotifyParent::Call__delete__(streamNotify, reason);
}
PluginScriptableObjectParent*

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

@ -57,7 +57,6 @@ namespace mozilla {
namespace plugins {
class PBrowserStreamParent;
class BrowserStreamParent;
class PluginModuleParent;
class PluginInstanceParent : public PPluginInstanceParent
@ -93,26 +92,15 @@ public:
const bool& seekable,
NPError* rv,
uint16_t *stype);
virtual bool
AnswerPBrowserStreamDestructor(PBrowserStreamParent* stream,
const NPError& reason,
const bool& artificial);
virtual bool
DeallocPBrowserStream(PBrowserStreamParent* stream,
const NPError& reason,
const bool& artificial);
DeallocPBrowserStream(PBrowserStreamParent* stream);
virtual PPluginStreamParent*
AllocPPluginStream(const nsCString& mimeType,
const nsCString& target,
NPError* result);
virtual bool
DeallocPPluginStream(PPluginStreamParent* stream,
const NPError& reason,
const bool& artificial);
DeallocPPluginStream(PPluginStreamParent* stream);
virtual bool
AnswerNPN_GetValue_NPNVjavascriptEnabledBool(bool* value, NPError* result);
@ -159,8 +147,7 @@ public:
NPError* result);
virtual bool
DeallocPStreamNotify(PStreamNotifyParent* notifyData,
const NPReason& reason);
DeallocPStreamNotify(PStreamNotifyParent* notifyData);
virtual bool
RecvNPN_InvalidateRect(const NPRect& rect);

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

@ -738,12 +738,12 @@ _destroystream(NPP aNPP,
if (s->IsBrowserStream()) {
BrowserStreamChild* bs = static_cast<BrowserStreamChild*>(s);
bs->EnsureCorrectInstance(p);
p->CallPBrowserStreamDestructor(bs, aReason, false);
PBrowserStreamChild::Call__delete__(bs, aReason, false);
}
else {
PluginStreamChild* ps = static_cast<PluginStreamChild*>(s);
ps->EnsureCorrectInstance(p);
p->CallPPluginStreamDestructor(ps, aReason, false);
PPluginStreamChild::Call__delete__(ps, aReason, false);
}
return NPERR_NO_ERROR;
}
@ -1442,8 +1442,7 @@ PluginModuleChild::AnswerPPluginInstanceConstructor(PPluginInstanceChild* aActor
}
bool
PluginModuleChild::DeallocPPluginInstance(PPluginInstanceChild* aActor,
NPError* rv)
PluginModuleChild::DeallocPPluginInstance(PPluginInstanceChild* aActor)
{
_MOZ_LOG(__FUNCTION__);
AssertPluginThread();
@ -1454,16 +1453,15 @@ PluginModuleChild::DeallocPPluginInstance(PPluginInstanceChild* aActor,
}
bool
PluginModuleChild::AnswerPPluginInstanceDestructor(PPluginInstanceChild* aActor,
NPError* rv)
PluginModuleChild::PluginInstanceDestroyed(PluginInstanceChild* aActor,
NPError* rv)
{
_MOZ_LOG(__FUNCTION__);
AssertPluginThread();
PluginInstanceChild* inst = static_cast<PluginInstanceChild*>(aActor);
*rv = mFunctions.destroy(inst->GetNPP(), 0);
inst->Destroy();
inst->GetNPP()->ndata = 0;
*rv = mFunctions.destroy(aActor->GetNPP(), 0);
aActor->Destroy();
aActor->GetNPP()->ndata = 0;
return true;
}

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

@ -109,12 +109,7 @@ protected:
NPError* rv);
virtual bool
DeallocPPluginInstance(PPluginInstanceChild* aActor,
NPError* rv);
virtual bool
AnswerPPluginInstanceDestructor(PPluginInstanceChild* aActor,
NPError* rv);
DeallocPPluginInstance(PPluginInstanceChild* aActor);
virtual bool
AnswerPPluginInstanceConstructor(PPluginInstanceChild* aActor,
@ -154,6 +149,10 @@ public:
bool NPObjectIsRegisteredForActor(PluginScriptableObjectChild* aActor);
#endif
bool
PluginInstanceDestroyed(PluginInstanceChild* aActor,
NPError* rv);
private:
bool InitGraphics();

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

@ -97,12 +97,10 @@ PluginModuleParent::AllocPPluginInstance(const nsCString& aMimeType,
}
bool
PluginModuleParent::DeallocPPluginInstance(PPluginInstanceParent* aActor,
NPError* _retval)
PluginModuleParent::DeallocPPluginInstance(PPluginInstanceParent* aActor)
{
_MOZ_LOG(__FUNCTION__);
delete aActor;
*_retval = NPERR_NO_ERROR;
return true;
}
@ -147,7 +145,7 @@ PluginModuleParent::NPP_Destroy(NPP instance,
parentInstance->Destroy();
NPError prv;
if (!parentInstance->Module()->CallPPluginInstanceDestructor(parentInstance, &prv)) {
if (!PPluginInstanceParent::Call__delete__(parentInstance, &prv)) {
prv = NPERR_GENERIC_ERROR;
}
instance->pdata = nsnull;
@ -556,7 +554,7 @@ PluginModuleParent::NPP_New(NPMIMEType pluginType, NPP instance,
*error);
if (*error != NPERR_NO_ERROR) {
CallPPluginInstanceDestructor(parentInstance, error);
PPluginInstanceParent::Call__delete__(parentInstance, error);
instance->pdata = nsnull;
return NS_ERROR_FAILURE;
}

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

@ -66,6 +66,8 @@ namespace mozilla {
namespace plugins {
//-----------------------------------------------------------------------------
class BrowserStreamParent;
/**
* PluginModuleParent
*
@ -91,8 +93,7 @@ protected:
NPError* rv);
virtual bool
DeallocPPluginInstance(PPluginInstanceParent* aActor,
NPError* _retval);
DeallocPPluginInstance(PPluginInstanceParent* aActor);
public:
PluginModuleParent(const char* aFilePath);

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

@ -216,7 +216,7 @@ PluginScriptableObjectChild::ScriptableInvalidate(NPObject* aObject)
object->invalidated = true;
if (instance &&
!instance->CallPPluginScriptableObjectDestructor(object->parent)) {
!PPluginScriptableObjectChild::Call__delete__(object->parent)) {
NS_WARNING("Failed to send message!");
}
}

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

@ -306,7 +306,7 @@ PluginScriptableObjectParent::ScriptableInvalidate(NPObject* aObject)
object->invalidated = true;
if (instance &&
!instance->CallPPluginScriptableObjectDestructor(actor)) {
!PPluginScriptableObjectParent::Call__delete__(actor)) {
NS_WARNING("Failed to send message!");
}
}

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

@ -41,13 +41,22 @@
namespace mozilla {
namespace plugins {
PluginStreamChild::PluginStreamChild(PluginInstanceChild* instance)
: mInstance(instance)
PluginStreamChild::PluginStreamChild()
{
memset(&mStream, 0, sizeof(mStream));
mStream.ndata = static_cast<AStream*>(this);
}
bool
PluginStreamChild::Answer__delete__(const NPReason& reason,
const bool& artificial)
{
AssertPluginThread();
if (!artificial)
NPP_DestroyStream(reason);
return true;
}
int32_t
PluginStreamChild::NPN_Write(int32_t length, void* buffer)
{
@ -57,7 +66,8 @@ PluginStreamChild::NPN_Write(int32_t length, void* buffer)
CallNPN_Write(nsCString(static_cast<char*>(buffer), length),
&written);
if (written < 0)
mInstance->CallPPluginStreamDestructor(this, NPERR_GENERIC_ERROR, true);
PPluginStreamChild::Call__delete__(this, NPERR_GENERIC_ERROR, true);
// careful after here! |this| just got deleted
return written;
}
@ -71,7 +81,14 @@ PluginStreamChild::NPP_DestroyStream(NPError reason)
return;
mClosed = true;
mInstance->mPluginIface->destroystream(&mInstance->mData, &mStream, reason);
Instance()->mPluginIface->destroystream(
&Instance()->mData, &mStream, reason);
}
PluginInstanceChild*
PluginStreamChild::Instance()
{
return static_cast<PluginInstanceChild*>(Manager());
}
} // namespace plugins

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

@ -51,17 +51,20 @@ class PluginStreamChild : public PPluginStreamChild, public AStream
friend class PluginInstanceChild;
public:
PluginStreamChild(PluginInstanceChild* instance);
PluginStreamChild();
virtual ~PluginStreamChild() { }
NS_OVERRIDE virtual bool IsBrowserStream() { return false; }
virtual bool Answer__delete__(const NPReason& reason,
const bool& artificial);
int32_t NPN_Write(int32_t length, void* buffer);
void NPP_DestroyStream(NPError reason);
void EnsureCorrectInstance(PluginInstanceChild* i)
{
if (i != mInstance)
if (i != Instance())
NS_RUNTIMEABORT("Incorrect stream instance");
}
void EnsureCorrectStream(NPStream* s)
@ -71,7 +74,8 @@ public:
}
private:
PluginInstanceChild* mInstance;
PluginInstanceChild* Instance();
NPStream mStream;
bool mClosed;
};

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

@ -75,6 +75,15 @@ PluginStreamParent::AnswerNPN_Write(const Buffer& data, int32_t* written)
return true;
}
bool
PluginStreamParent::Answer__delete__(const NPError& reason,
const bool& artificial)
{
if (!artificial)
this->NPN_DestroyStream(reason);
return true;
}
void
PluginStreamParent::NPN_DestroyStream(NPReason reason)
{

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

@ -60,9 +60,11 @@ public:
virtual bool AnswerNPN_Write(const Buffer& data, int32_t* written);
void NPN_DestroyStream(NPReason reason);
virtual bool Answer__delete__(const NPError& reason, const bool& artificial);
private:
void NPN_DestroyStream(NPReason reason);
PluginInstanceParent* mInstance;
NPStream* mStream;
bool mClosed;

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

@ -59,6 +59,8 @@ public:
mClosure = aClosure;
}
bool Answer__delete__(const NPReason& reason);
private:
nsCString mURL;
void* mClosure;

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

@ -296,12 +296,6 @@ class MessageDecl(Node):
def hasReply(self):
return self.sendSemantics is SYNC or self.sendSemantics is RPC
class TransitionStmt(Node):
def __init__(self, loc, state, transitions):
Node.__init__(self, loc)
self.state = state
self.transitions = transitions
class Transition(Node):
def __init__(self, loc, trigger, msg, toStates):
Node.__init__(self, loc)
@ -313,6 +307,18 @@ class Transition(Node):
def nameToTrigger(name):
return { 'send': SEND, 'recv': RECV, 'call': CALL, 'answer': ANSWER }[name]
Transition.NULL = Transition(Loc.NONE, None, None, [ ])
class TransitionStmt(Node):
def __init__(self, loc, state, transitions):
Node.__init__(self, loc)
self.state = state
self.transitions = transitions
@staticmethod
def makeNullStmt(state):
return TransitionStmt(Loc.NONE, state, [ Transition.NULL ])
class SEND:
pretty = 'send'
@classmethod
@ -355,7 +361,7 @@ class State(Node):
def __str__(self): return '<State %s start=%s>'% (self.name, self.start)
State.ANY = State(Loc.NONE, '[any]', start=True)
State.NONE = State(Loc.NONE, '[none]', start=False)
State.DEAD = State(Loc.NONE, '[dead]', start=False)
class Param(Node):
def __init__(self, loc, typespec, name):

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

@ -56,6 +56,19 @@ Types = (
'intptr_t',
'uintptr_t',
# NSPR types
'PRBool',
'PRPackedBool'
'PRInt8',
'PRUint8',
'PRInt16',
'PRUint16',
'PRInt32',
'PRUint32',
'PRInt64',
'PRUint64',
'PRSize',
# Mozilla types: "less" standard things we know how serialize/deserialize
'nsresult',
'nsString',

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

@ -468,12 +468,12 @@ class MethodDecl(Node):
self.typeop = typeop # Type or None
def __deepcopy__(self, memo):
return MethodDecl(self.name,
copy.deepcopy(self.params, memo),
copy.deepcopy(self.ret, memo),
self.virtual,
self.const,
self.pure)
return MethodDecl(
self.name,
copy.deepcopy(self.params, memo),
copy.deepcopy(self.ret, memo),
self.virtual, self.const, self.pure, self.static,
copy.deepcopy(self.typeop, memo))
class MethodDefn(Block):
def __init__(self, decl):

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

@ -387,6 +387,13 @@ def errfnSend(msg, errcode=ExprLiteral.FALSE):
def errfnSendCtor(msg): return errfnSend(msg, errcode=ExprLiteral.NULL)
# TODO should this error handling be strengthened for dtors?
def errfnSendDtor(msg):
return [
_printErrorMessage(msg),
StmtReturn(ExprLiteral.FALSE)
]
# used in |OnMessage*()| handlers that hand in-messages off to Recv*()
# interface methods
def errfnRecv(msg, errcode=_Result.ValuError):
@ -425,6 +432,11 @@ class _ConvertToCxxType(TypeVisitor):
def visitVoidType(self, v): assert 0
def visitStateType(self, st): assert 0
def _allocMethod(ptype):
return ExprVar('Alloc'+ ptype.name())
def _deallocMethod(ptype):
return ExprVar('Dealloc'+ ptype.name())
class _ConvertToSerializableCxxType(TypeVisitor):
def visitBuiltinCxxType(self, t):
@ -1086,24 +1098,18 @@ IPDL union type."""
class MessageDecl(ipdl.ast.MessageDecl):
def baseName(self):
if self.decl.type.isDtor():
return self.name[1:]
return self.name
def recvMethod(self):
name = _recvPrefix(self.decl.type) + self.baseName()
if self.decl.type.isCtor():
name += 'Constructor'
elif self.decl.type.isDtor():
name += 'Destructor'
return ExprVar(name)
def sendMethod(self):
name = _sendPrefix(self.decl.type) + self.baseName()
if self.decl.type.isCtor():
name += 'Constructor'
elif self.decl.type.isDtor():
name += 'Destructor'
return ExprVar(name)
def hasReply(self):
@ -1111,13 +1117,6 @@ class MessageDecl(ipdl.ast.MessageDecl):
or self.decl.type.isCtor()
or self.decl.type.isDtor())
# XXX best place for this?
def allocMethod(self):
return ExprVar('Alloc'+ self.baseName())
def deallocMethod(self):
return ExprVar('Dealloc'+ self.baseName())
def msgClass(self):
return 'Msg_%s'% (self.decl.progname)
@ -1126,7 +1125,7 @@ class MessageDecl(ipdl.ast.MessageDecl):
def msgCast(self, msgexpr):
return ExprCast(msgexpr, Type(self.pqMsgClass(), const=1, ptr=1),
reinterpret=1)
static=1)
def msgId(self): return self.msgClass()+ '__ID'
def pqMsgId(self):
@ -1140,7 +1139,7 @@ class MessageDecl(ipdl.ast.MessageDecl):
def replyCast(self, replyexpr):
return ExprCast(replyexpr, Type(self.pqReplyClass(), const=1, ptr=1),
reinterpret=1)
static=1)
def replyId(self): return self.replyClass()+ '__ID'
def pqReplyId(self):
@ -1262,11 +1261,24 @@ class Protocol(ipdl.ast.Protocol):
def fqListenerName(self):
return self.channelName() +'::'+ _semsToListener(self.sendSems())
def managerCxxType(self, ptr=0):
def managerInterfaceType(self, ptr=0):
return Type('mozilla::ipc::IProtocolManager',
ptr=ptr,
T=Type(self.fqListenerName()))
def managerActorType(self, side, ptr=0):
return Type(_actorName(self.decl.type.manager.name(), side),
ptr=ptr)
def managerMethod(self, actorThis=None):
if actorThis is not None:
return ExprSelect(actorThis, '->', 'Manager')
return ExprVar('Manager');
# FIXME/bug 525181: implement
def stateMethod(self):
return ExprVar('state');
def registerMethod(self):
return ExprVar('Register')
@ -1276,7 +1288,9 @@ class Protocol(ipdl.ast.Protocol):
def lookupIDMethod(self):
return ExprVar('Lookup')
def unregisterMethod(self):
def unregisterMethod(self, actorThis=None):
if actorThis is not None:
return ExprSelect(actorThis, '->', 'Unregister')
return ExprVar('Unregister')
def otherProcessMethod(self):
@ -1306,7 +1320,9 @@ class Protocol(ipdl.ast.Protocol):
assert self.decl.type.isToplevel()
return ExprVar('mActorMap')
def channelVar(self):
def channelVar(self, actorThis=None):
if actorThis is not None:
return ExprSelect(actorThis, '->', 'mChannel')
return ExprVar('mChannel')
def channelForSubactor(self):
@ -1314,9 +1330,11 @@ class Protocol(ipdl.ast.Protocol):
return ExprAddrOf(self.channelVar())
return self.channelVar()
def routingId(self):
def routingId(self, actorThis=None):
if self.decl.type.isToplevel():
return ExprVar('MSG_ROUTING_CONTROL')
if actorThis is not None:
return ExprSelect(actorThis, '->', self.idVar().name)
return self.idVar()
def idVar(self):
@ -1392,8 +1410,9 @@ with some new IPDL/C++ nodes that are tuned for C++ codegen."""
# the set of typedefs that allow generated classes to
# reference known C++ types by their "short name" rather than
# fully-qualified name. e.g. |Foo| rather than |a::b::Foo|.
self.typedefs = [ Typedef(Type('mozilla::ipc::ActorHandle'),
'ActorHandle') ]
self.typedefs = [
Typedef(Type('mozilla::ipc::ActorHandle'), 'ActorHandle')
]
self.protocolName = None
def visitProtocol(self, pro):
@ -1426,7 +1445,7 @@ with some new IPDL/C++ nodes that are tuned for C++ codegen."""
if ud.decl.fullname is not None:
self.typedefs.append(Typedef(Type(ud.fqClassName()), ud.name))
def visitDecl(self, decl):
return _HybridDecl(decl.type, decl.progname)
@ -2437,13 +2456,16 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
inherits = [ Inherit(Type(p.fqListenerName())) ]
if p.decl.type.isManager():
inherits.append(Inherit(p.managerCxxType()))
inherits.append(Inherit(p.managerInterfaceType()))
self.cls = Class(self.clsname, inherits=inherits, abstract=True)
friends = _FindFriends().findFriends(p.decl.type)
if p.decl.type.isManaged():
friends.add(p.decl.type.manager)
# |friend| managed actors so that they can call our Dealloc*()
friends.update(p.decl.type.manages)
for friend in friends:
self.hdrfile.addthings([
Whitespace.NL,
@ -2465,29 +2487,14 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
# interface methods that the concrete subclass has to impl
for md in p.messageDecls:
isctor, isdtor = md.decl.type.isCtor(), md.decl.type.isDtor()
if isctor:
self.cls.addstmt(StmtDecl(MethodDecl(
md.allocMethod().name,
params=md.makeCxxParams(paramsems='in', returnsems='out',
side=self.side,
implicit=0),
ret=md.actorDecl().bareType(self.side),
virtual=1, pure=1)))
elif isdtor:
self.cls.addstmt(StmtDecl(MethodDecl(
md.deallocMethod().name,
params=md.makeCxxParams(paramsems='in', returnsems='out',
side=self.side,
implicit=1),
ret=Type.BOOL,
virtual=1, pure=1)))
if self.receivesMessage(md):
# generate Recv/Answer* interface
implicit = (not isdtor)
recvDecl = MethodDecl(
md.recvMethod().name,
params=md.makeCxxParams(paramsems='in', returnsems='out',
side=self.side, implicit=1),
side=self.side, implicit=implicit),
ret=Type.BOOL, virtual=1)
if isctor or isdtor:
@ -2498,6 +2505,27 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
recvDecl.pure = 1
self.cls.addstmt(StmtDecl(recvDecl))
for md in p.messageDecls:
managed = md.decl.type.constructedType()
if not p.decl.type.isManagerOf(managed):
continue
# add the Alloc/Dealloc interface for managed actors
actortype = md.actorDecl().bareType(self.side)
self.cls.addstmt(StmtDecl(MethodDecl(
_allocMethod(managed).name,
params=md.makeCxxParams(side=self.side, implicit=0),
ret=actortype,
virtual=1, pure=1)))
self.cls.addstmt(StmtDecl(MethodDecl(
_deallocMethod(managed).name,
params=[ Decl(actortype, 'actor') ],
ret=Type.BOOL,
virtual=1, pure=1)))
self.cls.addstmt(Whitespace.NL)
self.cls.addstmts((
@ -2564,6 +2592,15 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
ExprCall(ExprSelect(p.channelVar(), '.', 'Close'))))
self.cls.addstmts([ closemeth, Whitespace.NL ])
if not p.decl.type.isToplevel():
## manager()
managertype = p.managerActorType(self.side, ptr=1)
managermeth = MethodDefn(MethodDecl(
p.managerMethod().name, ret=managertype))
managermeth.addstmt(StmtReturn(p.managerVar()))
self.cls.addstmts([ managermeth, Whitespace.NL ])
## OnMessageReceived()/OnCallReceived()
# save these away for use in message handler case stmts
@ -2718,7 +2755,8 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
elif p.decl.type.isManaged():
self.cls.addstmts([
StmtDecl(Decl(_actorIdType(), p.idVar().name)),
StmtDecl(Decl(p.managerCxxType(ptr=1), p.managerVar().name))
StmtDecl(Decl(p.managerActorType(self.side, ptr=1),
p.managerVar().name))
])
if p.usesShmem():
self.cls.addstmts([
@ -3014,6 +3052,11 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
sendmethod = self.genAsyncSendMethod(md)
else:
sendmethod = self.genBlockingSendMethod(md)
# XXX figure out what to do here
if isdtor and md.decl.type.constructedType().isToplevel():
sendmethod = None
if sendmethod is not None:
self.cls.addstmts([ sendmethod, Whitespace.NL ])
if recvcase is not None:
@ -3027,6 +3070,11 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
recvlbl, recvcase = self.genDtorRecvCase(md)
else:
recvlbl, recvcase = self.genRecvCase(md)
# XXX figure out what to do here
if isdtor and md.decl.type.constructedType().isToplevel():
return
addRecvCase(recvlbl, recvcase)
@ -3117,17 +3165,19 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
def genAsyncDtor(self, md):
actor = md.actorDecl()
method = MethodDefn(self.makeSendMethodDecl(md))
actorvar = actor.var()
method = MethodDefn(self.makeDtorMethodDecl(md))
method.addstmts(self.dtorPrologue(actor.var()))
method.addstmts(self.dtorPrologue(actorvar))
msgvar, stmts = self.makeMessage(md, errfnSend)
sendok, sendstmts = self.sendAsync(md, msgvar)
msgvar, stmts = self.makeMessage(md, errfnSendDtor, actorvar)
sendok, sendstmts = self.sendAsync(md, msgvar, actorvar)
method.addstmts(
stmts
+ sendstmts
+ [ Whitespace.NL ]
+ self.dtorEpilogue(md, actor.var(), retsems='out')
+ self.dtorEpilogue(md, actor.var())
+ [ StmtReturn(sendok) ])
lbl = CaseLabel(md.pqReplyId())
@ -3141,14 +3191,15 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
def genBlockingDtorMethod(self, md):
actor = md.actorDecl()
method = MethodDefn(self.makeSendMethodDecl(md))
actorvar = actor.var()
method = MethodDefn(self.makeDtorMethodDecl(md))
method.addstmts(self.dtorPrologue(actor.var()))
method.addstmts(self.dtorPrologue(actorvar))
msgvar, stmts = self.makeMessage(md, errfnSend)
msgvar, stmts = self.makeMessage(md, errfnSendDtor, actorvar)
replyvar = self.replyvar
sendok, sendstmts = self.sendBlocking(md, msgvar, replyvar)
sendok, sendstmts = self.sendBlocking(md, msgvar, replyvar, actorvar)
method.addstmts(
stmts
+ [ Whitespace.NL,
@ -3164,7 +3215,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
method.addstmts(
[ ifsendok ]
+ self.dtorEpilogue(md, actor.var(), retsems='out')
+ self.dtorEpilogue(md, actor.var())
+ [ Whitespace.NL, StmtReturn(sendok) ])
return method
@ -3172,9 +3223,9 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
def dtorPrologue(self, actorexpr):
return [ self.failIfNullActor(actorexpr), Whitespace.NL ]
def dtorEpilogue(self, md, actorexpr, retsems):
def dtorEpilogue(self, md, actorexpr):
return (self.unregisterActor(actorexpr)
+ [ StmtExpr(self.callDeallocActor(md, retsems)) ])
+ [ StmtExpr(self.callDeallocActor(md, actorexpr)) ])
def genAsyncSendMethod(self, md):
method = MethodDefn(self.makeSendMethodDecl(md))
@ -3187,10 +3238,10 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
return method
def genBlockingSendMethod(self, md):
def genBlockingSendMethod(self, md, fromActor=None):
method = MethodDefn(self.makeSendMethodDecl(md))
msgvar, serstmts = self.makeMessage(md, errfnSend)
msgvar, serstmts = self.makeMessage(md, errfnSend, fromActor)
replyvar = self.replyvar
sendok, sendstmts = self.sendBlocking(md, msgvar, replyvar)
@ -3256,9 +3307,9 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
+ [ failif, Whitespace.NL ]
+ [ StmtDecl(Decl(r.bareType(self.side), r.var().name))
for r in md.returns ]
+ self.invokeRecvHandler(md)
+ self.invokeRecvHandler(md, implicit=0)
+ [ Whitespace.NL ]
+ self.dtorEpilogue(md, md.actorDecl().var(), retsems='in')
+ self.dtorEpilogue(md, md.actorDecl().var())
+ self.makeReply(md, errfnRecv)
+ [ Whitespace.NL,
StmtReturn(_Result.Processed) ])
@ -3295,11 +3346,11 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
return failif
def unregisterActor(self, actorexpr):
return [ StmtExpr(ExprCall(self.protocol.unregisterMethod(),
return [ StmtExpr(ExprCall(self.protocol.unregisterMethod(actorexpr),
args=[ _actorId(actorexpr) ])),
StmtExpr(ExprAssn(_actorId(actorexpr), _FREED_ACTOR_ID)) ]
def makeMessage(self, md, errfn):
def makeMessage(self, md, errfn, fromActor=None):
msgvar = self.msgvar
stmts = [ StmtDecl(Decl(Type(md.pqMsgClass(), ptr=1), msgvar.name)),
Whitespace.NL ]
@ -3314,7 +3365,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
StmtExpr(ExprAssn(
msgvar,
ExprNew(Type(md.pqMsgClass()), args=msgCtorArgs))) ]
+ self.setMessageFlags(md, msgvar, reply=0))
+ self.setMessageFlags(md, msgvar, reply=0, actor=fromActor))
return msgvar, stmts
@ -3342,10 +3393,10 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
return stmts
def setMessageFlags(self, md, var, reply):
def setMessageFlags(self, md, var, reply, actor=None):
stmts = [ StmtExpr(ExprCall(
ExprSelect(var, '->', 'set_routing_id'),
args=[ self.protocol.routingId() ])) ]
args=[ self.protocol.routingId(actor) ])) ]
if md.decl.type.isSync():
stmts.append(StmtExpr(ExprCall(
@ -3436,7 +3487,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
return okvar, stmts
def sendAsync(self, md, msgexpr):
def sendAsync(self, md, msgexpr, actor=None):
sendok = ExprVar('__sendok')
return (
sendok,
@ -3445,46 +3496,53 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
Whitespace.NL,
StmtDecl(Decl(Type.BOOL, sendok.name),
init=ExprCall(
ExprSelect(self.protocol.channelVar(),
ExprSelect(self.protocol.channelVar(actor),
self.protocol.channelSel(), 'Send'),
args=[ msgexpr ]))
])
def sendBlocking(self, md, msgexpr, replyexpr):
def sendBlocking(self, md, msgexpr, replyexpr, actor=None):
sendok = ExprVar('__sendok')
return (
sendok,
[ Whitespace.NL,
self.logMessage(md, msgexpr, 'Sending '),
Whitespace.NL,
StmtDecl(Decl(Type.BOOL, sendok.name),
init=ExprCall(ExprSelect(self.protocol.channelVar(),
self.protocol.channelSel(),
_sendPrefix(md.decl.type)),
args=[ msgexpr,
ExprAddrOf(replyexpr) ]))
StmtDecl(
Decl(Type.BOOL, sendok.name),
init=ExprCall(ExprSelect(self.protocol.channelVar(actor),
self.protocol.channelSel(),
_sendPrefix(md.decl.type)),
args=[ msgexpr, ExprAddrOf(replyexpr) ]))
])
def callAllocActor(self, md, retsems):
return ExprCall(
md.allocMethod(),
_allocMethod(md.decl.type.constructedType()),
args=md.makeCxxArgs(params=1, retsems=retsems, retcallsems='out',
implicit=0))
def callDeallocActor(self, md, retsems):
def callDeallocActor(self, md, actorexpr):
actor = md.decl.type.constructedType()
return ExprCall(
md.deallocMethod(),
args=md.makeCxxArgs(params=1, retsems=retsems, retcallsems='out'))
ExprSelect(ExprCall(self.protocol.managerMethod(actorexpr)), '->',
_deallocMethod(md.decl.type.constructedType()).name),
args=[ actorexpr ])
def invokeRecvHandler(self, md):
def invokeRecvHandler(self, md, implicit=1):
failif = StmtIf(ExprNot(
ExprCall(md.recvMethod(),
args=md.makeCxxArgs(params=1,
retsems='in', retcallsems='out'))))
retsems='in', retcallsems='out',
implicit=implicit))))
failif.addifstmt(StmtReturn(_Result.ValuError))
return [ failif ]
def makeDtorMethodDecl(self, md):
decl = self.makeSendMethodDecl(md)
decl.static = 1
return decl
def makeSendMethodDecl(self, md):
implicit = md.decl.type.hasImplicitActorParam()
decl = MethodDecl(

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

@ -145,6 +145,8 @@ reserved = set((
'both',
'call',
'child',
'__delete__',
'delete', # reserve 'delete' to prevent its use
'goto',
'include',
'manager',
@ -395,9 +397,13 @@ def p_MessageBody(p):
def p_MessageId(p):
"""MessageId : ID
| __DELETE__
| DELETE
| '~' ID"""
if 3 == len(p):
p[1] += p[2] # munge dtor name to "~Foo". handled later
_error(locFromTok(p, 1), "sorry, `%s()' destructor syntax is a relic from a bygone era. Declare `__delete__()' in the `%s' protocol instead", p[1]+p[2], p[2])
elif 'delete' == p[1]:
_error(locFromTok(p, 1), "`delete' is a reserved identifier")
p[0] = p[1]
def p_MessageInParams(p):
@ -452,9 +458,18 @@ def p_Transitions(p):
p[0] = [ p[1] ]
def p_Transition(p):
"""Transition : Trigger MessageId GOTO StateList ';'"""
"""Transition : Trigger ID GOTO StateList ';'
| Trigger __DELETE__ ';'
| Trigger DELETE ';'"""
if 'delete' == p[2]:
_error(locFromTok(p, 1), "`delete' is a reserved identifier")
loc, trigger = p[1]
p[0] = Transition(loc, trigger, p[2], p[4])
if 6 == len(p):
nextstates = p[4]
else:
nextstates = [ State.DEAD ]
p[0] = Transition(loc, trigger, p[2], nextstates)
def p_Trigger(p):
"""Trigger : SEND

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

@ -32,9 +32,10 @@
import os, sys
from ipdl.ast import CxxInclude, Decl, Loc, QualifiedId, State, TypeSpec, UsingStmt, Visitor, ASYNC, SYNC, RPC, IN, OUT, INOUT, ANSWER, CALL, RECV, SEND
from ipdl.ast import CxxInclude, Decl, Loc, QualifiedId, State, TransitionStmt, TypeSpec, UsingStmt, Visitor, ASYNC, SYNC, RPC, IN, OUT, INOUT, ANSWER, CALL, RECV, SEND
import ipdl.builtin as builtin
_DELETE_MSG = '__delete__'
class TypeVisitor:
def defaultVisit(self, node, *args):
@ -230,11 +231,12 @@ class MessageType(IPDLType):
return self.isCtor() or self.isDtor()
class ProtocolType(IPDLType):
def __init__(self, qname, sendSemantics):
def __init__(self, qname, sendSemantics, stateless=False):
self.qname = qname
self.sendSemantics = sendSemantics
self.manager = None
self.manages = [ ]
self.stateless = stateless
def isProtocol(self): return True
def name(self):
@ -447,7 +449,6 @@ With this information, it finally type checks the AST.'''
if (len(tu.protocol.startStates)
and not runpass(CheckStateMachine(self.errors))):
return False
return True
def reportErrors(self, errout):
@ -514,7 +515,8 @@ class GatherDecls(TcheckVisitor):
fullname = str(qname)
p.decl = self.declare(
loc=p.loc,
type=ProtocolType(qname, p.sendSemantics),
type=ProtocolType(qname, p.sendSemantics,
stateless=(0 == len(p.transitionStmts))),
shortname=p.name,
fullname=fullname)
@ -543,6 +545,11 @@ class GatherDecls(TcheckVisitor):
def visitProtocolInclude(self, pi):
if pi.tu is None:
self.error(
pi.loc,
"(type checking here will be unreliable because of an earlier error)")
return
pi.tu.accept(self)
self.symtab.declare(pi.tu.protocol.decl)
@ -604,16 +611,22 @@ class GatherDecls(TcheckVisitor):
msg.accept(self)
del self.currentProtocolDecl
if not p.decl.type.isToplevel():
dtordecl = self.symtab.lookup(_DELETE_MSG)
if not dtordecl:
self.error(
p.loc,
"destructor declaration `delete(...)' required for managed protocol `%s'",
p.name)
for managed in p.managesStmts:
mgdname = managed.name
ctordecl = self.symtab.lookup(mgdname +'Constructor')
dtordecl = self.symtab.lookup(mgdname +'Destructor')
if not(ctordecl and dtordecl
and ctordecl.type.isCtor() and dtordecl.type.isDtor()):
if not (ctordecl and ctordecl.type.isCtor()):
self.error(
managed.loc,
"constructor and destructor declarations are required for managed protocol `%s' (managed by protocol `%s')",
"constructor declaration required for managed protocol `%s' (managed by protocol `%s')",
mgdname, p.name)
p.states = { }
@ -623,6 +636,14 @@ class GatherDecls(TcheckVisitor):
if ts.state.start ]
if 0 == len(p.startStates):
p.startStates = [ p.transitionStmts[0] ]
# declare implicit "any" and "dead" states
self.declare(loc=State.ANY.loc,
type=StateType(p.decl.type, State.ANY.name, start=False),
progname=State.ANY.name)
self.declare(loc=State.DEAD.loc,
type=StateType(p.decl.type, State.DEAD.name, start=False),
progname=State.DEAD.name)
# declare each state before decorating their mention
for trans in p.transitionStmts:
@ -632,15 +653,17 @@ class GatherDecls(TcheckVisitor):
type=StateType(p.decl.type, trans.state, trans.state.start),
progname=trans.state.name)
# declare implicit "any" state
self.declare(loc=State.ANY.loc,
type=StateType(p.decl.type, State.ANY.name, start=False),
progname=State.ANY.name)
for trans in p.transitionStmts:
self.seentriggers = set()
trans.accept(self)
if not (p.decl.type.stateless
or (p.decl.type.isToplevel()
and None is self.symtab.lookup(_DELETE_MSG))):
# add a special state |state DEAD: null goto DEAD;|
deadtrans = TransitionStmt.makeNullStmt(State.DEAD)
p.states[State.DEAD] = deadtrans
# visit the message decls once more and resolve the state names
# attached to actor params and returns
def resolvestate(loc, actortype):
@ -750,23 +773,7 @@ class GatherDecls(TcheckVisitor):
isdtor = False
cdtype = None
if '~' == msgname[0]:
# it's a destructor. look up the constructed type
msgname = msgname[1:]
decl = self.symtab.lookup(msgname)
if decl is None:
self.error(loc, "type `%s' has not been declared", msgname)
elif not decl.type.isProtocol():
self.error(loc, "destructor for non-protocol type `%s'",
msgname)
else:
msgname += 'Destructor'
isdtor = True
cdtype = decl.type
decl = self.symtab.lookup(msgname)
if decl is not None and decl.type.isProtocol():
# probably a ctor. we'll check validity later.
msgname += 'Constructor'
@ -776,7 +783,11 @@ class GatherDecls(TcheckVisitor):
self.error(loc, "message name `%s' already declared as `%s'",
msgname, decl.type.typename())
# if we error here, no big deal; move on to find more
decl = None
if _DELETE_MSG == msgname:
isdtor = True
cdtype = self.currentProtocolDecl.type
# enter message scope
self.symtab.enterScope(md)
@ -938,6 +949,17 @@ class CheckTypes(TcheckVisitor):
"protocol `%s' requires more powerful send semantics than its manager `%s' provides",
pname, mgrname)
# XXX currently we don't require a delete() message of top-level
# actors. need to let experience guide this decision
if not p.decl.type.isToplevel():
for md in p.messageDecls:
if _DELETE_MSG == md.name: break
else:
self.error(
p.decl.loc,
"managed protocol `%s' requires a `delete()' message to be declared",
p.name)
return Visitor.visitProtocol(self, p)
@ -1009,10 +1031,10 @@ class CheckTypes(TcheckVisitor):
"asynchronous message `%s' declares return values",
mname)
if (mtype.isCtor() or mtype.isDtor()) and not ptype.isManagerOf(mtype.constructedType()):
if mtype.isCtor() and not ptype.isManagerOf(mtype.constructedType()):
self.error(
loc,
"ctor/dtor for protocol `%s', which is not managed by protocol `%s'",
"ctor for protocol `%s', which is not managed by protocol `%s'",
mname[:-len('constructor')], pname)
@ -1022,7 +1044,7 @@ class CheckTypes(TcheckVisitor):
loc = t.loc
impliedDirection, impliedSems = {
SEND: [ OUT, _YNC ], RECV: [ IN, _YNC ],
CALL: [ OUT, RPC ], ANSWER: [ IN, RPC ]
CALL: [ OUT, RPC ], ANSWER: [ IN, RPC ],
} [t.trigger]
if (OUT is impliedDirection and t.msg.type.isIn()
@ -1253,18 +1275,30 @@ direction as trigger |t|'''
return
def checkReachability(self, p):
visited = set() # set(State)
def explore(ts):
def explore(ts, visited):
if ts.state in visited:
return
visited.add(ts.state)
for outedge in ts.transitions:
for toState in outedge.toStates:
explore(p.states[toState])
explore(p.states[toState], visited)
checkfordelete = (State.DEAD in p.states)
allvisited = set() # set(State)
for root in p.startStates:
explore(root)
for ts in p.transitionStmts:
if ts.state not in visited:
self.error(ts.loc, "unreachable state `%s' in protocol `%s'",
visited = set()
explore(root, visited)
allvisited.update(visited)
if checkfordelete and State.DEAD not in visited:
self.error(
root.loc,
"when starting from state `%s', actors of protocol `%s' cannot be deleted", root.state.name, p.name)
for ts in p.states.itervalues():
if ts.state is not State.DEAD and ts.state not in allvisited:
self.error(ts.loc,
"unreachable state `%s' in protocol `%s'",
ts.state.name, p.name)

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

@ -37,7 +37,7 @@ child:
Start();
parent:
~PTestArraysSub();
__delete__();
sync Test1(int[] i1)
returns (int[] o1);
@ -84,6 +84,24 @@ parent:
sync Test10(Unions[] i1)
returns (Unions[] o1);
state START:
send Start goto TEST1;
state TEST1: recv Test1 goto TEST2;
state TEST2: recv Test2 goto TEST3;
state TEST3: recv Test3 goto TEST4;
state TEST4: recv Test4 goto TEST5;
state TEST5: recv Test5 goto TEST6;
state TEST6: recv Test6 goto TEST7;
state TEST7: recv Test7 goto TEST8;
state TEST8: recv Test8 goto TEST9;
state TEST9: recv Test9 goto TEST10;
state TEST10: recv Test10 goto DEAD;
state DEAD:
recv __delete__;
};
} // namespace _ipdltest

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

@ -5,7 +5,9 @@ namespace _ipdltest {
protocol PTestArraysSub {
manager PTestArrays;
// empty
parent:
__delete__();
};
} // namespace _ipdltest

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

@ -8,7 +8,6 @@ protocol PTestDesc {
manages PTestDescSub;
child:
PTestDescSub();
~PTestDescSub();
Test(PTestDescSubsub a);

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

@ -9,8 +9,9 @@ protocol PTestDescSub {
manages PTestDescSubsub;
child:
__delete__();
PTestDescSubsub();
~PTestDescSubsub();
};
}

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

@ -1,3 +1,4 @@
include protocol "PTestDescSub.ipdl";
namespace mozilla {
@ -6,7 +7,8 @@ namespace _ipdltest {
protocol PTestDescSubsub {
manager PTestDescSub;
// empty
child:
__delete__();
};
}

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

@ -6,6 +6,7 @@ namespace _ipdltest {
protocol PTestLatency {
child:
__delete__();
Ping();
Ping5();
@ -24,7 +25,8 @@ state PONG:
// Trial 2: "overlapped" ping/pong latency
state PING5:
send Ping5 goto PING4;
//send delete; SOMEDAY!
send __delete__;
state PING4: send Ping5 goto PING3;
state PING3: send Ping5 goto PING2;
state PING2: send Ping5 goto PING1;

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

@ -9,8 +9,6 @@ protocol PTestManyChildAllocs {
child:
Go(); // start allocating
~PTestManyChildAllocsSub();
parent:
Done();

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

@ -6,6 +6,9 @@ namespace _ipdltest {
protocol PTestManyChildAllocsSub {
manager PTestManyChildAllocs;
child:
__delete__();
parent:
Hello();

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

@ -7,13 +7,11 @@ protocol PTestSanity {
child:
Ping(int zero, float zeroPtFive);
__delete__();
parent:
Pong(int one, float zeroPtTwoFive);
both:
UNREACHED();
state PING:
send Ping goto PONG;
@ -21,9 +19,8 @@ state PING:
state PONG:
recv Pong goto DEAD;
// hmm ... maybe support this idiom natively?
state DEAD:
send UNREACHED goto DEAD;
send __delete__;
};

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

@ -62,11 +62,12 @@ TestArraysParent::Main()
}
bool
TestArraysParent::RecvPTestArraysSubDestructor(PTestArraysSubParent* actor)
TestArraysParent::DeallocPTestArraysSub(PTestArraysSubParent* actor)
{
test_assert(Cast(actor).mI == Cast(mKids[0]).mI,
"dtor sent to wrong actor");
mKids.RemoveElementAt(0);
delete actor;
if (mKids.Length() > 0)
return true;
@ -321,7 +322,7 @@ TestArraysChild::RecvStart()
Test10();
for (uint32 i = 0; i < nactors; ++i)
if (!SendPTestArraysSubDestructor(mKids[i]))
if (!PTestArraysSubChild::Send__delete__(mKids[i]))
fail("can't send dtor");
return true;

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

@ -46,14 +46,7 @@ protected:
return actor;
}
virtual bool DeallocPTestArraysSub(PTestArraysSubParent* actor)
{
delete actor;
return true;
}
virtual bool
RecvPTestArraysSubDestructor(PTestArraysSubParent* actor);
virtual bool DeallocPTestArraysSub(PTestArraysSubParent* actor);
virtual bool RecvTest1(
const nsTArray<int>& i1,

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

@ -0,0 +1,14 @@
// XXX kind of a gray area whether |delete| should be a part of the
// top-level protocol. but if it's ever not, this test will break and
// we'll notice, right?
protocol DeleteRace {
parent:
M1();
child:
delete();
state START:
send delete;
recv M1 goto START;
};

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

@ -2,8 +2,9 @@ protocol actorparam_badState {
child:
Msg(actorparam_badState:FARGEL p);
delete();
state S1:
send Msg goto S1;
send delete;
};

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

@ -1,6 +1,6 @@
protocol dtorReserved {
// it's an error to use dtor syntax for non-dtor messages
// it's an error to use old-style dtor syntax
child:
~SomeMsg();

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

@ -3,4 +3,5 @@ include protocol "managerNoCtor.ipdl";
protocol managedNoCtor {
manager managerNoCtor;
// empty
child: delete();
};

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

@ -5,5 +5,4 @@ protocol managerNoCtor {
parent:
// error: no ctor defined
~managedNoCtor();
};

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

@ -2,13 +2,20 @@ protocol race_OverlappingMultiOut {
child:
Msg1();
Msg1_();
delete(); suppressUndeleteableError()
parent:
Msg2();
Msg2_();
start state _:
send delete;
send suppressUndeleteableError goto S10;
// *** ERROR: send/recv of Msg1/Msg2 in state S10 goes to overlapping
// sets { S11, S12 }, { S12, S13 } and thus can't be unidirectional
start state S10:
state S10:
send Msg1 goto S11 or S12;
recv Msg2 goto S12 or S13;
@ -25,5 +32,4 @@ state S13:
state S14:
send Msg1 goto S14;
recv Msg2 goto S14;
};

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

@ -2,12 +2,17 @@ protocol race_ViolateSameDirection {
child:
Msg1();
Msg1_();
delete(); suppressUndeleteableError();
parent:
Msg2();
Msg2_();
// *** ERROR: state S7 doesn't have all-same-direction
start state S6:
start state _:
send delete;
send suppressUndeleteableError goto S6;
state S6:
send Msg1 goto S7;
recv Msg2 goto S8;
@ -21,5 +26,4 @@ state S8:
state S9:
send Msg1 goto S9;
recv Msg2 goto S9;
};

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

@ -3,9 +3,12 @@ protocol redefState {
// error: redefining state in state machine
child:
Msg();
delete();
state S1: send Msg goto S1;
state S1: send Msg goto S1;
start state _:
send delete;
};

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

@ -1,5 +1,5 @@
protocol repeatedOutState {
child: Msg();
child: Msg(); delete();
// error: S2 repeated in multi-out set
@ -8,5 +8,5 @@ state S1:
state S2: send Msg goto S2;
state S3: send Msg goto S3;
state S4: send Msg goto S4;
state S4: send Mesg goto S4; send delete;
};

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

@ -2,8 +2,11 @@ protocol trans_WrongDirection {
child:
Msg();
delete();
state S1:
recv Msg goto S1;
start state _:
send delete();
};

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

@ -2,8 +2,11 @@ protocol trans_WrongDirection2 {
parent:
Msg();
delete();
state S1:
send Msg goto S1;
start state _:
recv delete;
};

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

@ -2,8 +2,11 @@ sync protocol trans_WrongDirection3 {
parent:
sync Msg();
delete();
state S1:
send Msg goto S1;
start state _:
recv delete;
};

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

@ -2,8 +2,11 @@ rpc protocol trans_WrongDirection4 {
child:
rpc Msg();
delete();
state S1:
answer Msg goto S1;
start state _:
send delete;
};

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

@ -2,8 +2,11 @@ rpc protocol trans_WrongDirection5 {
parent:
rpc Msg();
delete()
state S1:
call Msg goto S1;
start state_:
recv delete;
};

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

@ -2,8 +2,9 @@ protocol trans_WrongName {
child:
Msg();
delete();
state S1:
call Msg goto S1;
send delete();
};

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

@ -2,8 +2,9 @@ protocol trans_WrongName2 {
parent:
Msg();
delete();
state S1:
answer Msg goto S1;
recv delete;
};

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

@ -2,8 +2,9 @@ sync protocol trans_WrongName3 {
parent:
sync Msg();
delete();
state S1:
answer Msg goto S1;
recv delete();
};

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

@ -2,8 +2,9 @@ rpc protocol trans_WrongName4 {
child:
rpc Msg();
delete();
state S1:
send Msg goto S1;
send delete;
};

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

@ -2,8 +2,9 @@ rpc protocol trans_WrongName5 {
parent:
rpc Msg();
delete();
state S1:
recv Msg goto S1;
recv delete;
};

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

@ -3,5 +3,4 @@ protocol undeclProtocol {
child:
undeclared();
~undeclared();
};

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

@ -0,0 +1,5 @@
protocol unreachedDelete {
child: M1(); delete();
state S1: send M1 goto S1;
};

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

@ -0,0 +1,10 @@
protocol unreachedDeleteMultiStart {
child:
M1(); M2(); delete();
start state S1: send M1 goto S2;
state S2: send delete;
start state S3: send M2 goto S4;
state S4: send M1 goto S3;
};

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

@ -0,0 +1,8 @@
include protocol "DeleteSub.ipdl";
sync protocol Delete {
manages DeleteSub;
child:
DeleteSub();
};

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

@ -0,0 +1,12 @@
include protocol "Delete.ipdl";
sync protocol DeleteSub {
manager Delete;
parent:
sync __delete__(int x) returns (double d);
state START:
recv __delete__;
};

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

@ -2,8 +2,9 @@ protocol actorparam_state {
child:
Msg(actorparam_state:S1 p);
__delete__();
state S1:
send Msg goto S1;
send __delete__;
};

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

@ -7,5 +7,4 @@ child:
Msg(array_OfActorsSub[] p);
array_OfActorsSub();
~array_OfActorsSub();
};

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

@ -3,5 +3,5 @@ include protocol "array_OfActors.ipdl";
protocol array_OfActorsSub {
manager array_OfActors;
// empty
child: __delete__();
};

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

@ -2,5 +2,7 @@ include protocol "managerProtocol.ipdl";
protocol managedProtocol {
manager managerProtocol;
// empty
child:
__delete__();
};

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

@ -7,6 +7,5 @@ protocol managerProtocol {
parent:
managedProtocol(int i);
~managedProtocol(int i);
};

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

@ -1,11 +1,11 @@
protocol multiStartState {
child: Msg();
child: Msg(); __delete__();
start state S1:
send Msg goto S1;
send Msg goto S1; send __delete__;
start state S2:
send Msg goto S2;
send Msg goto S2; send __delete__;
};

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

@ -48,12 +48,11 @@ protocol PTestShell
manages PTestShellCommand;
child:
__delete__();
ExecuteCommand(nsString aCommand);
PTestShellCommand(nsString aCommand);
parent:
~PTestShellCommand(nsString aResponse);
};
} // namespace ipc

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

@ -43,6 +43,9 @@ namespace ipc {
protocol PTestShellCommand
{
manager PTestShell;
parent:
__delete__(nsString aResponse);
};
} // namespace ipc

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

@ -63,8 +63,7 @@ TestShellChild::AllocPTestShellCommand(const nsString& aCommand)
}
bool
TestShellChild::DeallocPTestShellCommand(PTestShellCommandChild* aCommand,
const nsString& aResponse)
TestShellChild::DeallocPTestShellCommand(PTestShellCommandChild* aCommand)
{
delete aCommand;
return true;
@ -84,5 +83,5 @@ TestShellChild::RecvPTestShellCommandConstructor(PTestShellCommandChild* aActor,
return false;
}
return SendPTestShellCommandDestructor(aActor, response);
return PTestShellCommandChild::Send__delete__(aActor, response);
}

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

@ -64,8 +64,7 @@ public:
const nsString& aCommand);
bool
DeallocPTestShellCommand(PTestShellCommandChild* aCommand,
const nsString& aResponse);
DeallocPTestShellCommand(PTestShellCommandChild* aCommand);
void SetXPCShell(XPCShellEnvironment* aXPCShell) {
mXPCShell = aXPCShell;

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

@ -49,21 +49,18 @@ TestShellParent::AllocPTestShellCommand(const nsString& aCommand)
}
bool
TestShellParent::DeallocPTestShellCommand(PTestShellCommandParent* aActor,
const nsString& aResponse)
TestShellParent::DeallocPTestShellCommand(PTestShellCommandParent* aActor)
{
delete aActor;
return true;
}
bool
TestShellParent::RecvPTestShellCommandDestructor(PTestShellCommandParent* aActor,
const nsString& aResponse)
TestShellParent::CommandDone(TestShellCommandParent* command,
const nsString& aResponse)
{
TestShellCommandParent* command =
reinterpret_cast<TestShellCommandParent*>(aActor);
JSBool ok = command->RunCallback(aResponse);
// XXX what should happen if the callback fails?
/*JSBool ok = */command->RunCallback(aResponse);
command->ReleaseCallback();
return true;

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

@ -1,3 +1,6 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=8 et :
*/
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@ -47,6 +50,23 @@
namespace mozilla {
namespace ipc {
class TestShellCommandParent;
class TestShellParent : public PTestShellParent
{
public:
PTestShellCommandParent*
AllocPTestShellCommand(const nsString& aCommand);
bool
DeallocPTestShellCommand(PTestShellCommandParent* aActor);
bool
CommandDone(TestShellCommandParent* aActor, const nsString& aResponse);
};
class TestShellCommandParent : public PTestShellCommandParent
{
public:
@ -59,25 +79,17 @@ public:
void ReleaseCallback();
protected:
bool Recv__delete__(const nsString& aResponse) {
return static_cast<TestShellParent*>(Manager())->CommandDone(
this, aResponse);
}
private:
JSContext* mCx;
nsAutoJSValHolder mCallback;
};
class TestShellParent : public PTestShellParent
{
public:
PTestShellCommandParent*
AllocPTestShellCommand(const nsString& aCommand);
bool
DeallocPTestShellCommand(PTestShellCommandParent* aActor,
const nsString& aResponse);
bool
RecvPTestShellCommandDestructor(PTestShellCommandParent* aActor,
const nsString& aResponse);
};
} /* namespace ipc */
} /* namespace mozilla */

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

@ -52,8 +52,9 @@ protocol PNecko
manages PHttpChannel;
parent:
__delete__();
PHttpChannel();
~PHttpChannel();
};

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

@ -50,6 +50,8 @@ protocol PHttpChannel
manager PNecko;
parent:
__delete__();
asyncOpen(nsCString uri);
};