LCOV - code coverage report
Current view: top level - dom/workers - Queue.h (source / functions) Hit Total Coverage
Test: output.info Lines: 33 48 68.8 %
Date: 2017-07-14 16:53:18 Functions: 13 23 56.5 %
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 ts=8 sts=2 et sw=2 tw=80: */
       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
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifndef mozilla_dom_workers_queue_h__
       8             : #define mozilla_dom_workers_queue_h__
       9             : 
      10             : #include "Workers.h"
      11             : 
      12             : #include "mozilla/Mutex.h"
      13             : #include "nsTArray.h"
      14             : 
      15             : BEGIN_WORKERS_NAMESPACE
      16             : 
      17             : template <typename T, int TCount>
      18             : struct StorageWithTArray
      19             : {
      20             :   typedef AutoTArray<T, TCount> StorageType;
      21             : 
      22          66 :   static void Reverse(StorageType& aStorage)
      23             :   {
      24          66 :     uint32_t length = aStorage.Length();
      25          66 :     for (uint32_t index = 0; index < length / 2; index++) {
      26           0 :       uint32_t reverseIndex = length - 1 - index;
      27             : 
      28           0 :       T t1 = aStorage.ElementAt(index);
      29           0 :       T t2 = aStorage.ElementAt(reverseIndex);
      30             : 
      31           0 :       aStorage.ReplaceElementsAt(index, 1, t2);
      32           0 :       aStorage.ReplaceElementsAt(reverseIndex, 1, t1);
      33             :     }
      34          66 :   }
      35             : 
      36         252 :   static bool IsEmpty(const StorageType& aStorage)
      37             :   {
      38         252 :     return !!aStorage.IsEmpty();
      39             :   }
      40             : 
      41           0 :   static bool Push(StorageType& aStorage, const T& aEntry)
      42             :   {
      43           0 :     return !!aStorage.AppendElement(aEntry);
      44             :   }
      45             : 
      46          66 :   static bool Pop(StorageType& aStorage, T& aEntry)
      47             :   {
      48          66 :     if (IsEmpty(aStorage)) {
      49          66 :       return false;
      50             :     }
      51             : 
      52           0 :     uint32_t index = aStorage.Length() - 1;
      53           0 :     aEntry = aStorage.ElementAt(index);
      54           0 :     aStorage.RemoveElementAt(index);
      55           0 :     return true;
      56             :   }
      57             : 
      58             :   static void Clear(StorageType& aStorage)
      59             :   {
      60             :     aStorage.Clear();
      61             :   }
      62             : 
      63          66 :   static void Compact(StorageType& aStorage)
      64             :   {
      65          66 :     aStorage.Compact();
      66          66 :   }
      67             : };
      68             : 
      69             : class LockingWithMutex
      70             : {
      71             :   mozilla::Mutex mMutex;
      72             : 
      73             : protected:
      74             :   LockingWithMutex()
      75             :   : mMutex("LockingWithMutex::mMutex")
      76             :   { }
      77             : 
      78             :   void Lock()
      79             :   {
      80             :     mMutex.Lock();
      81             :   }
      82             : 
      83             :   void Unlock()
      84             :   {
      85             :     mMutex.Unlock();
      86             :   }
      87             : 
      88             :   class AutoLock
      89             :   {
      90             :     LockingWithMutex& mHost;
      91             : 
      92             :   public:
      93             :     explicit AutoLock(LockingWithMutex& aHost)
      94             :     : mHost(aHost)
      95             :     {
      96             :       mHost.Lock();
      97             :     }
      98             : 
      99             :     ~AutoLock()
     100             :     {
     101             :       mHost.Unlock();
     102             :     }
     103             :   };
     104             : 
     105             :   friend class AutoLock;
     106             : };
     107             : 
     108           2 : class NoLocking
     109             : {
     110             : protected:
     111             :   void Lock()
     112             :   { }
     113             : 
     114             :   void Unlock()
     115             :   { }
     116             : 
     117             :   class AutoLock
     118             :   {
     119             :   public:
     120         126 :     explicit AutoLock(NoLocking& aHost)
     121         126 :     { }
     122             : 
     123         126 :     ~AutoLock()
     124         126 :     { }
     125             :   };
     126             : };
     127             : 
     128             : template <typename T,
     129             :           int TCount = 256,
     130             :           class LockingPolicy = NoLocking,
     131             :           class StoragePolicy = StorageWithTArray<T, TCount % 2 ?
     132             :                                                      TCount / 2 + 1 :
     133             :                                                      TCount / 2> >
     134           0 : class Queue : public LockingPolicy
     135             : {
     136             :   typedef typename StoragePolicy::StorageType StorageType;
     137             :   typedef typename LockingPolicy::AutoLock AutoLock;
     138             : 
     139             :   StorageType mStorage1;
     140             :   StorageType mStorage2;
     141             : 
     142             :   StorageType* mFront;
     143             :   StorageType* mBack;
     144             : 
     145             : public:
     146           2 :   Queue()
     147           2 :   : mFront(&mStorage1), mBack(&mStorage2)
     148           2 :   { }
     149             : 
     150          60 :   bool IsEmpty()
     151             :   {
     152         120 :     AutoLock lock(*this);
     153         120 :     return StoragePolicy::IsEmpty(*mFront) &&
     154         180 :            StoragePolicy::IsEmpty(*mBack);
     155             :   }
     156             : 
     157           0 :   bool Push(const T& aEntry)
     158             :   {
     159           0 :     AutoLock lock(*this);
     160           0 :     return StoragePolicy::Push(*mBack, aEntry);
     161             :   }
     162             : 
     163          66 :   bool Pop(T& aEntry)
     164             :   {
     165         132 :     AutoLock lock(*this);
     166          66 :     if (StoragePolicy::IsEmpty(*mFront)) {
     167          66 :       StoragePolicy::Compact(*mFront);
     168          66 :       StoragePolicy::Reverse(*mBack);
     169          66 :       StorageType* tmp = mFront;
     170          66 :       mFront = mBack;
     171          66 :       mBack = tmp;
     172             :     }
     173         132 :     return StoragePolicy::Pop(*mFront, aEntry);
     174             :   }
     175             : 
     176             :   void Clear()
     177             :   {
     178             :     AutoLock lock(*this);
     179             :     StoragePolicy::Clear(*mFront);
     180             :     StoragePolicy::Clear(*mBack);
     181             :   }
     182             : 
     183             :   // XXX Do we need this?
     184             :   void Lock()
     185             :   {
     186             :     LockingPolicy::Lock();
     187             :   }
     188             : 
     189             :   // XXX Do we need this?
     190             :   void Unlock()
     191             :   {
     192             :     LockingPolicy::Unlock();
     193             :   }
     194             : 
     195             : private:
     196             :   // Queue is not copyable.
     197             :   Queue(const Queue&);
     198             :   Queue & operator=(const Queue&);
     199             : };
     200             : 
     201             : END_WORKERS_NAMESPACE
     202             : 
     203             : #endif /* mozilla_dom_workers_queue_h__ */

Generated by: LCOV version 1.13