mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 559898: Allow (sub-)protocols to manage themselves. r=bsmedberg
This commit is contained in:
parent
867c2c58be
commit
b330eeb701
@ -1309,9 +1309,12 @@ def _usesShmem(p):
|
||||
def _subtreeUsesShmem(p):
|
||||
if _usesShmem(p):
|
||||
return True
|
||||
for mgd in p.decl.type.manages:
|
||||
if _subtreeUsesShmem(mgd._p):
|
||||
return True
|
||||
|
||||
ptype = p.decl.type
|
||||
for mgd in ptype.manages:
|
||||
if ptype is not mgd:
|
||||
if _subtreeUsesShmem(mgd._p):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
@ -2419,7 +2422,8 @@ class _FindFriends(ipdl.ast.Visitor):
|
||||
# don't want to |friend| ourself!
|
||||
self.visit(ptype)
|
||||
for mtype in ptype.manages:
|
||||
self.walkDownTheProtocolTree(mtype)
|
||||
if mtype is not ptype:
|
||||
self.walkDownTheProtocolTree(mtype)
|
||||
|
||||
def visit(self, ptype):
|
||||
# |vtype| is the type currently being visited
|
||||
@ -2623,6 +2627,9 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
||||
# |friend| managed actors so that they can call our Dealloc*()
|
||||
friends.update(ptype.manages)
|
||||
|
||||
# don't friend ourself if we're a self-managed protocol
|
||||
friends.discard(ptype)
|
||||
|
||||
for friend in friends:
|
||||
self.hdrfile.addthings([
|
||||
Whitespace.NL,
|
||||
@ -2664,7 +2671,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
||||
|
||||
for md in p.messageDecls:
|
||||
managed = md.decl.type.constructedType()
|
||||
if not ptype.isManagerOf(managed):
|
||||
if not ptype.isManagerOf(managed) or md.decl.type.isDtor():
|
||||
continue
|
||||
|
||||
# add the Alloc/Dealloc interface for managed actors
|
||||
|
@ -258,7 +258,8 @@ class ProtocolType(IPDLType):
|
||||
if self.isToplevel():
|
||||
return self
|
||||
for mgr in self.managers:
|
||||
return mgr.toplevel()
|
||||
if mgr is not self:
|
||||
return mgr.toplevel()
|
||||
|
||||
def isManagerOf(self, pt):
|
||||
for managed in self.manages:
|
||||
@ -267,7 +268,7 @@ class ProtocolType(IPDLType):
|
||||
return False
|
||||
def isManagedBy(self, pt):
|
||||
return pt in self.managers
|
||||
|
||||
|
||||
def isManager(self):
|
||||
return len(self.manages) > 0
|
||||
def isManaged(self):
|
||||
@ -275,6 +276,10 @@ class ProtocolType(IPDLType):
|
||||
def isToplevel(self):
|
||||
return not self.isManaged()
|
||||
|
||||
def manager(self):
|
||||
assert 1 == len(self.managers)
|
||||
for mgr in self.managers: return mgr
|
||||
|
||||
class ActorType(IPDLType):
|
||||
def __init__(self, protocol, state=None, nullable=0):
|
||||
self.protocol = protocol
|
||||
@ -971,7 +976,7 @@ class CheckTypes(TcheckVisitor):
|
||||
|
||||
# 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():
|
||||
if not ptype.isToplevel():
|
||||
for md in p.messageDecls:
|
||||
if _DELETE_MSG == md.name: break
|
||||
else:
|
||||
@ -980,6 +985,12 @@ class CheckTypes(TcheckVisitor):
|
||||
"managed protocol `%s' requires a `delete()' message to be declared",
|
||||
p.name)
|
||||
|
||||
if 1 == len(ptype.managers) and ptype is ptype.manager():
|
||||
self.error(
|
||||
p.decl.loc,
|
||||
"top-level protocol `%s' cannot manage itself",
|
||||
p.name)
|
||||
|
||||
return Visitor.visitProtocol(self, p)
|
||||
|
||||
|
||||
|
@ -72,6 +72,7 @@ IPDLTESTS = \
|
||||
TestRPCShutdownRace \
|
||||
TestRacyRPCReplies \
|
||||
TestSanity \
|
||||
TestSelfManageRoot \
|
||||
TestShmem \
|
||||
TestShutdown \
|
||||
TestStackHooks \
|
||||
|
24
ipc/ipdl/test/cxx/PTestSelfManage.ipdl
Normal file
24
ipc/ipdl/test/cxx/PTestSelfManage.ipdl
Normal file
@ -0,0 +1,24 @@
|
||||
include protocol PTestSelfManageRoot;
|
||||
|
||||
namespace mozilla {
|
||||
namespace _ipdltest {
|
||||
|
||||
|
||||
protocol PTestSelfManage {
|
||||
manager PTestSelfManageRoot or PTestSelfManage;
|
||||
manages PTestSelfManage;
|
||||
|
||||
child:
|
||||
PTestSelfManage();
|
||||
__delete__();
|
||||
|
||||
state LIVE:
|
||||
send PTestSelfManage goto DEAD;
|
||||
|
||||
state DEAD:
|
||||
send __delete__;
|
||||
};
|
||||
|
||||
|
||||
} // namespace mozilla
|
||||
} // namespace _ipdltest
|
23
ipc/ipdl/test/cxx/PTestSelfManageRoot.ipdl
Normal file
23
ipc/ipdl/test/cxx/PTestSelfManageRoot.ipdl
Normal file
@ -0,0 +1,23 @@
|
||||
include protocol PTestSelfManage;
|
||||
|
||||
namespace mozilla {
|
||||
namespace _ipdltest {
|
||||
|
||||
|
||||
protocol PTestSelfManageRoot {
|
||||
manages PTestSelfManage;
|
||||
|
||||
child:
|
||||
PTestSelfManage();
|
||||
__delete__();
|
||||
|
||||
state LIVE:
|
||||
send PTestSelfManage goto DEAD;
|
||||
|
||||
state DEAD:
|
||||
send __delete__;
|
||||
};
|
||||
|
||||
|
||||
} // namespace mozilla
|
||||
} // namespace _ipdltest
|
63
ipc/ipdl/test/cxx/TestSelfManageRoot.cpp
Normal file
63
ipc/ipdl/test/cxx/TestSelfManageRoot.cpp
Normal file
@ -0,0 +1,63 @@
|
||||
#include "TestSelfManageRoot.h"
|
||||
|
||||
#include "IPDLUnitTests.h" // fail etc.
|
||||
|
||||
#define ASSERT(c) \
|
||||
do { \
|
||||
if (!(c)) \
|
||||
fail(#c); \
|
||||
} while (0)
|
||||
|
||||
namespace mozilla {
|
||||
namespace _ipdltest {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// parent
|
||||
|
||||
void
|
||||
TestSelfManageRootParent::Main()
|
||||
{
|
||||
TestSelfManageParent* a =
|
||||
static_cast<TestSelfManageParent*>(SendPTestSelfManageConstructor());
|
||||
if (!a)
|
||||
fail("constructing PTestSelfManage");
|
||||
|
||||
ASSERT(1 == ManagedPTestSelfManageParent().Length());
|
||||
|
||||
TestSelfManageParent* aa =
|
||||
static_cast<TestSelfManageParent*>(a->SendPTestSelfManageConstructor());
|
||||
if (!aa)
|
||||
fail("constructing PTestSelfManage");
|
||||
|
||||
ASSERT(1 == ManagedPTestSelfManageParent().Length() &&
|
||||
1 == a->ManagedPTestSelfManageParent().Length());
|
||||
|
||||
if (!PTestSelfManageParent::Send__delete__(aa))
|
||||
fail("destroying PTestSelfManage");
|
||||
ASSERT(Deletion == aa->mWhy &&
|
||||
1 == ManagedPTestSelfManageParent().Length() &&
|
||||
0 == a->ManagedPTestSelfManageParent().Length());
|
||||
delete aa;
|
||||
|
||||
aa =
|
||||
static_cast<TestSelfManageParent*>(a->SendPTestSelfManageConstructor());
|
||||
if (!aa)
|
||||
fail("constructing PTestSelfManage");
|
||||
|
||||
ASSERT(1 == ManagedPTestSelfManageParent().Length() &&
|
||||
1 == a->ManagedPTestSelfManageParent().Length());
|
||||
|
||||
if (!PTestSelfManageParent::Send__delete__(a))
|
||||
fail("destroying PTestSelfManage");
|
||||
ASSERT(Deletion == a->mWhy &&
|
||||
AncestorDeletion == aa->mWhy &&
|
||||
0 == ManagedPTestSelfManageParent().Length() &&
|
||||
0 == a->ManagedPTestSelfManageParent().Length());
|
||||
delete a;
|
||||
delete aa;
|
||||
|
||||
Close();
|
||||
}
|
||||
|
||||
} // namespace _ipdltest
|
||||
} // namespace mozilla
|
150
ipc/ipdl/test/cxx/TestSelfManageRoot.h
Normal file
150
ipc/ipdl/test/cxx/TestSelfManageRoot.h
Normal file
@ -0,0 +1,150 @@
|
||||
#ifndef mozilla__ipdltest_TestSelfManageRoot_h
|
||||
#define mozilla__ipdltest_TestSelfManageRoot_h 1
|
||||
|
||||
#include "mozilla/_ipdltest/IPDLUnitTests.h"
|
||||
|
||||
#include "mozilla/_ipdltest/PTestSelfManageRootParent.h"
|
||||
#include "mozilla/_ipdltest/PTestSelfManageRootChild.h"
|
||||
#include "mozilla/_ipdltest/PTestSelfManageParent.h"
|
||||
#include "mozilla/_ipdltest/PTestSelfManageChild.h"
|
||||
|
||||
|
||||
namespace mozilla {
|
||||
namespace _ipdltest {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Parent side
|
||||
|
||||
class TestSelfManageParent :
|
||||
public PTestSelfManageParent
|
||||
{
|
||||
public:
|
||||
TestSelfManageParent() {
|
||||
MOZ_COUNT_CTOR(TestSelfManageParent);
|
||||
}
|
||||
virtual ~TestSelfManageParent() {
|
||||
MOZ_COUNT_DTOR(TestSelfManageParent);
|
||||
}
|
||||
|
||||
ActorDestroyReason mWhy;
|
||||
|
||||
protected:
|
||||
NS_OVERRIDE
|
||||
virtual PTestSelfManageParent* AllocPTestSelfManage() {
|
||||
return new TestSelfManageParent();
|
||||
}
|
||||
|
||||
NS_OVERRIDE
|
||||
virtual bool DeallocPTestSelfManage(PTestSelfManageParent* a) {
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_OVERRIDE
|
||||
virtual void ActorDestroy(ActorDestroyReason why) {
|
||||
mWhy = why;
|
||||
}
|
||||
};
|
||||
|
||||
class TestSelfManageRootParent :
|
||||
public PTestSelfManageRootParent
|
||||
{
|
||||
public:
|
||||
TestSelfManageRootParent() {
|
||||
MOZ_COUNT_CTOR(TestSelfManageRootParent);
|
||||
}
|
||||
virtual ~TestSelfManageRootParent() {
|
||||
MOZ_COUNT_DTOR(TestSelfManageRootParent);
|
||||
}
|
||||
|
||||
void Main();
|
||||
|
||||
protected:
|
||||
NS_OVERRIDE
|
||||
virtual PTestSelfManageParent* AllocPTestSelfManage() {
|
||||
return new TestSelfManageParent();
|
||||
}
|
||||
|
||||
NS_OVERRIDE
|
||||
virtual bool DeallocPTestSelfManage(PTestSelfManageParent* a) {
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_OVERRIDE
|
||||
virtual void ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
if (NormalShutdown != why)
|
||||
fail("unexpected destruction!");
|
||||
passed("ok");
|
||||
QuitParent();
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Child side
|
||||
|
||||
class TestSelfManageChild :
|
||||
public PTestSelfManageChild
|
||||
{
|
||||
public:
|
||||
TestSelfManageChild() {
|
||||
MOZ_COUNT_CTOR(TestSelfManageChild);
|
||||
}
|
||||
virtual ~TestSelfManageChild() {
|
||||
MOZ_COUNT_DTOR(TestSelfManageChild);
|
||||
}
|
||||
|
||||
protected:
|
||||
NS_OVERRIDE
|
||||
virtual PTestSelfManageChild* AllocPTestSelfManage() {
|
||||
return new TestSelfManageChild();
|
||||
}
|
||||
|
||||
NS_OVERRIDE
|
||||
virtual bool DeallocPTestSelfManage(PTestSelfManageChild* a) {
|
||||
delete a;
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_OVERRIDE
|
||||
virtual void ActorDestroy(ActorDestroyReason why) { }
|
||||
};
|
||||
|
||||
class TestSelfManageRootChild :
|
||||
public PTestSelfManageRootChild
|
||||
{
|
||||
public:
|
||||
TestSelfManageRootChild() {
|
||||
MOZ_COUNT_CTOR(TestSelfManageRootChild);
|
||||
}
|
||||
virtual ~TestSelfManageRootChild() {
|
||||
MOZ_COUNT_DTOR(TestSelfManageRootChild);
|
||||
}
|
||||
|
||||
void Main();
|
||||
|
||||
protected:
|
||||
NS_OVERRIDE
|
||||
virtual PTestSelfManageChild* AllocPTestSelfManage() {
|
||||
return new TestSelfManageChild();
|
||||
}
|
||||
|
||||
NS_OVERRIDE
|
||||
virtual bool DeallocPTestSelfManage(PTestSelfManageChild* a) {
|
||||
delete a;
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_OVERRIDE
|
||||
virtual void ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
if (NormalShutdown != why)
|
||||
fail("unexpected destruction!");
|
||||
QuitChild();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace _ipdltest
|
||||
} // namespace mozilla
|
||||
|
||||
|
||||
#endif // ifndef mozilla__ipdltest_TestSelfManageRoot_h
|
@ -20,6 +20,8 @@ IPDLSRCS = \
|
||||
PTestRPCRaces.ipdl \
|
||||
PTestRPCShutdownRace.ipdl \
|
||||
PTestSanity.ipdl \
|
||||
PTestSelfManage.ipdl \
|
||||
PTestSelfManageRoot.ipdl \
|
||||
PTestShmem.ipdl \
|
||||
PTestShutdown.ipdl \
|
||||
PTestShutdownSub.ipdl \
|
||||
|
8
ipc/ipdl/test/ipdl/error/manageSelfToplevel.ipdl
Normal file
8
ipc/ipdl/test/ipdl/error/manageSelfToplevel.ipdl
Normal file
@ -0,0 +1,8 @@
|
||||
protocol manageSelfToplevel {
|
||||
manager manageSelfToplevel;
|
||||
manages manageSelfToplevel;
|
||||
|
||||
child:
|
||||
manageSelfToplevel();
|
||||
__delete__();
|
||||
};
|
10
ipc/ipdl/test/ipdl/ok/manageSelf.ipdl
Normal file
10
ipc/ipdl/test/ipdl/ok/manageSelf.ipdl
Normal file
@ -0,0 +1,10 @@
|
||||
include protocol manageSelf_Toplevel;
|
||||
|
||||
protocol manageSelf {
|
||||
manager manageSelf_Toplevel or manageSelf;
|
||||
manages manageSelf;
|
||||
|
||||
child:
|
||||
manageSelf();
|
||||
__delete__();
|
||||
};
|
9
ipc/ipdl/test/ipdl/ok/manageSelf_Toplevel.ipdl
Normal file
9
ipc/ipdl/test/ipdl/ok/manageSelf_Toplevel.ipdl
Normal file
@ -0,0 +1,9 @@
|
||||
include protocol manageSelf;
|
||||
|
||||
protocol manageSelf_Toplevel {
|
||||
manages manageSelf;
|
||||
|
||||
child:
|
||||
manageSelf();
|
||||
__delete__();
|
||||
};
|
Loading…
Reference in New Issue
Block a user