LCOV - code coverage report
Current view: top level - dom/media/systemservices - ShmemPool.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 55 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 10 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set sw=2 ts=8 et ft=cpp : */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
       5             :  * You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifndef mozilla_ShmemPool_h
       8             : #define mozilla_ShmemPool_h
       9             : 
      10             : #include "mozilla/ipc/Shmem.h"
      11             : #include "mozilla/Mutex.h"
      12             : #include "mozilla/SizePrintfMacros.h"
      13             : 
      14             : #undef LOG
      15             : #undef LOG_ENABLED
      16             : extern mozilla::LazyLogModule gCamerasParentLog;
      17             : #define LOG(args) MOZ_LOG(gCamerasParentLog, mozilla::LogLevel::Debug, args)
      18             : #define LOG_ENABLED() MOZ_LOG_TEST(gCamerasParentLog, mozilla::LogLevel::Debug)
      19             : 
      20             : namespace mozilla {
      21             : 
      22             : class ShmemPool;
      23             : 
      24           0 : class ShmemBuffer {
      25             : public:
      26           0 :   ShmemBuffer() : mInitialized(false) {}
      27           0 :   explicit ShmemBuffer(mozilla::ipc::Shmem aShmem) {
      28           0 :     mInitialized = true;
      29           0 :     mShmem = aShmem;
      30           0 :   }
      31             : 
      32           0 :   ShmemBuffer(ShmemBuffer&& rhs) {
      33           0 :     mInitialized = rhs.mInitialized;
      34           0 :     mShmem = Move(rhs.mShmem);
      35           0 :   }
      36             : 
      37           0 :   ShmemBuffer& operator=(ShmemBuffer&& rhs) {
      38           0 :     MOZ_ASSERT(&rhs != this, "self-moves are prohibited");
      39           0 :     mInitialized = rhs.mInitialized;
      40           0 :     mShmem = Move(rhs.mShmem);
      41           0 :     return *this;
      42             :   }
      43             : 
      44             :   // No copies allowed
      45             :   ShmemBuffer(const ShmemBuffer&) = delete;
      46             :   ShmemBuffer& operator=(const ShmemBuffer&) = delete;
      47             : 
      48           0 :   bool Valid() {
      49           0 :     return mInitialized;
      50             :   }
      51             : 
      52           0 :   uint8_t * GetBytes() {
      53           0 :     return mShmem.get<uint8_t>();
      54             :   }
      55             : 
      56           0 :   mozilla::ipc::Shmem& Get() {
      57           0 :     return mShmem;
      58             :   }
      59             : 
      60             : private:
      61             :   friend class ShmemPool;
      62             : 
      63             :   bool mInitialized;
      64             :   mozilla::ipc::Shmem mShmem;
      65             : };
      66             : 
      67             : class ShmemPool {
      68             : public:
      69             :   explicit ShmemPool(size_t aPoolSize);
      70             :   ~ShmemPool();
      71             :   // Get/GetIfAvailable differ in what thread they can run on. GetIfAvailable
      72             :   // can run anywhere but won't allocate if the right size isn't available.
      73             :   ShmemBuffer GetIfAvailable(size_t aSize);
      74             :   void Put(ShmemBuffer&& aShmem);
      75             : 
      76             :   // We need to use the allocation/deallocation functions
      77             :   // of a specific IPC child/parent instance.
      78             :   template <class T>
      79           0 :   void Cleanup(T* aInstance)
      80             :   {
      81           0 :     MutexAutoLock lock(mMutex);
      82           0 :     for (size_t i = 0; i < mShmemPool.Length(); i++) {
      83           0 :       if (mShmemPool[i].mInitialized) {
      84           0 :         aInstance->DeallocShmem(mShmemPool[i].Get());
      85           0 :         mShmemPool[i].mInitialized = false;
      86             :       }
      87             :     }
      88           0 :   }
      89             : 
      90             :   template <class T>
      91           0 :   ShmemBuffer Get(T* aInstance, size_t aSize)
      92             :   {
      93           0 :     MutexAutoLock lock(mMutex);
      94             : 
      95             :     // Pool is empty, don't block caller.
      96           0 :     if (mPoolFree == 0) {
      97             :       // This isn't initialized, so will be understood as an error.
      98           0 :       return ShmemBuffer();
      99             :     }
     100             : 
     101           0 :     ShmemBuffer& res = mShmemPool[mPoolFree - 1];
     102             : 
     103           0 :     if (!res.mInitialized) {
     104           0 :       LOG(("Initializing new Shmem in pool"));
     105           0 :       if (!aInstance->AllocShmem(aSize, ipc::SharedMemory::TYPE_BASIC, &res.mShmem)) {
     106           0 :         LOG(("Failure allocating new Shmem buffer"));
     107           0 :         return ShmemBuffer();
     108             :       }
     109           0 :       res.mInitialized = true;
     110             :     }
     111             : 
     112           0 :     MOZ_ASSERT(res.mShmem.IsWritable(), "Shmem in Pool is not writable?");
     113             : 
     114             :     // Prepare buffer, increase size if needed (we never shrink as we don't
     115             :     // maintain seperate sized pools and we don't want to keep reallocating)
     116           0 :     if (res.mShmem.Size<char>() < aSize) {
     117           0 :       LOG(("Size change/increase in Shmem Pool"));
     118           0 :       aInstance->DeallocShmem(res.mShmem);
     119           0 :       res.mInitialized = false;
     120             :       // this may fail; always check return value
     121           0 :       if (!aInstance->AllocShmem(aSize, ipc::SharedMemory::TYPE_BASIC, &res.mShmem)) {
     122           0 :         LOG(("Failure allocating resized Shmem buffer"));
     123           0 :         return ShmemBuffer();
     124             :       } else {
     125           0 :         res.mInitialized = true;
     126             :       }
     127             :     }
     128             : 
     129           0 :     MOZ_ASSERT(res.mShmem.IsWritable(), "Shmem in Pool is not writable post resize?");
     130             : 
     131           0 :     mPoolFree--;
     132             : #ifdef DEBUG
     133           0 :     size_t poolUse = mShmemPool.Length() - mPoolFree;
     134           0 :     if (poolUse > mMaxPoolUse) {
     135           0 :       mMaxPoolUse = poolUse;
     136           0 :       LOG(("Maximum ShmemPool use increased: %" PRIuSIZE " buffers", mMaxPoolUse));
     137             :     }
     138             : #endif
     139           0 :     return Move(res);
     140             :   }
     141             : 
     142             : private:
     143             :   Mutex mMutex;
     144             :   size_t mPoolFree;
     145             : #ifdef DEBUG
     146             :   size_t mMaxPoolUse;
     147             : #endif
     148             :   nsTArray<ShmemBuffer> mShmemPool;
     149             : };
     150             : 
     151             : 
     152             : } // namespace mozilla
     153             : 
     154             : #endif  // mozilla_ShmemPool_h

Generated by: LCOV version 1.13