UDK 3.2.7 C/C++ API Reference
|
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 00002 /************************************************************************* 00003 * 00004 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 00005 * 00006 * Copyright 2000, 2010 Oracle and/or its affiliates. 00007 * 00008 * OpenOffice.org - a multi-platform office productivity suite 00009 * 00010 * This file is part of OpenOffice.org. 00011 * 00012 * OpenOffice.org is free software: you can redistribute it and/or modify 00013 * it under the terms of the GNU Lesser General Public License version 3 00014 * only, as published by the Free Software Foundation. 00015 * 00016 * OpenOffice.org is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Lesser General Public License version 3 for more details 00020 * (a copy is included in the LICENSE file that accompanied this code). 00021 * 00022 * You should have received a copy of the GNU Lesser General Public License 00023 * version 3 along with OpenOffice.org. If not, see 00024 * <http://www.openoffice.org/license.html> 00025 * for a copy of the LGPLv3 License. 00026 * 00027 ************************************************************************/ 00028 00029 #ifndef _SALHELPER_MONITOR_HXX_ 00030 #define _SALHELPER_MONITOR_HXX_ 00031 00032 #include <sal/types.h> 00033 #include <osl/conditn.hxx> 00034 #include <osl/diagnose.h> 00035 #include <osl/interlck.h> 00036 #include <rtl/ref.hxx> 00037 #include <salhelper/refobj.hxx> 00038 #include <salhelper/future.hxx> 00039 #include <salhelper/futurequeue.hxx> 00040 00041 namespace salhelper 00042 { 00043 00044 //---------------------------------------------------------------------------- 00045 00046 #ifndef SALHELPER_COPYCTOR_API 00047 #define SALHELPER_COPYCTOR_API(C) C (const C&); C& operator= (const C&) 00048 #endif 00049 00050 //---------------------------------------------------------------------------- 00051 00052 class MonitorCondition : protected osl::Condition 00053 { 00056 oslInterlockedCount m_nReferenceCount; 00057 00060 SALHELPER_COPYCTOR_API(MonitorCondition); 00061 00062 public: 00065 inline MonitorCondition() SAL_THROW(()) : m_nReferenceCount (0) 00066 { 00067 Condition::set(); 00068 } 00069 00072 inline ~MonitorCondition() SAL_THROW(()) 00073 { 00074 OSL_ASSERT(m_nReferenceCount == 0); 00075 } 00076 00079 inline void acquire() SAL_THROW(()) 00080 { 00081 if (osl_incrementInterlockedCount (&m_nReferenceCount) == 1) 00082 { 00083 Condition::reset(); 00084 } 00085 } 00086 00089 inline void release() SAL_THROW(()) 00090 { 00091 if (osl_decrementInterlockedCount (&m_nReferenceCount) == 0) 00092 { 00093 Condition::set(); 00094 } 00095 } 00096 00099 inline void wait() SAL_THROW(()) 00100 { 00101 Condition::wait(); 00102 } 00103 }; 00104 00105 //---------------------------------------------------------------------------- 00106 00107 class QueuedReaderWriterMonitor : public salhelper::ReferenceObject 00108 { 00111 typedef salhelper::Future<sal_Int32> future_type; 00112 00113 salhelper::FutureQueue<sal_Int32> m_aQueue; 00114 salhelper::MonitorCondition m_aMonitor; 00115 00118 SALHELPER_COPYCTOR_API(QueuedReaderWriterMonitor); 00119 00120 public: 00123 inline QueuedReaderWriterMonitor() 00124 { 00125 // Insert the token. 00126 m_aQueue.put(0); 00127 } 00128 00131 inline void acquireReader() 00132 { 00133 // Obtain the token. 00134 rtl::Reference<future_type> xFuture (m_aQueue.get()); 00135 xFuture->get(); 00136 00137 // Enter the monitor. 00138 m_aMonitor.acquire(); 00139 00140 // Push back the token. 00141 m_aQueue.put(0); 00142 } 00143 00146 inline void releaseReader() 00147 { 00148 // Leave the monitor. 00149 m_aMonitor.release(); 00150 } 00151 00154 inline void acquireWriter() 00155 { 00156 // Obtain the token. 00157 rtl::Reference<future_type> xFuture (m_aQueue.get()); 00158 xFuture->get(); 00159 00160 // Wait until all readers have left. 00161 m_aMonitor.wait(); 00162 } 00163 00166 inline void releaseWriter() 00167 { 00168 // Push back the token. 00169 m_aQueue.put(0); 00170 } 00171 00172 protected: 00175 virtual ~QueuedReaderWriterMonitor() 00176 {} 00177 }; 00178 00179 //---------------------------------------------------------------------------- 00180 00181 template<class monitor_type> 00182 class ReaderGuard 00183 { 00186 monitor_type *m_pMonitor; 00187 00190 SALHELPER_COPYCTOR_API(ReaderGuard<monitor_type>); 00191 00192 public: 00195 inline ReaderGuard (monitor_type & rMonitor) : m_pMonitor (&rMonitor) 00196 { 00197 m_pMonitor->acquireReader(); 00198 } 00199 00202 inline ReaderGuard (monitor_type * pMonitor) : m_pMonitor (pMonitor) 00203 { 00204 OSL_PRECOND(m_pMonitor, "ReaderGuard::ReaderGuard(): No Monitor"); 00205 m_pMonitor->acquireReader(); 00206 } 00207 00210 inline ~ReaderGuard() 00211 { 00212 if (m_pMonitor) 00213 m_pMonitor->releaseReader(); 00214 } 00215 00218 inline void clear() 00219 { 00220 if (m_pMonitor) 00221 { 00222 m_pMonitor->releaseReader(); 00223 m_pMonitor = 0; 00224 } 00225 } 00226 }; 00227 00228 //---------------------------------------------------------------------------- 00229 00230 typedef ReaderGuard<QueuedReaderWriterMonitor> QueuedReaderGuard; 00231 00232 //---------------------------------------------------------------------------- 00233 00234 template<class monitor_type> 00235 class WriterGuard 00236 { 00239 monitor_type *m_pMonitor; 00240 00243 SALHELPER_COPYCTOR_API(WriterGuard<monitor_type>); 00244 00245 public: 00248 inline WriterGuard (monitor_type & rMonitor) : m_pMonitor (&rMonitor) 00249 { 00250 m_pMonitor->acquireWriter(); 00251 } 00252 00255 inline WriterGuard (monitor_type * pMonitor) : m_pMonitor (pMonitor) 00256 { 00257 OSL_PRECOND(m_pMonitor, "WriterGuard::WriterGuard(): No Monitor"); 00258 m_pMonitor->acquireWriter(); 00259 } 00260 00263 inline ~WriterGuard() 00264 { 00265 if (m_pMonitor) 00266 m_pMonitor->releaseWriter(); 00267 } 00268 00271 inline void clear() 00272 { 00273 if (m_pMonitor) 00274 { 00275 m_pMonitor->releaseWriter(); 00276 m_pMonitor = 0; 00277 } 00278 } 00279 }; 00280 00281 //---------------------------------------------------------------------------- 00282 00283 typedef WriterGuard<QueuedReaderWriterMonitor> QueuedWriterGuard; 00284 00285 //---------------------------------------------------------------------------- 00286 00287 } // namespace salhelper 00288 00289 #endif /* !_SALHELPER_MONITOR_HXX_ */ 00290 00291 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */