Fix the boiler plate codes
[platform/framework/native/appfw.git] / src / base / runtime / FBaseRt_WaitingLoopImpl.cpp
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        FBaseRt_WaitingLoopImpl.cpp
19  * @brief       This is the implementation for the %_WaitingLoopImpl class.
20  *
21  */
22
23 #include <Ecore.h>
24 #include <unique_ptr.h>
25 #include <FBaseRtWaitingLoop.h>
26 #include <FBaseSysLog.h>
27 #include "FBaseRt_ThreadImpl.h"
28 #include "FBaseRt_EventDispatcher.h"
29 #include "FBaseRt_WaitingLoopImpl.h"
30
31 using namespace Tizen::Base;
32
33 namespace Tizen { namespace Base { namespace Runtime
34 {
35
36
37 static int __sleepTime = 10;
38 static int __waitingCount = 10;
39 static int __waitingRepeatableTime = 100;
40 static int __maxTime = 50;
41
42 _WaitingLoopImpl::_WaitingLoopImpl(void)
43         : __pTimer(null)
44         , __timeout(false)
45         , __notifyWait(true)
46         , __threadType(THREAD_TYPE_MAIN)
47         , __pGmainContext(null)
48         , __waitType(WAIT_DEFAULT)
49         , __waitStatus(WAIT_OFF)
50         , __pWaitingLoopCondition(null)
51         , __timerCalledCount(0)
52         , __maxTimeout(10000)
53 {
54
55 }
56
57 _WaitingLoopImpl::~_WaitingLoopImpl(void)
58 {
59         if (__pTimer != null)
60         {
61                 __pTimer->Cancel();
62                 delete __pTimer;
63         }
64 }
65
66 result
67 _WaitingLoopImpl::Construct(void)
68 {
69         _ThreadImpl* pThreadImpl = _ThreadImpl::GetCurrentThreadImpl();
70         SysTryReturnResult(NID_BASE_RT, pThreadImpl != null, E_OBJ_NOT_FOUND,"This is not a OSP thread.");
71         
72         ThreadType threadType = pThreadImpl->GetThreadType();
73         
74         if(threadType == THREAD_TYPE_MAIN)
75         {
76                 SysLog(NID_BASE_RT, "This is a the main thread which supports the waiting loop using ecore.");
77         }
78         else if(threadType == THREAD_TYPE_EVENT_DRIVEN)
79         {
80                 SysLog(NID_BASE_RT, "This is a a event driven thread which supports the waiting loop using glib.");
81                 
82                 _EventDispatcher* pEventDispatcher = _EventDispatcher::GetCurrentEventDispatcher();
83                 if (pEventDispatcher != null)
84                 {
85                         __pGmainContext = pEventDispatcher->GetGMainContext();  
86                         SysLog(NID_BASE_RT, "This thread already has the gmaincontext.");       
87                 }
88                 else
89                 {
90                         SysLog(NID_BASE_RT, "This thread does not create the gmaincontext.");                   
91                 }
92         }       
93         else
94         {
95                 SysLog(NID_BASE_RT, "This ia a worker thread which does not support the waiting loop.");
96                 return E_INVALID_OPERATION;
97         }
98         __threadType = threadType;
99
100         std::unique_ptr< Timer > pTimer(new (std::nothrow) Timer());
101         SysTryReturnResult(NID_BASE_RT, pThreadImpl != null, E_OUT_OF_MEMORY,"Fail to create a timer instance.");
102         
103         result r = pTimer->Construct(*this); 
104         SysTryReturn(NID_BASE_RT, r == E_SUCCESS, null, r,"[%s]Fail to create a timer instance.", GetErrorMessage(r));
105
106         __pTimer = pTimer.release();
107         return r;
108 }
109
110 WaitingLoop* 
111 _WaitingLoopImpl::GetInstanceN(void)
112 {
113         std::unique_ptr< _WaitingLoopImpl > pWaitingLoopImpl(new (std::nothrow) _WaitingLoopImpl());
114         SysTryReturn(NID_APP, pWaitingLoopImpl != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY]Fail to create a _WaitingLoopImpl instance.");
115         
116         result r = pWaitingLoopImpl->Construct();       
117         SysTryReturn(NID_BASE_RT, r == E_SUCCESS, null, r,"[%s]Fail to create a _WaitingLoopImpl instance.", GetErrorMessage(r));
118
119         WaitingLoop* pWaitingLoop = new WaitingLoop();
120         SysTryReturn(NID_BASE_RT, pWaitingLoop != null, null, E_OUT_OF_MEMORY,"[E_OUT_OF_MEMORY]Fail to create a WaitingLoop instance.");
121
122         pWaitingLoop->__pWaitingLoopImpl = pWaitingLoopImpl.release();
123         
124         return pWaitingLoop;
125 }
126
127 result 
128 _WaitingLoopImpl::Wait(int timeout)
129 {
130         SysTryReturnResult(NID_BASE_RT, __waitStatus == WAIT_OFF, E_INVALID_STATE, "The waiting loop is waiting on a thread.");
131         
132         __timeout = false;
133         __waitType = WAIT_TIMEOUT;
134
135         result r = __pTimer->Start(timeout);
136
137         SysTryReturn(NID_BASE_RT, r == E_SUCCESS, r, r,"[%s]Timer does not start.", GetErrorMessage(r));
138
139         __waitStatus = WAIT_ON;
140         if (__threadType == THREAD_TYPE_MAIN)
141         {
142                 ecore_main_loop_begin();
143                 SysLog(NID_BASE_RT, "The waiting loop(ecore) is stopped.");
144         }
145         else
146         {
147                 while(!__timeout && __notifyWait)
148                 {       
149                         g_main_context_iteration(__pGmainContext, TRUE);
150                         Thread::Sleep(__sleepTime);
151                 }
152                 SysLog(NID_BASE_RT, "The waiting loop(glib) is stopped.");
153         }
154         __pTimer->Cancel();
155         __waitStatus = WAIT_OFF;
156
157         SysTryReturn(NID_BASE_RT, __timeout != true, E_TIMEOUT, E_TIMEOUT, "[E_TIMEOUT]The time is expired.");
158         
159         return E_SUCCESS;
160 }
161
162 result 
163 _WaitingLoopImpl::Wait(IWaitingLoopCondition& condition)
164 {
165         SysTryReturnResult(NID_BASE_RT, __waitStatus == WAIT_OFF, E_INVALID_STATE, "[E_INVALID_STATUS]The waiting loop is waiting on a thread.");
166
167         __timeout = false;
168         __waitType = WAIT_CONDITION;
169         __pWaitingLoopCondition = &condition;
170
171         if (__threadType == THREAD_TYPE_MAIN)
172         {
173                 result r = __pTimer->StartAsRepeatable(__waitingRepeatableTime);
174                 SysTryReturn(NID_BASE_RT, r == E_SUCCESS, r, r, "[%s]Timer does not start.", GetErrorMessage(r));
175         
176                 __waitStatus = WAIT_ON;
177                 ecore_main_loop_begin();
178                 SysLog(NID_BASE_RT, "The waiting loop(ecore) is stopped.");
179
180                 __pTimer->Cancel();
181         }
182         else
183         {
184                 __waitStatus = WAIT_ON;
185                 while(!__pWaitingLoopCondition->IsMet() && __notifyWait)
186                 {
187                         g_main_context_iteration(__pGmainContext, FALSE);
188                         Thread::Sleep(__sleepTime);
189                 }
190                 SysLog(NID_BASE_RT, "The waiting loop(glib) is stopped.");
191         }
192         __waitStatus = WAIT_OFF;
193
194         return E_SUCCESS;
195 }
196
197 result 
198 _WaitingLoopImpl::Wait(int timeout, IWaitingLoopCondition& condition)
199 {
200         SysTryReturnResult(NID_BASE_RT, __waitStatus == WAIT_OFF, E_INVALID_STATE, "[E_INVALID_STATUS]The waiting loop is waiting on a thread.");
201
202         __timeout = false;
203         __timerCalledCount = 0;
204         __waitType = WAIT_TIMEOUT_CONDITION;
205         __pWaitingLoopCondition = &condition;
206
207         if (timeout < __waitingRepeatableTime)
208         {
209                 result r = __pTimer->StartAsRepeatable(__waitingRepeatableTime);
210                 SysTryReturn(NID_BASE_RT, r == E_SUCCESS, r, r, "[%s]Timer does not start.", GetErrorMessage(r));
211         }
212         else
213         {
214                 result r = __pTimer->StartAsRepeatable(timeout/10);
215                 SysTryReturn(NID_BASE_RT, r == E_SUCCESS, r, r, "[%s]Timer does not start.", GetErrorMessage(r));       
216         }
217         __waitStatus = WAIT_ON;
218         if (__threadType == THREAD_TYPE_MAIN)
219         {
220                 ecore_main_loop_begin();
221                 SysLog(NID_BASE_RT, "The waiting loop(ecore) is stopped.");
222         }
223         else
224         {
225                 while(!__pWaitingLoopCondition->IsMet() && __timeout && __notifyWait)
226                 {
227                         g_main_context_iteration(__pGmainContext, TRUE);
228                         Thread::Sleep(__sleepTime);
229                 }
230                 SysLog(NID_BASE_RT, "The waiting loop(glib) is stopped.");
231         }
232
233         __pTimer->Cancel();
234         __waitStatus = WAIT_OFF;
235
236         SysTryReturn(NID_BASE_RT, __timeout != true, E_TIMEOUT, E_TIMEOUT, "[E_TIMEOUT]The time is expired.");
237
238         return E_SUCCESS;
239 }
240
241 void 
242 _WaitingLoopImpl::Notify(void)
243 {
244         SysTryReturnVoidResult(NID_BASE_RT, __waitStatus == WAIT_ON, E_INVALID_STATE, "[E_INVALID_STATUS]The waiting loop is not waiting on a thread.");
245         __notifyWait = false;
246
247         SysLog(NID_BASE_RT, "The waiting loop would be stopped from Notifying.");
248
249         if (__threadType == THREAD_TYPE_MAIN)
250         {
251                 ecore_main_loop_quit();
252         }
253 }
254
255 void 
256 _WaitingLoopImpl::SetMaxTimeoutForWaiting(int timeout)
257 {
258         if (timeout < __maxTime)
259         {
260                 __maxTimeout = __maxTime;
261         }
262         else
263         {
264                 __maxTimeout = timeout;
265         }
266 }
267
268 void 
269 _WaitingLoopImpl::OnTimerExpired(Timer& timer)
270 {
271         if (__threadType == THREAD_TYPE_MAIN)
272         {
273                 if (__waitType == WAIT_TIMEOUT)
274                 {
275                         ecore_main_loop_quit();
276                         SysLog(NID_BASE_RT, "The waiting loop is stopped from time out.");
277                         __timeout = true;
278                 }
279                 else if ((__waitType == WAIT_CONDITION) && __pWaitingLoopCondition->IsMet())
280                 {
281                         ecore_main_loop_quit(); 
282                         SysLog(NID_BASE_RT, "The waiting loop  is stopped from firing condition.");
283                 }
284                 else if (__waitType == WAIT_TIMEOUT_CONDITION)
285                 {
286                         __timerCalledCount++;
287                         if (__timerCalledCount == __waitingCount)
288                         {
289                                 ecore_main_loop_quit(); 
290                                 SysLog(NID_BASE_RT, "The waiting loop is stopped from time out.");
291                                 __timeout = true;
292                         }
293                         else
294                         {
295                                 if (__pWaitingLoopCondition->IsMet())
296                                 {
297                                         ecore_main_loop_quit(); 
298                                         SysLog(NID_BASE_RT, "The waiting loop is stopped from firing condition.");      
299                                 }       
300                         }               
301                 }
302         }
303         else
304         {
305                 if (__waitType == WAIT_TIMEOUT)
306                 {
307                         __timeout = true;
308                         SysLog(NID_BASE_RT, "The waiting loop is stopped from time out.");
309                 }
310                 else if (__waitType == WAIT_TIMEOUT_CONDITION)
311                 {
312                         __timerCalledCount++;
313                         if (__timerCalledCount == __waitingCount)
314                         {
315                                 __timeout = true;
316                                 SysLog(NID_BASE_RT, "The waiting loop is stopped from time out.");
317                         }
318                 }
319         }
320 }
321
322 bool
323 _WaitingLoopImpl::IsSameThread(void)
324 {
325         _ThreadImpl* pThreadImpl = _ThreadImpl::GetCurrentThreadImpl();
326         SysTryReturn(NID_BASE_RT, pThreadImpl != null, false, E_OBJ_NOT_FOUND,"This is not a OSP thread.");
327         
328         ThreadType threadType = pThreadImpl->GetThreadType();
329
330         if (__threadType == threadType)
331         {
332                 SysLog(NID_BASE_RT, "The waiting loop is working on the current thread.");
333                 return true;
334         }
335         else
336         {
337                 SysLog(NID_BASE_RT, "The waiting loop is working on another thread.");
338                 return false;
339         }       
340 }
341
342 } } } // Tizen::Base::Runtime
343