1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/xpcom/glue/Monitor.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,158 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * vim: sw=2 ts=8 et : 1.6 + */ 1.7 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.8 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.9 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.10 + 1.11 +#ifndef mozilla_Monitor_h 1.12 +#define mozilla_Monitor_h 1.13 + 1.14 +#include "mozilla/CondVar.h" 1.15 +#include "mozilla/Mutex.h" 1.16 + 1.17 +namespace mozilla { 1.18 + 1.19 +/** 1.20 + * Monitor provides a *non*-reentrant monitor: *not* a Java-style 1.21 + * monitor. If your code needs support for reentrancy, use 1.22 + * ReentrantMonitor instead. (Rarely should reentrancy be needed.) 1.23 + * 1.24 + * Instead of directly calling Monitor methods, it's safer and simpler 1.25 + * to instead use the RAII wrappers MonitorAutoLock and 1.26 + * MonitorAutoUnlock. 1.27 + */ 1.28 +class NS_COM_GLUE Monitor 1.29 +{ 1.30 +public: 1.31 + Monitor(const char* aName) : 1.32 + mMutex(aName), 1.33 + mCondVar(mMutex, "[Monitor.mCondVar]") 1.34 + {} 1.35 + 1.36 + ~Monitor() {} 1.37 + 1.38 + void Lock() 1.39 + { 1.40 + mMutex.Lock(); 1.41 + } 1.42 + 1.43 + void Unlock() 1.44 + { 1.45 + mMutex.Unlock(); 1.46 + } 1.47 + 1.48 + nsresult Wait(PRIntervalTime interval = PR_INTERVAL_NO_TIMEOUT) 1.49 + { 1.50 + return mCondVar.Wait(interval); 1.51 + } 1.52 + 1.53 + nsresult Notify() 1.54 + { 1.55 + return mCondVar.Notify(); 1.56 + } 1.57 + 1.58 + nsresult NotifyAll() 1.59 + { 1.60 + return mCondVar.NotifyAll(); 1.61 + } 1.62 + 1.63 + void AssertCurrentThreadOwns() const 1.64 + { 1.65 + mMutex.AssertCurrentThreadOwns(); 1.66 + } 1.67 + 1.68 + void AssertNotCurrentThreadOwns() const 1.69 + { 1.70 + mMutex.AssertNotCurrentThreadOwns(); 1.71 + } 1.72 + 1.73 +private: 1.74 + Monitor(); 1.75 + Monitor(const Monitor&); 1.76 + Monitor& operator =(const Monitor&); 1.77 + 1.78 + Mutex mMutex; 1.79 + CondVar mCondVar; 1.80 +}; 1.81 + 1.82 +/** 1.83 + * Lock the monitor for the lexical scope instances of this class are 1.84 + * bound to (except for MonitorAutoUnlock in nested scopes). 1.85 + * 1.86 + * The monitor must be unlocked when instances of this class are 1.87 + * created. 1.88 + */ 1.89 +class NS_COM_GLUE MOZ_STACK_CLASS MonitorAutoLock 1.90 +{ 1.91 +public: 1.92 + MonitorAutoLock(Monitor& aMonitor) : 1.93 + mMonitor(&aMonitor) 1.94 + { 1.95 + mMonitor->Lock(); 1.96 + } 1.97 + 1.98 + ~MonitorAutoLock() 1.99 + { 1.100 + mMonitor->Unlock(); 1.101 + } 1.102 + 1.103 + nsresult Wait(PRIntervalTime interval = PR_INTERVAL_NO_TIMEOUT) 1.104 + { 1.105 + return mMonitor->Wait(interval); 1.106 + } 1.107 + 1.108 + nsresult Notify() 1.109 + { 1.110 + return mMonitor->Notify(); 1.111 + } 1.112 + 1.113 + nsresult NotifyAll() 1.114 + { 1.115 + return mMonitor->NotifyAll(); 1.116 + } 1.117 + 1.118 +private: 1.119 + MonitorAutoLock(); 1.120 + MonitorAutoLock(const MonitorAutoLock&); 1.121 + MonitorAutoLock& operator =(const MonitorAutoLock&); 1.122 + static void* operator new(size_t) CPP_THROW_NEW; 1.123 + static void operator delete(void*); 1.124 + 1.125 + Monitor* mMonitor; 1.126 +}; 1.127 + 1.128 +/** 1.129 + * Unlock the monitor for the lexical scope instances of this class 1.130 + * are bound to (except for MonitorAutoLock in nested scopes). 1.131 + * 1.132 + * The monitor must be locked by the current thread when instances of 1.133 + * this class are created. 1.134 + */ 1.135 +class NS_COM_GLUE MOZ_STACK_CLASS MonitorAutoUnlock 1.136 +{ 1.137 +public: 1.138 + MonitorAutoUnlock(Monitor& aMonitor) : 1.139 + mMonitor(&aMonitor) 1.140 + { 1.141 + mMonitor->Unlock(); 1.142 + } 1.143 + 1.144 + ~MonitorAutoUnlock() 1.145 + { 1.146 + mMonitor->Lock(); 1.147 + } 1.148 + 1.149 +private: 1.150 + MonitorAutoUnlock(); 1.151 + MonitorAutoUnlock(const MonitorAutoUnlock&); 1.152 + MonitorAutoUnlock& operator =(const MonitorAutoUnlock&); 1.153 + static void* operator new(size_t) CPP_THROW_NEW; 1.154 + static void operator delete(void*); 1.155 + 1.156 + Monitor* mMonitor; 1.157 +}; 1.158 + 1.159 +} // namespace mozilla 1.160 + 1.161 +#endif // mozilla_Monitor_h