2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
18 * @file FBaseRtMonitor.h
19 * @brief This is the header file for the %Monitor class.
21 * This header file contains the declarations of the %Monitor class.
24 #ifndef _FBASE_RT_MONITOR_H_
25 #define _FBASE_RT_MONITOR_H_
27 #include <FBaseResult.h>
28 #include <FBaseObject.h>
31 namespace Tizen { namespace Base { namespace Runtime
38 * @brief This represents a monitor; a type of synchronization mechanism that provides acquire/release semantics by Enter() / Exit() as well as wait/notify semantics by Wait() / Notify() / NotifyAll().
42 * @final This class is not intended for extension.
44 * The %Monitor class represents a monitor. %Monitor is a synchronization mechanism that provides acquire/release semantics by Enter() / Exit() as well as wait/notify semantics by Wait() / Notify() / NotifyAll().
46 * For more information on the class features, see <a href="../org.tizen.native.appprogramming/html/guide/base/monitor.htm">Monitor</a>.
48 * The following examples demonstrates how to use the %Monitor class. In the examples, 2 classes, Consumer and Producer, share a space.
49 * Producer writes some data to this space, and Consumer reads it. Consumer and Producer run simultaneously.
50 * Consumer must not miss the data which Producer writes. In this case, Consumer and Producer share the monitor.
51 * Producer notifies Consumer that its writing action is done. Consumer waits for this notification, and reads the data after receiving it.
57 * using namespace Tizen::Base;
58 * using namespace Tizen::Base::Runtime;
65 * // This methods creates a new instance of the Producer thread
66 * Producer(int* pShared, Monitor* pMonitor);
67 * virtual ~Producer(void);
69 * // This methods waits for a starting Consumer and sets a value to the shared position
70 * // Finally it notifies the Consumer thread
71 * virtual Object* Run(void);
75 * Monitor* __pMonitor;
78 * Producer::Producer(int* pShared, Monitor* pMonitor)
79 * : __pShared(pShared)
80 * , __pMonitor(pMonitor)
84 * Producer::~Producer(void)
91 * if (__pShared && __pMonitor)
93 * // Begins a critical region
94 * result r = __pMonitor->Enter();
100 * // Waits for a starting Consumer
101 * r = __pMonitor->Wait();
107 * // Produces a number value 6 times
108 * for (int i = 0; i < 6; i++)
112 * // Notifies the consumer thread
113 * r = __pMonitor->Notify();
119 * AppLog("Producer::Run [%d]: Value at shared resource: %d\n", i, *__pShared);
120 * if (*__pShared == 5)
125 * // Waits until the consumer thread reads the value
126 * r = __pMonitor->Wait();
130 * __pMonitor->Exit();
142 * // This methods creates a new instance of the Consumer thread
143 * Consumer(int* pShared, Monitor* pMonitor);
144 * virtual ~Consumer(void);
146 * // This methods waits for a notification from the Producer thread and reads a value From the shared position
147 * virtual Tizen::Base::Object* Run(void);
151 * Monitor* __pMonitor;
155 * Consumer::Consumer(int* pShared, Monitor* pMonitor)
156 * : __pShared(pShared)
157 * , __pMonitor(pMonitor)
161 * Consumer::~Consumer(void)
166 * Consumer::Run(void)
168 * if (__pShared &&__pMonitor)
170 * // Begins a critical region
171 * result r = __pMonitor->Enter();
177 * // Notifies the producer thread
178 * r = __pMonitor->Notify();
184 * // Waits for a notification
185 * r = __pMonitor->Wait();
186 * while (!IsFailed(r))
188 * // Notifies the producer thread
189 * r = __pMonitor->Notify();
195 * AppLog("Consumer::Run: Value at shared resource: %d\n", *__pShared);
196 * if (*__pShared == 5)
201 * // Waits for a notification
202 * r = __pMonitor->Wait();
210 * // Exits the monitor
211 * r = __pMonitor->Exit();
219 * MyApp::TestProducerConsumer(void)
221 * result r = E_SUCCESS;
222 * Monitor* pMonitor = null;
223 * int* pShared = null;
225 * pMonitor = new Monitor;
228 * r = pMonitor->Construct();
231 * AppLog("Failed at Monitor Construct\n");
238 * Producer producer(pShared, pMonitor);
239 * Consumer consumer(pShared, pMonitor);
241 * producer.Construct();
242 * consumer.Construct();
261 class _OSP_EXPORT_ Monitor
262 : public Tizen::Base::Object
266 * This is the default constructor for this class.
270 * @remarks After creating an instance of this class, one of the
271 * Construct() methods must be called explicitly to initialize this instance.
277 * This is the destructor for this class.
281 virtual ~Monitor(void);
285 * Initializes this instance of %Monitor.
289 * @return An error code
290 * @exception E_SUCCESS The method is successful.
291 * @exception E_OUT_OF_MEMORY The memory is insufficient.
292 * @exception E_SYSTEM A system error has occurred.
294 result Construct(void);
297 * Acquires a lock for a monitor. @n
298 * Semantically, this method declares the beginning of the critical region for the monitor. This region
299 * ends with the Exit() method.
303 * @return An error code
304 * @exception E_SUCCESS The method is successful in acquiring the lock.
305 * @exception E_SYSTEM A system error has occurred.
306 * @remarks This method will block if called on already locked monitor object until monitor becomes available.
313 * Releases a lock for a monitor. @n
314 * Semantically, it declares the ending of the critical region for the monitor that begins with
315 * the Enter() method.
319 * @return An error code
320 * @exception E_SUCCESS The method is successful in releasing the lock.
321 * @exception E_SYSTEM A system error has occurred.
322 * @remarks This method should be called only after acquiring lock by Enter() call
328 * Releases the lock for the monitor and waits for the notification from the other thread. @n
329 * After receiving the notification, it tries to acquire the lock.
330 * Semantically, it waits until the other thread notifies it.
334 * @return An error code
335 * @exception E_SUCCESS The method is successful.
336 * @exception E_SYSTEM A system error has occurred.
337 * @remarks This method should be called only after acquiring lock by Enter() call
344 * Notifies one of the waiting threads. @n
345 * The selection of the notified thread is determined by the Linux scheduling policy.
349 * @return An error code
350 * @exception E_SUCCESS The method is successful.
351 * @exception E_SYSTEM A system error has occurred.
359 * Notifies all waiting threads.
363 * @return An error code
364 * @exception E_SUCCESS The method is successful.
365 * @exception E_SYSTEM A system error has occurred.
369 result NotifyAll(void);
372 Monitor(const Monitor& rhs);
373 Monitor& operator =(const Monitor& rhs);
376 friend class _MonitorImpl;
377 class _MonitorImpl * __pMonitorImpl;
380 } } } // Tizen::Base::Runtime
382 #endif // _FBASE_RT_MONITOR_H_