LCOV - code coverage report
Current view: top level - xpcom/threads - RWLock.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 20 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 4 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 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             : // An interface for read-write locks.
       8             : 
       9             : #ifndef mozilla_RWLock_h
      10             : #define mozilla_RWLock_h
      11             : 
      12             : #include "mozilla/Assertions.h"
      13             : #include "mozilla/BlockingResourceBase.h"
      14             : #include "mozilla/GuardObjects.h"
      15             : 
      16             : #ifndef XP_WIN
      17             : #include <pthread.h>
      18             : #endif
      19             : 
      20             : namespace mozilla {
      21             : 
      22             : // A RWLock is similar to a Mutex, but whereas a Mutex permits only a single
      23             : // reader thread or a single writer thread to access a piece of data, a
      24             : // RWLock distinguishes between readers and writers: you may have multiple
      25             : // reader threads concurrently accessing a piece of data or a single writer
      26             : // thread.  This difference should guide your usage of RWLock: if you are not
      27             : // reading the data from multiple threads simultaneously or you are writing
      28             : // to the data roughly as often as read from it, then Mutex will suit your
      29             : // purposes just fine.
      30             : //
      31             : // You should be using the AutoReadLock and AutoWriteLock classes, below,
      32             : // for RAII read locking and write locking, respectively.  If you really must
      33             : // take a read lock manually, call the ReadLock method; to relinquish that
      34             : // read lock, call the ReadUnlock method.  Similarly, WriteLock and WriteUnlock
      35             : // perform the same operations, but for write locks.
      36             : //
      37             : // It is unspecified what happens when a given thread attempts to acquire the
      38             : // same lock in multiple ways; some underlying implementations of RWLock do
      39             : // support acquiring a read lock multiple times on a given thread, but you
      40             : // should not rely on this behavior.
      41             : //
      42             : // It is unspecified whether RWLock gives priority to waiting readers or
      43             : // a waiting writer when unlocking.
      44             : class RWLock : public BlockingResourceBase
      45             : {
      46             : public:
      47             :   explicit RWLock(const char* aName);
      48             : 
      49             :   // Windows rwlocks don't need any special handling to be destroyed, but
      50             :   // POSIX ones do.
      51             : #ifdef XP_WIN
      52             :   ~RWLock() = default;
      53             : #else
      54             :   ~RWLock();
      55             : #endif
      56             : 
      57             : #ifdef DEBUG
      58             :   bool LockedForWritingByCurrentThread();
      59             :   void ReadLock();
      60             :   void ReadUnlock();
      61             :   void WriteLock();
      62             :   void WriteUnlock();
      63             : #else
      64             :   void ReadLock() { ReadLockInternal(); }
      65             :   void ReadUnlock() { ReadUnlockInternal(); }
      66             :   void WriteLock() { WriteLockInternal(); }
      67             :   void WriteUnlock() { WriteUnlockInternal(); }
      68             : #endif
      69             : 
      70             : private:
      71             :   void ReadLockInternal();
      72             :   void ReadUnlockInternal();
      73             :   void WriteLockInternal();
      74             :   void WriteUnlockInternal();
      75             : 
      76             :   RWLock() = delete;
      77             :   RWLock(const RWLock&) = delete;
      78             :   RWLock& operator=(const RWLock&) = delete;
      79             : 
      80             : #ifndef XP_WIN
      81             :   pthread_rwlock_t mRWLock;
      82             : #else
      83             :   // SRWLock is pointer-sized.  We declare it in such a fashion here to
      84             :   // avoid pulling in windows.h wherever this header is used.
      85             :   void* mRWLock;
      86             : #endif
      87             : 
      88             : #ifdef DEBUG
      89             :   // We record the owning thread for write locks only.
      90             :   PRThread* mOwningThread;
      91             : #endif
      92             : };
      93             : 
      94             : // Read lock and unlock a RWLock with RAII semantics.  Much preferred to bare
      95             : // calls to ReadLock() and ReadUnlock().
      96             : class MOZ_RAII AutoReadLock final
      97             : {
      98             : public:
      99           0 :   explicit AutoReadLock(RWLock& aLock MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     100           0 :     : mLock(&aLock)
     101             :   {
     102           0 :     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     103           0 :     MOZ_ASSERT(mLock, "null lock");
     104           0 :     mLock->ReadLock();
     105           0 :   }
     106             : 
     107           0 :   ~AutoReadLock()
     108           0 :   {
     109           0 :     mLock->ReadUnlock();
     110           0 :   }
     111             : 
     112             :  private:
     113             :   AutoReadLock() = delete;
     114             :   AutoReadLock(const AutoReadLock&) = delete;
     115             :   AutoReadLock& operator=(const AutoReadLock&) = delete;
     116             : 
     117             :   RWLock* mLock;
     118             :   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
     119             : };
     120             : 
     121             : // Write lock and unlock a RWLock with RAII semantics.  Much preferred to bare
     122             : // calls to WriteLock() and WriteUnlock().
     123             : class MOZ_RAII AutoWriteLock final
     124             : {
     125             : public:
     126           0 :   explicit AutoWriteLock(RWLock& aLock MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     127           0 :     : mLock(&aLock)
     128             :   {
     129           0 :     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     130           0 :     MOZ_ASSERT(mLock, "null lock");
     131           0 :     mLock->WriteLock();
     132           0 :   }
     133             : 
     134           0 :   ~AutoWriteLock()
     135           0 :   {
     136           0 :     mLock->WriteUnlock();
     137           0 :   }
     138             : 
     139             :  private:
     140             :   AutoWriteLock() = delete;
     141             :   AutoWriteLock(const AutoWriteLock&) = delete;
     142             :   AutoWriteLock& operator=(const AutoWriteLock&) = delete;
     143             : 
     144             :   RWLock* mLock;
     145             :   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
     146             : };
     147             : 
     148             : } // namespace mozilla
     149             : 
     150             : #endif // mozilla_RWLock_h

Generated by: LCOV version 1.13