sync with tizen_2.0
[platform/framework/native/appfw.git] / inc / FBaseRtMonitor.h
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file                FBaseRtMonitor.h
20  * @brief               This is the header file for the %Monitor class.
21  *
22  * This header file contains the declarations of the %Monitor class.
23  */
24
25 #ifndef _FBASE_RT_MONITOR_H_
26 #define _FBASE_RT_MONITOR_H_
27
28 #include <FBaseResult.h>
29 #include <FBaseObject.h>
30
31
32 namespace Tizen { namespace Base { namespace Runtime
33 {
34
35 class _MonitorImpl;
36
37 /**
38  * @class   Monitor
39  * @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().
40  *
41  * @since 2.0
42  *
43  * @final This class is not intended for extension.
44  *
45  * 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  *
47  * For more information on the class features, see <a href="../org.tizen.native.appprogramming/html/guide/base/monitor.htm">Monitor</a>.
48  *
49  * The following examples demonstrates how to use the %Monitor class. In the examples, 2 classes, Consumer and Producer, share a space.
50  * Producer writes some data to this space, and Consumer reads it. Consumer and Producer run simultaneously.
51  * Consumer must not miss the data which Producer writes. In this case, Consumer and Producer share the monitor.
52  * Producer notifies Consumer that its writing action is done. Consumer waits for this notification, and reads the data after receiving it.
53  *
54  * @code
55  *
56  *  #include <FBase.h>
57  *
58  *  using namespace Tizen::Base;
59  *  using namespace Tizen::Base::Runtime;
60  *
61  *  class Producer
62  *              : public Thread
63  *  {
64  *  public:
65  *
66  *              // This methods creates a new instance of the Producer thread
67  *      Producer(int* pShared, Monitor* pMonitor);
68  *      virtual ~Producer(void);
69  *
70  *      // This methods waits for a starting Consumer and sets a value to the shared position
71  *      //      Finally it notifies the Consumer thread
72  *      virtual Object* Run(void);
73  *
74  *      private:
75  *                      int* __pShared;
76  *      Monitor* __pMonitor;
77  *  };
78  *
79  *  Producer::Producer(int* pShared, Monitor* pMonitor)
80  *      : __pShared(pShared)
81  *      , __pMonitor(pMonitor)
82  *  {
83  *  }
84  *
85  *  Producer::~Producer(void)
86  *  {
87  *  }
88  *
89  *  Object*
90  *  Producer::Run(void)
91  *  {
92  *      if (__pShared && __pMonitor)
93  *      {
94  *              // Begins a critical region
95  *              result r = __pMonitor->Enter();
96  *              if (IsFailed(r))
97  *              {
98  *                      goto CATCH2;
99  *              }
100  *
101  *              // Waits for a starting Consumer
102  *              r = __pMonitor->Wait();
103  *              if (IsFailed(r))
104  *              {
105  *                      goto CATCH1;
106  *              }
107  *
108  *              // Produces a number value 6 times
109  *              for (int i = 0; i < 6; i++)
110  *              {
111  *                      *__pShared = i;
112  *
113  *                      // Notifies the consumer thread
114  *                      r = __pMonitor->Notify();
115  *                      if (IsFailed(r))
116  *                      {
117  *                              goto CATCH1;
118  *                      }
119  *
120  *                      AppLog("Producer::Run [%d]: Value at shared resource: %d\n", i, *__pShared);
121  *                      if (*__pShared == 5)
122  *                      {
123  *                              break;
124  *                      }
125  *
126  *                      // Waits until the consumer thread reads the value
127  *                      r = __pMonitor->Wait();
128  *              }
129  *
130  *              CATCH1:
131  *              __pMonitor->Exit();
132  *              }
133  *
134  *  CATCH2:
135  *      return null;
136  *  }
137  *
138  *  class Consumer
139  *              : public Thread
140  *  {
141  *  public:
142  *
143  *      // This methods creates a new instance of the Consumer thread
144  *      Consumer(int* pShared, Monitor* pMonitor);
145  *      virtual ~Consumer(void);
146  *
147  *      // This methods waits for a notification from the Producer thread and reads a value From the shared position
148  *      virtual Tizen::Base::Object* Run(void);
149  *
150  *  private:
151  *      int* __pShared;
152  *      Monitor* __pMonitor;
153  *
154  *  };
155  *
156  *  Consumer::Consumer(int* pShared, Monitor* pMonitor)
157  *      : __pShared(pShared)
158  *      , __pMonitor(pMonitor)
159  *  {
160  *  }
161  *
162  *  Consumer::~Consumer(void)
163  *  {
164  *  }
165  *
166  *  Object*
167  *  Consumer::Run(void)
168  *  {
169  *      if (__pShared &&__pMonitor)
170  *      {
171  *              // Begins a critical region
172  *              result r = __pMonitor->Enter();
173  *              if (IsFailed(r))
174  *              {
175  *                      goto CATCH2;
176  *              }
177  *
178  *              // Notifies the producer thread
179  *              r = __pMonitor->Notify();
180  *              if (IsFailed(r))
181  *              {
182  *                      goto CATCH1;
183  *              }
184  *
185  *              // Waits for a notification
186  *              r = __pMonitor->Wait();
187  *              while (!IsFailed(r))
188  *              {
189  *                      // Notifies the producer thread
190  *                      r = __pMonitor->Notify();
191  *                      if (IsFailed(r))
192  *                      {
193  *                              goto CATCH1;
194  *                      }
195  *
196  *                      AppLog("Consumer::Run: Value at shared resource: %d\n", *__pShared);
197  *                      if (*__pShared == 5)
198  *                      {
199  *                              break;
200  *                      }
201  *
202  *                      // Waits for a notification
203  *                      r = __pMonitor->Wait();
204  *                      if (IsFailed(r))
205  *                      {
206  *                              goto CATCH1;
207  *                      }
208  *              }
209  *
210  *      CATCH1:
211  *              // Exits the monitor
212  *              r = __pMonitor->Exit();
213  *      }
214  *
215  *  CATCH2:
216  *      return null;
217  *  }
218  *
219  *  void
220  *  MyApp::TestProducerConsumer(void)
221  *  {
222  *      result r = E_SUCCESS;
223  *      Monitor* pMonitor = null;
224  *      int* pShared = null;
225  *
226  *      pMonitor = new Monitor;
227  *      if (pMonitor)
228  *      {
229  *              r = pMonitor->Construct();
230  *              if (IsFailed(r))
231  *              {
232  *                      AppLog("Failed at Monitor Construct\n");
233  *                      goto CATCH;
234  *              }
235  *
236  *              pShared = new int;
237  *              if (pShared)
238  *              {
239  *                      Producer producer(pShared, pMonitor);
240  *                      Consumer consumer(pShared, pMonitor);
241  *
242  *                      producer.Construct();
243  *                      consumer.Construct();
244  *
245  *                      producer.Start();
246  *                      consumer.Start();
247  *
248  *                      producer.Join();
249  *                      consumer.Join();
250  *              }
251  *      }
252  *
253  *  CATCH:
254  *      delete pShared;
255  *      delete pMonitor;
256  *  }
257  *
258  * @endcode
259  *
260  */
261
262 class _OSP_EXPORT_ Monitor
263         : public Tizen::Base::Object
264 {
265 public:
266         /**
267          * This is the default constructor for this class.
268          *
269          * @since 2.0
270          *
271          * @remarks     After creating an instance of this class, one of the
272          *                      Construct() methods must be called explicitly to initialize this instance.
273          */
274         Monitor(void);
275
276
277         /**
278          * This is the destructor for this class.
279          *
280          * @since 2.0
281          */
282         virtual ~Monitor(void);
283
284
285         /**
286          * Initializes this instance of %Monitor.
287          *
288          * @since 2.0
289          *
290          * @return              An error code
291          * @exception   E_SUCCESS       The method is successful.
292          * @exception   E_OUT_OF_MEMORY The memory is insufficient.
293          * @exception   E_SYSTEM        A system error has occurred.
294          */
295         result Construct(void);
296
297         /**
298          * Acquires a lock for a monitor. @n
299          * Semantically, this method declares the beginning of the critical region for the monitor. This region
300          * ends with the Exit() method.
301          *
302          * @since 2.0
303          *
304          * @return              An error code
305          * @exception   E_SUCCESS       The method is successful in acquiring the lock.
306          * @exception   E_SYSTEM        A system error has occurred.
307          * @remarks             This method will block if called on already locked monitor object until monitor becomes availalbe.
308          * @see                 Exit()
309          */
310         result Enter(void);
311
312
313         /**
314          * Releases a lock for a monitor. @n
315          * Semantically, it declares the ending of the critical region for the monitor that begins with
316          * the Enter() method.
317          *
318          * @since 2.0
319          *
320          * @return              An error code
321          * @exception   E_SUCCESS       The method is successful in releasing the lock.
322          * @exception   E_SYSTEM        A system error has occurred.
323          * @remarks             This method should be called only after acquiring lock by Enter() call
324          * @see                 Enter()
325          */
326         result Exit(void);
327
328         /**
329          * Releases the lock for the monitor and waits for the notification from the other thread. @n
330          * After receiving the notification, it tries to acquire the lock.
331          * Semantically, it waits until the other thread notifies it.
332          *
333          * @since 2.0
334          *
335          * @return              An error code
336          * @exception   E_SUCCESS       The method is successful.
337          * @exception   E_SYSTEM        A system error has occurred.
338          * @remarks             This method should be called only after acquiring lock by Enter() call
339          * @see                 Notify(), NotifyAll()
340          */
341         result Wait(void);
342
343         /**
344          * Notifies one of the waiting threads. @n
345          * The selection of the notified thread is determined by the Linux scheduling policy.
346          *
347          * @since 2.0
348          *
349          * @return              An error code
350          * @exception   E_SUCCESS       The method is successful.
351          * @exception   E_SYSTEM        A system error has occurred.
352          * @see                 NotifyAll(), Wait()
353          */
354         result Notify(void);
355
356
357         /**
358          * Notifies all waiting threads.
359          *
360          * @since 2.0
361          *
362          * @return              An error code
363          * @exception   E_SUCCESS       The method is successful.
364          * @exception   E_SYSTEM        A system error has occurred.
365          * @see                 Notify(), Wait()
366          */
367         result NotifyAll(void);
368
369 private:
370         Monitor(const Monitor& rhs);
371         Monitor& operator =(const Monitor& rhs);
372
373 private:
374         friend class _MonitorImpl;
375         class _MonitorImpl * __pMonitorImpl;
376 }; // Monitor
377
378 } } } // Tizen::Base::Runtime
379
380 #endif // _FBASE_RT_MONITOR_H_