LCOV - app.info - ipc/glue/Shmem.cpp

LCOV - code coverage report
| Current view: | directory - ipc/glue - Shmem.cpp (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 198 | 0 | 0.0 %
| Date: | 2012-04-21 | Functions: | 26 | 0 | 0.0 %

           1                 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
           2                 :  * vim: sw=2 ts=8 et :
           3                 :  */
           4                 : /* ***** BEGIN LICENSE BLOCK *****
           5                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           6                 :  *
           7                 :  * The contents of this file are subject to the Mozilla Public License Version
           8                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           9                 :  * the License. You may obtain a copy of the License at
          10                 :  * http://www.mozilla.org/MPL/
          11                 :  *
          12                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          13                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          14                 :  * for the specific language governing rights and limitations under the
          15                 :  * License.
          16                 :  *
          17                 :  * The Original Code is Mozilla IPC.
          18                 :  *
          19                 :  * The Initial Developer of the Original Code is
          20                 :  *   The Mozilla Foundation
          21                 :  * Portions created by the Initial Developer are Copyright (C) 2009
          22                 :  * the Initial Developer. All Rights Reserved.
          23                 :  *
          24                 :  * Contributor(s):
          25                 :  *   Chris Jones <jones.chris.g@gmail.com>
          26                 :  *
          27                 :  * Alternatively, the contents of this file may be used under the terms of
          28                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
          29                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          30                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          31                 :  * of those above. If you wish to allow use of your version of this file only
          32                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          33                 :  * use your version of this file under the terms of the MPL, indicate your
          34                 :  * decision by deleting the provisions above and replace them with the notice
          35                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          36                 :  * the provisions above, a recipient may use your version of this file under
          37                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          38                 :  *
          39                 :  * ***** END LICENSE BLOCK ***** */
          40                 :
          41                 : #include "Shmem.h"
          42                 :
          43                 : #include "ProtocolUtils.h"
          44                 : #include "SharedMemoryBasic.h"
          45                 : #include "SharedMemorySysV.h"
          46                 :
          47                 : #include "nsAutoPtr.h"
          48                 : #include "mozilla/unused.h"
          49                 :
          50                 :
          51                 : namespace mozilla {
          52                 : namespace ipc {
          53                 :
          54                 : class ShmemCreated : public IPC::Message
          55               0 : {
          56                 : private:
          57                 :   typedef Shmem::id_t id_t;
          58                 :
          59                 : public:
          60               0 :   ShmemCreated(int32 routingId,
          61                 :                const id_t& aIPDLId,
          62                 :                const size_t& aSize,
          63                 :                const SharedMemoryBasic::Handle& aHandle) :
          64               0 :     IPC::Message(routingId, SHMEM_CREATED_MESSAGE_TYPE, PRIORITY_NORMAL)
          65                 :   {
          66               0 :     IPC::WriteParam(this, aIPDLId);
          67               0 :     IPC::WriteParam(this, aSize);
          68               0 :     IPC::WriteParam(this, int32(SharedMemory::TYPE_BASIC)),
          69               0 :     IPC::WriteParam(this, aHandle);
          70               0 :   }
          71                 :
          72                 :   // Instead of a single Read() function, we have ReadInfo() and
          73                 :   // ReadHandle().  The reason is that the handle type is specific to
          74                 :   // the shmem type.  These functions should only be called in the
          75                 :   // order ReadInfo(); ReadHandle();, and only once each.
          76                 :
          77                 :   static bool
          78               0 :   ReadInfo(const Message* msg, void** iter,
          79                 :            id_t* aIPDLId,
          80                 :            size_t* aSize,
          81                 :            SharedMemory::SharedMemoryType* aType)
          82                 :   {
          83               0 :     if (!IPC::ReadParam(msg, iter, aIPDLId) ||
          84               0 :         !IPC::ReadParam(msg, iter, aSize) ||
          85               0 :         !IPC::ReadParam(msg, iter, reinterpret_cast<int32*>(aType)))
          86               0 :       return false;
          87               0 :     return true;
          88                 :   }
          89                 :
          90                 :   static bool
          91               0 :   ReadHandle(const Message* msg, void** iter,
          92                 :              SharedMemoryBasic::Handle* aHandle)
          93                 :   {
          94               0 :     if (!IPC::ReadParam(msg, iter, aHandle))
          95               0 :       return false;
          96               0 :     msg->EndRead(*iter);
          97               0 :     return true;
          98                 :   }
          99                 :
         100                 : #ifdef MOZ_HAVE_SHAREDMEMORYSYSV
         101               0 :   ShmemCreated(int32 routingId,
         102                 :                const id_t& aIPDLId,
         103                 :                const size_t& aSize,
         104                 :                const SharedMemorySysV::Handle& aHandle) :
         105               0 :     IPC::Message(routingId, SHMEM_CREATED_MESSAGE_TYPE, PRIORITY_NORMAL)
         106                 :   {
         107               0 :     IPC::WriteParam(this, aIPDLId);
         108               0 :     IPC::WriteParam(this, aSize);
         109               0 :     IPC::WriteParam(this, int32(SharedMemory::TYPE_SYSV)),
         110               0 :     IPC::WriteParam(this, aHandle);
         111               0 :   }
         112                 :
         113                 :   static bool
         114               0 :   ReadHandle(const Message* msg, void** iter,
         115                 :              SharedMemorySysV::Handle* aHandle)
         116                 :   {
         117               0 :     if (!IPC::ReadParam(msg, iter, aHandle))
         118               0 :       return false;
         119               0 :     msg->EndRead(*iter);
         120               0 :     return true;
         121                 :   }
         122                 : #endif
         123                 :
         124                 :   void Log(const std::string& aPrefix,
         125                 :            FILE* aOutf) const
         126                 :   {
         127                 :     fputs("(special ShmemCreated msg)", aOutf);
         128                 :   }
         129                 : };
         130                 :
         131                 : class ShmemDestroyed : public IPC::Message
         132               0 : {
         133                 : private:
         134                 :   typedef Shmem::id_t id_t;
         135                 :
         136                 : public:
         137               0 :   ShmemDestroyed(int32 routingId,
         138                 :                  const id_t& aIPDLId) :
         139               0 :     IPC::Message(routingId, SHMEM_DESTROYED_MESSAGE_TYPE, PRIORITY_NORMAL)
         140                 :   {
         141               0 :     IPC::WriteParam(this, aIPDLId);
         142               0 :   }
         143                 : };
         144                 :
         145                 :
         146                 : #ifdef MOZ_HAVE_SHAREDMEMORYSYSV
         147                 : static Shmem::SharedMemory*
         148               0 : CreateSegment(size_t aNBytes, SharedMemorySysV::Handle aHandle)
         149                 : {
         150               0 :   nsAutoPtr<SharedMemory> segment;
         151                 :
         152               0 :   if (SharedMemorySysV::IsHandleValid(aHandle)) {
         153               0 :     segment = new SharedMemorySysV(aHandle);
         154                 :   }
         155                 :   else {
         156               0 :     segment = new SharedMemorySysV();
         157                 :
         158               0 :     if (!segment->Create(aNBytes))
         159               0 :       return 0;
         160                 :   }
         161               0 :   if (!segment->Map(aNBytes))
         162               0 :     return 0;
         163                 :
         164               0 :   segment->AddRef();
         165               0 :   return segment.forget();
         166                 : }
         167                 : #endif
         168                 :
         169                 : static Shmem::SharedMemory*
         170               0 : CreateSegment(size_t aNBytes, SharedMemoryBasic::Handle aHandle)
         171                 : {
         172               0 :   nsAutoPtr<SharedMemory> segment;
         173                 :
         174               0 :   if (SharedMemoryBasic::IsHandleValid(aHandle)) {
         175               0 :     segment = new SharedMemoryBasic(aHandle);
         176                 :   }
         177                 :   else {
         178               0 :     segment = new SharedMemoryBasic();
         179                 :
         180               0 :     if (!segment->Create(aNBytes))
         181               0 :       return 0;
         182                 :   }
         183               0 :   if (!segment->Map(aNBytes))
         184               0 :     return 0;
         185                 :
         186               0 :   segment->AddRef();
         187               0 :   return segment.forget();
         188                 : }
         189                 :
         190                 : static void
         191               0 : DestroySegment(SharedMemory* aSegment)
         192                 : {
         193                 :   // the SharedMemory dtor closes and unmaps the actual OS shmem segment
         194               0 :   if (aSegment)
         195               0 :     aSegment->Release();
         196               0 : }
         197                 :
         198                 :
         199                 : #if defined(DEBUG)
         200                 :
         201                 : static const char sMagic[] =
         202                 :     "This little piggy went to market.\n"
         203                 :     "This little piggy stayed at home.\n"
         204                 :     "This little piggy has roast beef,\n"
         205                 :     "This little piggy had none.\n"
         206                 :     "And this little piggy cried \"Wee! Wee! Wee!\" all the way home";
         207                 :
         208                 :
         209                 : struct Header {
         210                 :   // Don't use size_t or bool here because their size depends on the
         211                 :   // architecture.
         212                 :   uint32 mSize;
         213                 :   uint32 mUnsafe;
         214                 :   char mMagic[sizeof(sMagic)];
         215                 : };
         216                 :
         217                 : static void
         218               0 : GetSections(Shmem::SharedMemory* aSegment,
         219                 :             Header** aHeader,
         220                 :             char** aFrontSentinel,
         221                 :             char** aData,
         222                 :             char** aBackSentinel)
         223                 : {
         224               0 :   NS_ABORT_IF_FALSE(aSegment && aFrontSentinel && aData && aBackSentinel,
         225                 :                     "NULL param(s)");
         226                 :
         227               0 :   *aFrontSentinel = reinterpret_cast<char*>(aSegment->memory());
         228               0 :   NS_ABORT_IF_FALSE(*aFrontSentinel, "NULL memory()");
         229                 :
         230               0 :   *aHeader = reinterpret_cast<Header*>(*aFrontSentinel);
         231                 :
         232               0 :   size_t pageSize = Shmem::SharedMemory::SystemPageSize();
         233               0 :   *aData = *aFrontSentinel + pageSize;
         234                 :
         235               0 :   *aBackSentinel = *aFrontSentinel + aSegment->Size() - pageSize;
         236               0 : }
         237                 :
         238                 : static Header*
         239               0 : GetHeader(Shmem::SharedMemory* aSegment)
         240                 : {
         241                 :   Header* header;
         242                 :   char* dontcare;
         243               0 :   GetSections(aSegment, &header, &dontcare, &dontcare, &dontcare);
         244               0 :   return header;
         245                 : }
         246                 :
         247                 : static void
         248               0 : Protect(SharedMemory* aSegment)
         249                 : {
         250               0 :   NS_ABORT_IF_FALSE(aSegment, "NULL segment");
         251               0 :   aSegment->Protect(reinterpret_cast<char*>(aSegment->memory()),
         252                 :                     aSegment->Size(),
         253               0 :                     RightsNone);
         254               0 : }
         255                 :
         256                 : static void
         257               0 : Unprotect(SharedMemory* aSegment)
         258                 : {
         259               0 :   NS_ABORT_IF_FALSE(aSegment, "NULL segment");
         260               0 :   aSegment->Protect(reinterpret_cast<char*>(aSegment->memory()),
         261                 :                     aSegment->Size(),
         262               0 :                     RightsRead | RightsWrite);
         263               0 : }
         264                 :
         265                 : //
         266                 : // In debug builds, we specially allocate shmem segments.  The layout
         267                 : // is as follows
         268                 : //
         269                 : //   Page 0: "front sentinel"
         270                 : //     size of mapping
         271                 : //     magic bytes
         272                 : //   Page 1 through n-1:
         273                 : //     user data
         274                 : //   Page n: "back sentinel"
         275                 : //     [nothing]
         276                 : //
         277                 : // The mapping can be in one of the following states, wrt to the
         278                 : // current process.
         279                 : //
         280                 : //   State "unmapped": all pages are mapped with no access rights.
         281                 : //
         282                 : //   State "mapping": all pages are mapped with read/write access.
         283                 : //
         284                 : //   State "mapped": the front and back sentinels are mapped with no
         285                 : //     access rights, and all the other pages are mapped with
         286                 : //     read/write access.
         287                 : //
         288                 : // When a SharedMemory segment is first allocated, it starts out in
         289                 : // the "mapping" state for the process that allocates the segment, and
         290                 : // in the "unmapped" state for the other process.  The allocating
         291                 : // process will then create a Shmem, which takes the segment into the
         292                 : // "mapped" state, where it can be accessed by clients.
         293                 : //
         294                 : // When a Shmem is sent to another process in an IPDL message, the
         295                 : // segment transitions into the "unmapped" state for the sending
         296                 : // process, and into the "mapping" state for the receiving process.
         297                 : // The receiving process will then create a Shmem from the underlying
         298                 : // segment, and take the segment into the "mapped" state.
         299                 : //
         300                 : // In the "mapping" state, we use the front sentinel to verify the
         301                 : // integrity of the shmem segment.  If valid, it has a size_t
         302                 : // containing the number of bytes the user allocated followed by the
         303                 : // magic bytes above.
         304                 : //
         305                 : // In the "mapped" state, the front and back sentinels have no access
         306                 : // rights.  They act as guards against buffer overflows and underflows
         307                 : // in client code; if clients touch a sentinel, they die with SIGSEGV.
         308                 : //
         309                 : // The "unmapped" state is used to enforce single-owner semantics of
         310                 : // the shmem segment.  If a process other than the current owner tries
         311                 : // to touch the segment, it dies with SIGSEGV.
         312                 : //
         313                 :
         314               0 : Shmem::Shmem(IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead,
         315                 :              SharedMemory* aSegment, id_t aId) :
         316                 :     mSegment(aSegment),
         317                 :     mData(0),
         318               0 :     mSize(0)
         319                 : {
         320               0 :   NS_ABORT_IF_FALSE(mSegment, "NULL segment");
         321               0 :   NS_ABORT_IF_FALSE(aId != 0, "invalid ID");
         322                 :
         323               0 :   Unprotect(mSegment);
         324                 :
         325                 :   Header* header;
         326                 :   char* frontSentinel;
         327                 :   char* data;
         328                 :   char* backSentinel;
         329               0 :   GetSections(aSegment, &header, &frontSentinel, &data, &backSentinel);
         330                 :
         331                 :   // do a quick validity check to avoid weird-looking crashes in libc
         332               0 :   char check = *frontSentinel;
         333                 :   (void)check;
         334                 :
         335               0 :   NS_ABORT_IF_FALSE(!strncmp(header->mMagic, sMagic, sizeof(sMagic)),
         336                 :                       "invalid segment");
         337               0 :   mSize = static_cast<size_t>(header->mSize);
         338                 :
         339               0 :   size_t pageSize = SharedMemory::SystemPageSize();
         340                 :   // transition into the "mapped" state by protecting the front and
         341                 :   // back sentinels (which guard against buffer under/overflows)
         342               0 :   mSegment->Protect(frontSentinel, pageSize, RightsNone);
         343               0 :   mSegment->Protect(backSentinel, pageSize, RightsNone);
         344                 :
         345                 :   // don't set these until we know they're valid
         346               0 :   mData = data;
         347               0 :   mId = aId;
         348               0 : }
         349                 :
         350                 : void
         351               0 : Shmem::AssertInvariants() const
         352                 : {
         353               0 :   NS_ABORT_IF_FALSE(mSegment, "NULL segment");
         354               0 :   NS_ABORT_IF_FALSE(mData, "NULL data pointer");
         355               0 :   NS_ABORT_IF_FALSE(mSize > 0, "invalid size");
         356                 :   // if the segment isn't owned by the current process, these will
         357                 :   // trigger SIGSEGV
         358               0 :   char checkMappingFront = *reinterpret_cast<char*>(mData);
         359               0 :   char checkMappingBack = *(reinterpret_cast<char*>(mData) + mSize - 1);
         360                 :
         361                 :   // avoid "unused" warnings for these variables:
         362               0 :   unused << checkMappingFront;
         363               0 :   unused << checkMappingBack;
         364               0 : }
         365                 :
         366                 : void
         367               0 : Shmem::RevokeRights(IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead)
         368                 : {
         369               0 :   AssertInvariants();
         370                 :
         371               0 :   size_t pageSize = SharedMemory::SystemPageSize();
         372               0 :   Header* header = GetHeader(mSegment);
         373                 :
         374                 :   // Open this up for reading temporarily
         375               0 :   mSegment->Protect(reinterpret_cast<char*>(header), pageSize, RightsRead);
         376                 :
         377               0 :   if (!header->mUnsafe) {
         378               0 :     Protect(mSegment);
         379                 :   } else {
         380               0 :     mSegment->Protect(reinterpret_cast<char*>(header), pageSize, RightsNone);
         381                 :   }
         382               0 : }
         383                 :
         384                 : // static
         385                 : Shmem::SharedMemory*
         386               0 : Shmem::Alloc(IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead,
         387                 :              size_t aNBytes,
         388                 :              SharedMemoryType aType,
         389                 :              bool aUnsafe,
         390                 :              bool aProtect)
         391                 : {
         392                 :   NS_ASSERTION(aNBytes <= PR_UINT32_MAX, "Will truncate shmem segment size!");
         393               0 :   NS_ABORT_IF_FALSE(!aProtect || !aUnsafe, "protect => !unsafe");
         394                 :
         395               0 :   size_t pageSize = SharedMemory::SystemPageSize();
         396               0 :   SharedMemory* segment = nsnull;
         397                 :   // |2*pageSize| is for the front and back sentinel
         398               0 :   size_t segmentSize = SharedMemory::PageAlignedSize(aNBytes + 2*pageSize);
         399                 :
         400               0 :   if (aType == SharedMemory::TYPE_BASIC)
         401               0 :     segment = CreateSegment(segmentSize, SharedMemoryBasic::NULLHandle());
         402                 : #ifdef MOZ_HAVE_SHAREDMEMORYSYSV
         403               0 :   else if (aType == SharedMemory::TYPE_SYSV)
         404               0 :     segment = CreateSegment(segmentSize, SharedMemorySysV::NULLHandle());
         405                 : #endif
         406                 :   else
         407               0 :     NS_RUNTIMEABORT("unknown shmem type");
         408                 :
         409               0 :   if (!segment)
         410               0 :     return 0;
         411                 :
         412                 :   Header* header;
         413                 :   char *frontSentinel;
         414                 :   char *data;
         415                 :   char *backSentinel;
         416               0 :   GetSections(segment, &header, &frontSentinel, &data, &backSentinel);
         417                 :
         418                 :   // initialize the segment with Shmem-internal information
         419                 :
         420                 :   // NB: this can't be a static assert because technically pageSize
         421                 :   // isn't known at compile time, event though in practice it's always
         422                 :   // going to be 4KiB
         423               0 :   NS_ABORT_IF_FALSE(sizeof(Header) <= pageSize,
         424                 :                     "Shmem::Header has gotten too big");
         425               0 :   memcpy(header->mMagic, sMagic, sizeof(sMagic));
         426               0 :   header->mSize = static_cast<uint32>(aNBytes);
         427               0 :   header->mUnsafe = aUnsafe;
         428                 :
         429               0 :   if (aProtect)
         430               0 :     Protect(segment);
         431                 :
         432               0 :   return segment;
         433                 : }
         434                 :
         435                 : // static
         436                 : Shmem::SharedMemory*
         437               0 : Shmem::OpenExisting(IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead,
         438                 :                     const IPC::Message& aDescriptor,
         439                 :                     id_t* aId,
         440                 :                     bool aProtect)
         441                 : {
         442               0 :   if (SHMEM_CREATED_MESSAGE_TYPE != aDescriptor.type())
         443               0 :     NS_RUNTIMEABORT("expected 'shmem created' message");
         444                 :
         445               0 :   void* iter = 0;
         446                 :   SharedMemory::SharedMemoryType type;
         447                 :   size_t size;
         448               0 :   if (!ShmemCreated::ReadInfo(&aDescriptor, &iter, aId, &size, &type))
         449               0 :     return 0;
         450                 :
         451               0 :   SharedMemory* segment = 0;
         452               0 :   size_t pageSize = SharedMemory::SystemPageSize();
         453                 :   // |2*pageSize| is for the front and back sentinels
         454               0 :   size_t segmentSize = SharedMemory::PageAlignedSize(size + 2*pageSize);
         455                 :
         456               0 :   if (SharedMemory::TYPE_BASIC == type) {
         457               0 :     SharedMemoryBasic::Handle handle;
         458               0 :     if (!ShmemCreated::ReadHandle(&aDescriptor, &iter, &handle))
         459               0 :       return 0;
         460                 :
         461               0 :     if (!SharedMemoryBasic::IsHandleValid(handle))
         462               0 :       NS_RUNTIMEABORT("trying to open invalid handle");
         463               0 :     segment = CreateSegment(segmentSize, handle);
         464                 :   }
         465                 : #ifdef MOZ_HAVE_SHAREDMEMORYSYSV
         466               0 :   else if (SharedMemory::TYPE_SYSV == type) {
         467                 :     SharedMemorySysV::Handle handle;
         468               0 :     if (!ShmemCreated::ReadHandle(&aDescriptor, &iter, &handle))
         469               0 :       return 0;
         470                 :
         471               0 :     if (!SharedMemorySysV::IsHandleValid(handle))
         472               0 :       NS_RUNTIMEABORT("trying to open invalid handle");
         473               0 :     segment = CreateSegment(segmentSize, handle);
         474                 :   }
         475                 : #endif
         476                 :   else {
         477               0 :     NS_RUNTIMEABORT("unknown shmem type");
         478                 :   }
         479                 :
         480               0 :   if (!segment)
         481               0 :     return 0;
         482                 :
         483                 :   // The caller of this function may not know whether the segment is
         484                 :   // unsafe or not
         485               0 :   Header* header = GetHeader(segment);
         486               0 :   if (!header->mUnsafe && aProtect)
         487               0 :     Protect(segment);
         488                 :
         489               0 :   return segment;
         490                 : }
         491                 :
         492                 : // static
         493                 : void
         494               0 : Shmem::Dealloc(IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead,
         495                 :                SharedMemory* aSegment)
         496                 : {
         497               0 :   if (!aSegment)
         498               0 :     return;
         499                 :
         500               0 :   size_t pageSize = SharedMemory::SystemPageSize();
         501                 :   Header* header;
         502                 :   char *frontSentinel;
         503                 :   char *data;
         504                 :   char *backSentinel;
         505               0 :   GetSections(aSegment, &header, &frontSentinel, &data, &backSentinel);
         506                 :
         507               0 :   aSegment->Protect(frontSentinel, pageSize, RightsWrite | RightsRead);
         508               0 :   memset(header->mMagic, 0, sizeof(sMagic));
         509               0 :   header->mSize = 0;
         510               0 :   header->mUnsafe = false;          // make it "safe" so as to catch errors
         511                 :
         512               0 :   DestroySegment(aSegment);
         513                 : }
         514                 :
         515                 :
         516                 : #else  // !defined(DEBUG)
         517                 :
         518                 : // static
         519                 : Shmem::SharedMemory*
         520                 : Shmem::Alloc(IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead,
         521                 :              size_t aNBytes,
         522                 :              SharedMemoryType aType,
         523                 :              bool /*unused*/,
         524                 :              bool /*unused*/)
         525                 : {
         526                 :   SharedMemory *segment = nsnull;
         527                 :
         528                 :   if (aType == SharedMemory::TYPE_BASIC)
         529                 :     segment = CreateSegment(SharedMemory::PageAlignedSize(aNBytes + sizeof(uint32)),
         530                 :                             SharedMemoryBasic::NULLHandle());
         531                 : #ifdef MOZ_HAVE_SHAREDMEMORYSYSV
         532                 :   else if (aType == SharedMemory::TYPE_SYSV)
         533                 :     segment = CreateSegment(SharedMemory::PageAlignedSize(aNBytes + sizeof(uint32)),
         534                 :                             SharedMemorySysV::NULLHandle());
         535                 : #endif
         536                 :   else
         537                 :     // Unhandled!!
         538                 :     NS_ABORT();
         539                 :
         540                 :   if (!segment)
         541                 :     return 0;
         542                 :
         543                 :   *PtrToSize(segment) = static_cast<uint32>(aNBytes);
         544                 :
         545                 :   return segment;
         546                 : }
         547                 :
         548                 : // static
         549                 : Shmem::SharedMemory*
         550                 : Shmem::OpenExisting(IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead,
         551                 :                     const IPC::Message& aDescriptor,
         552                 :                     id_t* aId,
         553                 :                     bool /*unused*/)
         554                 : {
         555                 :   if (SHMEM_CREATED_MESSAGE_TYPE != aDescriptor.type())
         556                 :     NS_RUNTIMEABORT("expected 'shmem created' message");
         557                 :
         558                 :   SharedMemory::SharedMemoryType type;
         559                 :   void* iter = 0;
         560                 :   size_t size;
         561                 :   if (!ShmemCreated::ReadInfo(&aDescriptor, &iter, aId, &size, &type))
         562                 :     return 0;
         563                 :
         564                 :   SharedMemory* segment = 0;
         565                 :   size_t segmentSize = SharedMemory::PageAlignedSize(size + sizeof(uint32));
         566                 :
         567                 :   if (SharedMemory::TYPE_BASIC == type) {
         568                 :     SharedMemoryBasic::Handle handle;
         569                 :     if (!ShmemCreated::ReadHandle(&aDescriptor, &iter, &handle))
         570                 :       return 0;
         571                 :
         572                 :     if (!SharedMemoryBasic::IsHandleValid(handle))
         573                 :       NS_RUNTIMEABORT("trying to open invalid handle");
         574                 :
         575                 :     segment = CreateSegment(segmentSize, handle);
         576                 :   }
         577                 : #ifdef MOZ_HAVE_SHAREDMEMORYSYSV
         578                 :   else if (SharedMemory::TYPE_SYSV == type) {
         579                 :     SharedMemorySysV::Handle handle;
         580                 :     if (!ShmemCreated::ReadHandle(&aDescriptor, &iter, &handle))
         581                 :       return 0;
         582                 :
         583                 :     if (!SharedMemorySysV::IsHandleValid(handle))
         584                 :       NS_RUNTIMEABORT("trying to open invalid handle");
         585                 :     segment = CreateSegment(segmentSize, handle);
         586                 :   }
         587                 : #endif
         588                 :   else {
         589                 :     NS_RUNTIMEABORT("unknown shmem type");
         590                 :   }
         591                 :
         592                 :   if (!segment)
         593                 :     return 0;
         594                 :
         595                 :   // this is the only validity check done OPT builds
         596                 :   if (size != static_cast<size_t>(*PtrToSize(segment)))
         597                 :     NS_RUNTIMEABORT("Alloc() segment size disagrees with OpenExisting()'s");
         598                 :
         599                 :   return segment;
         600                 : }
         601                 :
         602                 : // static
         603                 : void
         604                 : Shmem::Dealloc(IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead,
         605                 :                SharedMemory* aSegment)
         606                 : {
         607                 :   DestroySegment(aSegment);
         608                 : }
         609                 :
         610                 : #endif  // if defined(DEBUG)
         611                 :
         612                 : int
         613               0 : Shmem::GetSysVID() const
         614                 : {
         615                 : #ifdef MOZ_HAVE_SHAREDMEMORYSYSV
         616               0 :   AssertInvariants();
         617                 :
         618               0 :   if (mSegment->Type() != SharedMemory::TYPE_SYSV)
         619               0 :     NS_RUNTIMEABORT("Can't call GetSysVID() on a non-SysV Shmem!");
         620                 :
         621               0 :   SharedMemorySysV* seg = static_cast<SharedMemorySysV*>(mSegment);
         622               0 :   return seg->GetHandle();
         623                 : #else
         624                 :   NS_RUNTIMEABORT("Can't call GetSysVID() with no support for SysV shared memory!");
         625                 :   return -1;                    // not reached
         626                 : #endif
         627                 : }
         628                 :
         629                 : IPC::Message*
         630               0 : Shmem::ShareTo(IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead,
         631                 :                base::ProcessHandle aProcess,
         632                 :                int32 routingId)
         633                 : {
         634               0 :   AssertInvariants();
         635                 :
         636               0 :   if (SharedMemory::TYPE_BASIC == mSegment->Type()) {
         637               0 :     SharedMemoryBasic* seg = static_cast<SharedMemoryBasic*>(mSegment);
         638               0 :     SharedMemoryBasic::Handle handle;
         639               0 :     if (!seg->ShareToProcess(aProcess, &handle))
         640               0 :       return 0;
         641                 :
         642               0 :     return new ShmemCreated(routingId, mId, mSize, handle);
         643                 :   }
         644                 : #ifdef MOZ_HAVE_SHAREDMEMORYSYSV
         645               0 :   else if (SharedMemory::TYPE_SYSV == mSegment->Type()) {
         646               0 :     SharedMemorySysV* seg = static_cast<SharedMemorySysV*>(mSegment);
         647               0 :     return new ShmemCreated(routingId, mId, mSize, seg->GetHandle());
         648                 :   }
         649                 : #endif
         650                 :   else {
         651               0 :     NS_RUNTIMEABORT("unknown shmem type (here?!)");
         652                 :   }
         653                 :
         654               0 :   return 0;
         655                 : }
         656                 :
         657                 : IPC::Message*
         658               0 : Shmem::UnshareFrom(IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead,
         659                 :                    base::ProcessHandle aProcess,
         660                 :                    int32 routingId)
         661                 : {
         662               0 :   AssertInvariants();
         663               0 :   return new ShmemDestroyed(routingId, mId);
         664                 : }
         665                 :
         666                 : } // namespace ipc
         667                 : } // namespace mozilla

Generated by: LCOV version 1.7