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