My Project
UDK 3.2.7 C/C++ API Reference
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
monitor.hxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * Copyright 2000, 2010 Oracle and/or its affiliates.
7  *
8  * OpenOffice.org - a multi-platform office productivity suite
9  *
10  * This file is part of OpenOffice.org.
11  *
12  * OpenOffice.org is free software: you can redistribute it and/or modify
13  * it under the terms of the GNU Lesser General Public License version 3
14  * only, as published by the Free Software Foundation.
15  *
16  * OpenOffice.org is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Lesser General Public License version 3 for more details
20  * (a copy is included in the LICENSE file that accompanied this code).
21  *
22  * You should have received a copy of the GNU Lesser General Public License
23  * version 3 along with OpenOffice.org. If not, see
24  * <http://www.openoffice.org/license.html>
25  * for a copy of the LGPLv3 License.
26  *
27  ************************************************************************/
28 
29 #ifndef _SALHELPER_MONITOR_HXX_
30 #define _SALHELPER_MONITOR_HXX_
31 
32 #include <sal/types.h>
33 #include <osl/conditn.hxx>
34 #include <osl/diagnose.h>
35 #include <osl/interlck.h>
36 #include <rtl/ref.hxx>
37 #include <salhelper/refobj.hxx>
38 #include <salhelper/future.hxx>
40 
41 namespace salhelper
42 {
43 
44 //----------------------------------------------------------------------------
45 
46 #ifndef SALHELPER_COPYCTOR_API
47 #define SALHELPER_COPYCTOR_API(C) C (const C&); C& operator= (const C&)
48 #endif
49 
50 //----------------------------------------------------------------------------
51 
53 {
56  oslInterlockedCount m_nReferenceCount;
57 
60  SALHELPER_COPYCTOR_API(MonitorCondition);
61 
62 public:
65  inline MonitorCondition() SAL_THROW(()) : m_nReferenceCount (0)
66  {
68  }
69 
73  {
74  OSL_ASSERT(m_nReferenceCount == 0);
75  }
76 
79  inline void acquire() SAL_THROW(())
80  {
81  if (osl_incrementInterlockedCount (&m_nReferenceCount) == 1)
82  {
84  }
85  }
86 
89  inline void release() SAL_THROW(())
90  {
91  if (osl_decrementInterlockedCount (&m_nReferenceCount) == 0)
92  {
94  }
95  }
96 
99  inline void wait() SAL_THROW(())
100  {
101  Condition::wait();
102  }
103 };
104 
105 //----------------------------------------------------------------------------
106 
108 {
112 
114  salhelper::MonitorCondition m_aMonitor;
115 
118  SALHELPER_COPYCTOR_API(QueuedReaderWriterMonitor);
119 
120 public:
124  {
125  // Insert the token.
126  m_aQueue.put(0);
127  }
128 
131  inline void acquireReader()
132  {
133  // Obtain the token.
134  rtl::Reference<future_type> xFuture (m_aQueue.get());
135  xFuture->get();
136 
137  // Enter the monitor.
138  m_aMonitor.acquire();
139 
140  // Push back the token.
141  m_aQueue.put(0);
142  }
143 
146  inline void releaseReader()
147  {
148  // Leave the monitor.
149  m_aMonitor.release();
150  }
151 
154  inline void acquireWriter()
155  {
156  // Obtain the token.
157  rtl::Reference<future_type> xFuture (m_aQueue.get());
158  xFuture->get();
159 
160  // Wait until all readers have left.
161  m_aMonitor.wait();
162  }
163 
166  inline void releaseWriter()
167  {
168  // Push back the token.
169  m_aQueue.put(0);
170  }
171 
172 protected:
176  {}
177 };
178 
179 //----------------------------------------------------------------------------
180 
181 template<class monitor_type>
183 {
186  monitor_type *m_pMonitor;
187 
190  SALHELPER_COPYCTOR_API(ReaderGuard<monitor_type>);
191 
192 public:
195  inline ReaderGuard (monitor_type & rMonitor) : m_pMonitor (&rMonitor)
196  {
197  m_pMonitor->acquireReader();
198  }
199 
202  inline ReaderGuard (monitor_type * pMonitor) : m_pMonitor (pMonitor)
203  {
204  OSL_PRECOND(m_pMonitor, "ReaderGuard::ReaderGuard(): No Monitor");
205  m_pMonitor->acquireReader();
206  }
207 
210  inline ~ReaderGuard()
211  {
212  if (m_pMonitor)
213  m_pMonitor->releaseReader();
214  }
215 
218  inline void clear()
219  {
220  if (m_pMonitor)
221  {
222  m_pMonitor->releaseReader();
223  m_pMonitor = 0;
224  }
225  }
226 };
227 
228 //----------------------------------------------------------------------------
229 
231 
232 //----------------------------------------------------------------------------
233 
234 template<class monitor_type>
236 {
239  monitor_type *m_pMonitor;
240 
243  SALHELPER_COPYCTOR_API(WriterGuard<monitor_type>);
244 
245 public:
248  inline WriterGuard (monitor_type & rMonitor) : m_pMonitor (&rMonitor)
249  {
250  m_pMonitor->acquireWriter();
251  }
252 
255  inline WriterGuard (monitor_type * pMonitor) : m_pMonitor (pMonitor)
256  {
257  OSL_PRECOND(m_pMonitor, "WriterGuard::WriterGuard(): No Monitor");
258  m_pMonitor->acquireWriter();
259  }
260 
263  inline ~WriterGuard()
264  {
265  if (m_pMonitor)
266  m_pMonitor->releaseWriter();
267  }
268 
271  inline void clear()
272  {
273  if (m_pMonitor)
274  {
275  m_pMonitor->releaseWriter();
276  m_pMonitor = 0;
277  }
278  }
279 };
280 
281 //----------------------------------------------------------------------------
282 
284 
285 //----------------------------------------------------------------------------
286 
287 } // namespace salhelper
288 
289 #endif /* !_SALHELPER_MONITOR_HXX_ */
290 
291 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */