Bug 792652 - Move over toplevel shmem code (r=dvander)
☠☠ backed out by d2098e1d1f2d ☠ ☠
authorBill McCloskey <billm@mozilla.com>
Tue, 01 Nov 2016 21:05:38 -0700
changeset 321762 ddd915ab4a483afcbf4deb2913c4e1af5c21a86c
parent 321761 95eff6c45cae4aa5735aba99fbf74e3633c3556b
child 321763 90eaf6aec002136b753bb7f921cce5141dcd0f12
push id21
push usermaklebus@msu.edu
push dateThu, 01 Dec 2016 06:22:08 +0000
reviewersdvander
bugs792652
milestone52.0a1
Bug 792652 - Move over toplevel shmem code (r=dvander)
ipc/glue/ProtocolUtils.cpp
ipc/glue/ProtocolUtils.h
ipc/ipdl/ipdl/lower.py
--- a/ipc/glue/ProtocolUtils.cpp
+++ b/ipc/glue/ProtocolUtils.cpp
@@ -12,16 +12,17 @@
 #endif
 
 #include "mozilla/ipc/ProtocolUtils.h"
 
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/ipc/MessageChannel.h"
 #include "mozilla/ipc/Transport.h"
 #include "mozilla/StaticMutex.h"
+#include "mozilla/Unused.h"
 #include "nsPrintfCString.h"
 
 #if defined(MOZ_SANDBOX) && defined(XP_WIN)
 #define TARGET_SANDBOX_EXPORTS
 #include "mozilla/sandboxTarget.h"
 #endif
 
 #if defined(MOZ_CRASHREPORTER) && defined(XP_WIN)
@@ -506,17 +507,18 @@ IProtocol::DeallocShmem(Shmem& aMem)
   aMem.forget(Shmem::IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead());
   return ok;
 }
 
 IToplevelProtocol::IToplevelProtocol(ProtocolId aProtoId, Side aSide)
  : IProtocol(aSide),
    mProtocolId(aProtoId),
    mOtherPid(mozilla::ipc::kInvalidProcessId),
-   mLastRouteId(mSide == ParentSide : 1 : 0)
+   mLastRouteId(aSide == ParentSide ? 1 : 0),
+   mLastShmemId(aSide == ParentSide ? 1 : 0)
 {
 }
 
 IToplevelProtocol::~IToplevelProtocol()
 {
   if (mTrans) {
     RefPtr<DeleteTask<Transport>> task = new DeleteTask<Transport>(mTrans.release());
     XRE_GetIOMessageLoop()->PostTask(task.forget());
@@ -581,17 +583,17 @@ bool
 IToplevelProtocol::IsOnCxxStack() const
 {
   return GetIPCChannel()->IsOnCxxStack();
 }
 
 int32_t
 IToplevelProtocol::Register(IProtocol* aRouted)
 {
-  int32_t id = mSide == ParentSide ? ++mLastRouteId : --mLastRouteId;
+  int32_t id = GetSide() == ParentSide ? ++mLastRouteId : --mLastRouteId;
   mActorMap.AddWithID(aRouted, id);
   return id;
 }
 
 int32_t
 IToplevelProtocol::RegisterID(IProtocol* aRouted,
                               int32_t aId)
 {
@@ -606,10 +608,113 @@ IToplevelProtocol::Lookup(int32_t aId)
 }
 
 void
 IToplevelProtocol::Unregister(int32_t aId)
 {
   return mActorMap.Remove(aId);
 }
 
+Shmem::SharedMemory*
+IToplevelProtocol::CreateSharedMemory(size_t aSize,
+                                      Shmem::SharedMemory::SharedMemoryType aType,
+                                      bool aUnsafe,
+                                      Shmem::id_t* aId)
+{
+  RefPtr<Shmem::SharedMemory> segment(
+    Shmem::Alloc(Shmem::IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead(), aSize, aType, aUnsafe));
+  if (!segment) {
+    return nullptr;
+  }
+  int32_t id = GetSide() == ParentSide ? ++mLastShmemId : --mLastShmemId;
+  Shmem shmem(
+    Shmem::IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead(),
+    segment.get(),
+    id);
+  Message* descriptor = shmem.ShareTo(
+    Shmem::IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead(), OtherPid(), MSG_ROUTING_CONTROL);
+  if (!descriptor) {
+    return nullptr;
+  }
+  Unused << GetIPCChannel()->Send(descriptor);
+
+  *aId = shmem.Id(Shmem::IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead());
+  Shmem::SharedMemory* rawSegment = segment.get();
+  mShmemMap.AddWithID(segment.forget().take(), *aId);
+  return rawSegment;
+}
+
+Shmem::SharedMemory*
+IToplevelProtocol::LookupSharedMemory(Shmem::id_t aId)
+{
+  return mShmemMap.Lookup(aId);
+}
+
+bool
+IToplevelProtocol::IsTrackingSharedMemory(Shmem::SharedMemory* segment)
+{
+  return mShmemMap.HasData(segment);
+}
+
+bool
+IToplevelProtocol::DestroySharedMemory(Shmem& shmem)
+{
+  Shmem::id_t aId = shmem.Id(Shmem::IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead());
+  Shmem::SharedMemory* segment = LookupSharedMemory(aId);
+  if (!segment) {
+    return false;
+  }
+
+  Message* descriptor = shmem.UnshareFrom(
+    Shmem::IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead(), OtherPid(), MSG_ROUTING_CONTROL);
+
+  mShmemMap.Remove(aId);
+  Shmem::Dealloc(Shmem::IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead(), segment);
+
+  if (!GetIPCChannel()->CanSend()) {
+    delete descriptor;
+    return true;
+  }
+
+  return descriptor && GetIPCChannel()->Send(descriptor);
+}
+
+void
+IToplevelProtocol::DeallocShmems()
+{
+  for (IDMap<SharedMemory>::const_iterator cit = mShmemMap.begin(); cit != mShmemMap.end(); ++cit) {
+    Shmem::Dealloc(Shmem::IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead(), cit->second);
+  }
+  mShmemMap.Clear();
+}
+
+bool
+IToplevelProtocol::ShmemCreated(const Message& aMsg)
+{
+  Shmem::id_t id;
+  RefPtr<Shmem::SharedMemory> rawmem(Shmem::OpenExisting(Shmem::IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead(), aMsg, &id, true));
+  if (!rawmem) {
+    return false;
+  }
+  mShmemMap.AddWithID(rawmem.forget().take(), id);
+  return true;
+}
+
+bool
+IToplevelProtocol::ShmemDestroyed(const Message& aMsg)
+{
+  Shmem::id_t id;
+  PickleIterator iter = PickleIterator(aMsg);
+  if (!IPC::ReadParam(&aMsg, &iter, &id)) {
+    return false;
+  }
+  aMsg.EndRead(iter);
+
+  Shmem::SharedMemory* rawmem = LookupSharedMemory(id);
+  if (rawmem) {
+    mShmemMap.Remove(id);
+    Shmem::Dealloc(Shmem::IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead(), rawmem);
+  }
+  return true;
+}
+
 } // namespace ipc
 } // namespace mozilla
--- a/ipc/glue/ProtocolUtils.h
+++ b/ipc/glue/ProtocolUtils.h
@@ -256,16 +256,27 @@ public:
 
     void SetReplyTimeoutMs(int32_t aTimeoutMs);
 
     virtual int32_t Register(IProtocol*);
     virtual int32_t RegisterID(IProtocol*, int32_t);
     virtual IProtocol* Lookup(int32_t);
     virtual void Unregister(int32_t);
 
+    virtual Shmem::SharedMemory* CreateSharedMemory(
+        size_t, SharedMemory::SharedMemoryType, bool, int32_t*);
+    virtual Shmem::SharedMemory* LookupSharedMemory(int32_t);
+    virtual bool IsTrackingSharedMemory(Shmem::SharedMemory*);
+    virtual bool DestroySharedMemory(Shmem&);
+
+    void DeallocShmems();
+
+    bool ShmemCreated(const Message& aMsg);
+    bool ShmemDestroyed(const Message& aMsg);
+
     virtual bool ShouldContinueFromReplyTimeout() {
         return false;
     }
 
     // WARNING: This function is called with the MessageChannel monitor held.
     virtual void IntentionalCrash() {
         MOZ_CRASH("Intentional IPDL crash");
     }
@@ -325,16 +336,18 @@ public:
     }
 
 private:
     ProtocolId mProtocolId;
     UniquePtr<Transport> mTrans;
     base::ProcessId mOtherPid;
     IDMap<IProtocol> mActorMap;
     int32_t mLastRouteId;
+    IDMap<Shmem::SharedMemory> mShmemMap;
+    Shmem::id_t mLastShmemId;
 };
 
 class IShmemAllocator
 {
 public:
   virtual bool AllocShmem(size_t aSize,
                           mozilla::ipc::SharedMemory::SharedMemoryType aShmType,
                           mozilla::ipc::Shmem* aShmem) = 0;
--- a/ipc/ipdl/ipdl/lower.py
+++ b/ipc/ipdl/ipdl/lower.py
@@ -1213,51 +1213,16 @@ class Protocol(ipdl.ast.Protocol):
         assert self.decl.type.isManagerOf(actortype)
         return ExprVar('mManaged'+ _actorName(actortype.name(), side))
 
     def managedVarType(self, actortype, side, const=0, ref=0):
         assert self.decl.type.isManagerOf(actortype)
         return _cxxManagedContainerType(Type(_actorName(actortype.name(), side)),
                                         const=const, ref=ref)
 
-    # shmem stuff
-    def shmemMapType(self):
-        assert self.decl.type.isToplevel()
-        return Type('IDMap', T=_rawShmemType())
-
-    def shmemIteratorType(self):
-        assert self.decl.type.isToplevel()
-        # XXX breaks abstractions
-        return Type('IDMap<SharedMemory>::const_iterator')
-
-    def shmemMapVar(self):
-        assert self.decl.type.isToplevel()
-        return ExprVar('mShmemMap')
-
-    def lastShmemIdVar(self):
-        assert self.decl.type.isToplevel()
-        return ExprVar('mLastShmemId')
-
-    def shmemIdInit(self, side):
-        assert self.decl.type.isToplevel()
-        # use the same scheme for shmem IDs as actor IDs
-        if side is 'parent':  return _FREED_ACTOR_ID
-        elif side is 'child': return _NULL_ACTOR_ID
-        else: assert 0
-
-    def nextShmemIdExpr(self, side):
-        assert self.decl.type.isToplevel()
-        if side is 'parent':   op = '++'
-        elif side is 'child':  op = '--'
-        return ExprPrefixUnop(self.lastShmemIdVar(), op)
-
-    def removeShmemId(self, idexpr):
-        return ExprCall(ExprSelect(self.shmemMapVar(), '.', 'Remove'),
-                        args=[ idexpr ])
-
     # XXX this is sucky, fix
     def usesShmem(self):
         return _usesShmem(self)
 
     def subtreeUsesShmem(self):
         return _subtreeUsesShmem(self)
 
     @staticmethod
@@ -2902,18 +2867,16 @@ class _GenerateProtocolActorCode(ipdl.as
         side = ExprVar('mozilla::ipc::' + self.side.title() + 'Side')
         if ptype.isToplevel():
             ctor.memberinits = [
                 ExprMemberInit(ExprVar('mozilla::ipc::IToplevelProtocol'),
                                [_protocolId(ptype), side]),
                 ExprMemberInit(p.channelVar(), [
                     ExprCall(ExprVar('ALLOW_THIS_IN_INITIALIZER_LIST'),
                              [ ExprVar.THIS ]) ]),
-                ExprMemberInit(p.lastShmemIdVar(),
-                               [ p.shmemIdInit(self.side) ]),
                 ExprMemberInit(p.stateVar(),
                                [ p.startState() ])
             ]
         else:
             ctor.memberinits = [
                 ExprMemberInit(ExprVar('mozilla::ipc::IProtocol'), [side]),
                 ExprMemberInit(p.idVar(), [ ExprLiteral.ZERO ]),
                 ExprMemberInit(p.stateVar(),
@@ -3279,55 +3242,28 @@ class _GenerateProtocolActorCode(ipdl.as
 
             ])
             deallocsubtree.addstmt(block)
         # don't delete outselves: either the manager will do it, or
         # we're toplevel
         self.cls.addstmts([ deallocsubtree, Whitespace.NL ])
 
         if ptype.isToplevel():
-            ## DeallocShmem():
-            #    for (cit = map.begin(); cit != map.end(); ++cit)
-            #      Dealloc(cit->second)
-            #    map.Clear()
-            deallocshmem = MethodDefn(MethodDecl(deallocshmemvar.name))
-
-            citvar = ExprVar('cit')
-            begin = ExprCall(ExprSelect(p.shmemMapVar(), '.', 'begin'))
-            end = ExprCall(ExprSelect(p.shmemMapVar(), '.', 'end'))
-            shmem = ExprSelect(citvar, '->', 'second')
-            foreachdealloc = StmtFor(
-                Param(p.shmemIteratorType(), citvar.name, begin),
-                ExprBinary(citvar, '!=', end),
-                ExprPrefixUnop(citvar, '++'))
-            foreachdealloc.addstmt(StmtExpr(_shmemDealloc(shmem)))
-
-            deallocshmem.addstmts([
-                foreachdealloc,
-                StmtExpr(ExprCall(ExprSelect(p.shmemMapVar(), '.', 'Clear')))
-            ])
-            self.cls.addstmts([ deallocshmem, Whitespace.NL ])
-
             deallocself = MethodDefn(MethodDecl(deallocselfvar.name, virtual=1))
             self.cls.addstmts([ deallocself, Whitespace.NL ])
 
         self.implementPickling()
 
         ## private members
         if ptype.isToplevel():
             self.cls.addstmt(StmtDecl(Decl(p.channelType(), 'mChannel')))
         elif ptype.isManaged():
             self.cls.addstmts([
                 StmtDecl(Decl(_actorIdType(), p.idVar().name))
             ])
-        if p.decl.type.isToplevel():
-            self.cls.addstmts([
-                StmtDecl(Decl(p.shmemMapType(), p.shmemMapVar().name)),
-                StmtDecl(Decl(_shmemIdType(), p.lastShmemIdVar().name))
-            ])
 
         self.cls.addstmt(StmtDecl(Decl(Type('State'), p.stateVar().name)))
 
         for managed in ptype.manages:
             self.cls.addstmts([
                 StmtDecl(Decl(
                     p.managedVarType(managed, self.side),
                     p.managedVar(managed, self.side).name)) ])
@@ -3345,173 +3281,34 @@ class _GenerateProtocolActorCode(ipdl.as
         sourcevar = ExprVar('aSource')
         ivar = ExprVar('i')
         kidsvar = ExprVar('kids')
         ithkid = ExprIndex(kidsvar, ivar)
 
         methods = []
 
         if p.decl.type.isToplevel():
-            createshmem = MethodDefn(MethodDecl(
-                p.createSharedMemory().name,
-                ret=_rawShmemType(ptr=1),
-                params=[ Decl(Type.SIZE, sizevar.name),
-                         Decl(_shmemTypeType(), typevar.name),
-                         Decl(Type.BOOL, unsafevar.name),
-                         Decl(_shmemIdType(ptr=1), idvar.name) ],
-                virtual=1))
-            lookupshmem = MethodDefn(MethodDecl(
-                p.lookupSharedMemory().name,
-                ret=_rawShmemType(ptr=1),
-                params=[ Decl(_shmemIdType(), idvar.name) ],
-                virtual=1))
-            destroyshmem = MethodDefn(MethodDecl(
-                p.destroySharedMemory().name,
-                ret=Type.BOOL,
-                params=[ Decl(_shmemType(ref=1), shmemvar.name) ],
-                virtual=1))
-            istracking = MethodDefn(MethodDecl(
-                p.isTrackingSharedMemory().name,
-                ret=Type.BOOL,
-                params=[ Decl(_rawShmemType(ptr=1), rawvar.name) ],
-                virtual=1))
-
             getchannel = MethodDefn(MethodDecl(
                 p.getChannelMethod().name,
                 ret=Type('MessageChannel', ptr=1),
                 virtual=1))
             getchannel.addstmt(StmtReturn(ExprAddrOf(p.channelVar())))
 
             getchannelconst = MethodDefn(MethodDecl(
                 p.getChannelMethod().name,
                 ret=Type('MessageChannel', ptr=1, const=1),
                 virtual=1, const=1))
             getchannelconst.addstmt(StmtReturn(ExprAddrOf(p.channelVar())))
 
-            methods += [ createshmem,
-                         lookupshmem,
-                         istracking,
-                         destroyshmem,
-                         getchannel,
+            methods += [ getchannel,
                          getchannelconst ]
 
         if p.decl.type.isToplevel():
             tmpvar = ExprVar('tmp')
 
-            # SharedMemory* CreateSharedMemory(size_t aSize, Type aType, bool aUnsafe, id_t* aId):
-            #   RefPtr<SharedMemory> segment(Shmem::Alloc(aSize, aType, aUnsafe));
-            #   if (!segment)
-            #     return nullptr;
-            #   Shmem shmem(segment.get(), [nextshmemid]);
-            #   Message descriptor = shmem.ShareTo(subprocess, mId, descriptor);
-            #   if (!descriptor)
-            #     return nullptr;
-            #   mChannel.Send(descriptor);
-            #   *aId = shmem.Id();
-            #   SharedMemory* rawSegment = segment.get();
-            #   mShmemMap.Add(segment.forget().take(), *aId);
-            #   return rawSegment;
-            createshmem.addstmt(StmtDecl(
-                Decl(_refptr(_rawShmemType()), rawvar.name),
-                initargs=[ _shmemAlloc(sizevar, typevar, unsafevar) ]))
-            failif = StmtIf(ExprNot(rawvar))
-            failif.addifstmt(StmtReturn(ExprLiteral.NULL))
-            createshmem.addstmt(failif)
-
-            descriptorvar = ExprVar('descriptor')
-            createshmem.addstmts([
-                StmtDecl(
-                    Decl(_shmemType(), shmemvar.name),
-                    initargs=[ _shmemBackstagePass(),
-                               _refptrGet(rawvar),
-                               p.nextShmemIdExpr(self.side) ]),
-                StmtDecl(Decl(Type('Message', ptr=1), descriptorvar.name),
-                         init=_shmemShareTo(shmemvar,
-                                            p.callOtherPid(),
-                                            p.routingId()))
-            ])
-            failif = StmtIf(ExprNot(descriptorvar))
-            failif.addifstmt(StmtReturn(ExprLiteral.NULL))
-            createshmem.addstmt(failif)
-
-            failif = StmtIf(ExprNot(ExprCall(
-                ExprSelect(p.callGetChannel(), '->', 'Send'),
-                args=[ descriptorvar ])))
-            createshmem.addstmt(failif)
-
-            rawsegmentvar = ExprVar('rawSegment')
-            createshmem.addstmts([
-                StmtExpr(ExprAssn(ExprDeref(idvar), _shmemId(shmemvar))),
-                StmtDecl(Decl(_rawShmemType(ptr=1), rawsegmentvar.name),
-                         init=_refptrGet(rawvar)),
-                StmtExpr(ExprCall(
-                    ExprSelect(p.shmemMapVar(), '.', 'AddWithID'),
-                    args=[ _refptrTake(_refptrForget(rawvar)), ExprDeref(idvar) ])),
-                StmtReturn(rawsegmentvar)
-            ])
-
-            # SharedMemory* Lookup(id)
-            lookupshmem.addstmt(StmtReturn(ExprCall(
-                ExprSelect(p.shmemMapVar(), '.', 'Lookup'),
-                args=[ idvar ])))
-
-            # bool IsTrackingSharedMemory(mem)
-            istracking.addstmt(StmtReturn(ExprCall(
-                ExprSelect(p.shmemMapVar(), '.', 'HasData'),
-                args=[ rawvar ])))
-
-            # bool DestroySharedMemory(shmem):
-            #   id = shmem.Id()
-            #   SharedMemory* rawmem = Lookup(id)
-            #   if (!rawmem)
-            #     return false;
-            #   Message descriptor = UnShare(subprocess, mId, descriptor)
-            #   mShmemMap.Remove(id)
-            #   Shmem::Dealloc(rawmem)
-            #   if (!mChannel.CanSend()) {
-            #     delete descriptor;
-            #     return true;
-            #   }
-            #   return descriptor && Send(descriptor)
-            destroyshmem.addstmts([
-                StmtDecl(Decl(_shmemIdType(), idvar.name),
-                         init=_shmemId(shmemvar)),
-                StmtDecl(Decl(_rawShmemType(ptr=1), rawvar.name),
-                         init=_lookupShmem(idvar))
-            ])
-
-            failif = StmtIf(ExprNot(rawvar))
-            failif.addifstmt(StmtReturn.FALSE)
-            cansend = ExprCall(ExprSelect(p.channelVar(), '.', 'CanSend'), [])
-            returnif = StmtIf(ExprNot(cansend))
-            returnif.addifstmts([
-                    StmtExpr(ExprDelete(descriptorvar)),
-                    StmtReturn.TRUE])
-            destroyshmem.addstmts([
-                failif,
-                Whitespace.NL,
-                StmtDecl(Decl(Type('Message', ptr=1), descriptorvar.name),
-                         init=_shmemUnshareFrom(
-                             shmemvar,
-                             p.callOtherPid(),
-                             p.routingId())),
-                Whitespace.NL,
-                StmtExpr(p.removeShmemId(idvar)),
-                StmtExpr(_shmemDealloc(rawvar)),
-                Whitespace.NL,
-                returnif,
-                Whitespace.NL,
-                StmtReturn(ExprBinary(
-                    descriptorvar, '&&',
-                    ExprCall(
-                        ExprSelect(p.channelVar(), p.channelSel(), 'Send'),
-                        args=[ descriptorvar ])))
-            ])
-
-
             # "private" message that passes shmem mappings from one process
             # to the other
             if p.subtreeUsesShmem():
                 self.asyncSwitch.addcase(
                     CaseLabel('SHMEM_CREATED_MESSAGE_TYPE'),
                     self.genShmemCreatedHandler())
                 self.asyncSwitch.addcase(
                     CaseLabel('SHMEM_DESTROYED_MESSAGE_TYPE'),
@@ -3588,80 +3385,37 @@ class _GenerateProtocolActorCode(ipdl.as
         return methods + [removemanagee, Whitespace.NL]
 
     def genShmemCreatedHandler(self):
         p = self.protocol
         assert p.decl.type.isToplevel()
 
         case = StmtBlock()
 
-        rawvar = ExprVar('rawmem')
-        idvar = ExprVar('id')
+        ifstmt = StmtIf(ExprNot(ExprCall(ExprVar('ShmemCreated'), args=[self.msgvar])))
         case.addstmts([
-            StmtDecl(Decl(_shmemIdType(), idvar.name)),
-            StmtDecl(Decl(_refptr(_rawShmemType()), rawvar.name),
-                     initargs=[ _shmemOpenExisting(self.msgvar,
-                                                   ExprAddrOf(idvar)) ])
-        ])
-        failif = StmtIf(ExprNot(rawvar))
-        failif.addifstmt(StmtReturn(_Result.PayloadError))
-
-        case.addstmts([
-            failif,
-            StmtExpr(ExprCall(
-                ExprSelect(p.shmemMapVar(), '.', 'AddWithID'),
-                args=[ _refptrTake(_refptrForget(rawvar)), idvar ])),
-            Whitespace.NL,
+            ifstmt,
             StmtReturn(_Result.Processed)
         ])
+        ifstmt.addifstmt(StmtReturn(_Result.PayloadError))
 
         return case
 
     def genShmemDestroyedHandler(self):
         p = self.protocol
         assert p.decl.type.isToplevel()
 
         case = StmtBlock()
 
-        rawvar = ExprVar('rawmem')
-        idvar = ExprVar('id')
-        itervar = ExprVar('iter')
-        case.addstmts([
-            StmtDecl(Decl(_shmemIdType(), idvar.name)),
-            StmtDecl(Decl(_iterType(ptr=0), itervar.name), init=ExprCall(ExprVar('PickleIterator'),
-                                                                         args=[ self.msgvar ]))
-        ])
-
-        failif = StmtIf(ExprNot(
-            ExprCall(ExprVar('IPC::ReadParam'),
-                     args=[ ExprAddrOf(self.msgvar), ExprAddrOf(itervar),
-                            ExprAddrOf(idvar) ])))
-        failif.addifstmt(StmtReturn(_Result.PayloadError))
-
+        ifstmt = StmtIf(ExprNot(ExprCall(ExprVar('ShmemDestroyed'), args=[self.msgvar])))
         case.addstmts([
-            failif,
-            StmtExpr(ExprCall(ExprSelect(self.msgvar, '.', 'EndRead'),
-                              args=[ itervar ])),
-            Whitespace.NL,
-            StmtDecl(Decl(_rawShmemType(ptr=1), rawvar.name),
-                     init=ExprCall(p.lookupSharedMemory(), args=[ idvar ]))
-        ])
-
-        # Here we don't return an error if we failed to look the shmem up. This
-        # is because we don't have a way to know if it is because we failed to
-        # map the shmem or if the id is wrong. In the latter case it would be
-        # better to catch the error but the former case is legit...
-        lookupif = StmtIf(rawvar)
-        lookupif.addifstmt(StmtExpr(p.removeShmemId(idvar)))
-        lookupif.addifstmt(StmtExpr(_shmemDealloc(rawvar)))
-
-        case.addstmts([
-            lookupif,
+            ifstmt,
             StmtReturn(_Result.Processed)
         ])
+        ifstmt.addifstmt(StmtReturn(_Result.PayloadError))
 
         return case
 
 
     def makeChannelOpenedHandlers(self, actors):
         handlers = StmtBlock()
 
         # unpack the transport descriptor et al.