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 FBaseRt_WaitingLoopImpl.cpp
19 * @brief This is the implementation for the %_WaitingLoopImpl class.
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"
31 using namespace Tizen::Base;
33 namespace Tizen { namespace Base { namespace Runtime
37 static int __sleepTime = 10;
38 static int __waitingCount = 10;
39 static int __waitingRepeatableTime = 100;
40 static int __maxTime = 50;
42 _WaitingLoopImpl::_WaitingLoopImpl(void)
46 , __threadType(THREAD_TYPE_MAIN)
47 , __pGmainContext(null)
48 , __waitType(WAIT_DEFAULT)
49 , __waitStatus(WAIT_OFF)
50 , __pWaitingLoopCondition(null)
51 , __timerCalledCount(0)
57 _WaitingLoopImpl::~_WaitingLoopImpl(void)
67 _WaitingLoopImpl::Construct(void)
69 _ThreadImpl* pThreadImpl = _ThreadImpl::GetCurrentThreadImpl();
70 SysTryReturnResult(NID_BASE_RT, pThreadImpl != null, E_OBJ_NOT_FOUND,"This is not a OSP thread.");
72 ThreadType threadType = pThreadImpl->GetThreadType();
74 if(threadType == THREAD_TYPE_MAIN)
76 SysLog(NID_BASE_RT, "This is a the main thread which supports the waiting loop using ecore.");
78 else if(threadType == THREAD_TYPE_EVENT_DRIVEN)
80 SysLog(NID_BASE_RT, "This is a a event driven thread which supports the waiting loop using glib.");
82 _EventDispatcher* pEventDispatcher = _EventDispatcher::GetCurrentEventDispatcher();
83 if (pEventDispatcher != null)
85 __pGmainContext = pEventDispatcher->GetGMainContext();
86 SysLog(NID_BASE_RT, "This thread already has the gmaincontext.");
90 SysLog(NID_BASE_RT, "This thread does not create the gmaincontext.");
95 SysLog(NID_BASE_RT, "This ia a worker thread which does not support the waiting loop.");
96 return E_INVALID_OPERATION;
98 __threadType = threadType;
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.");
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));
106 __pTimer = pTimer.release();
111 _WaitingLoopImpl::GetInstanceN(void)
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.");
116 result r = pWaitingLoopImpl->Construct();
117 SysTryReturn(NID_BASE_RT, r == E_SUCCESS, null, r,"[%s]Fail to create a _WaitingLoopImpl instance.", GetErrorMessage(r));
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.");
122 pWaitingLoop->__pWaitingLoopImpl = pWaitingLoopImpl.release();
128 _WaitingLoopImpl::Wait(int timeout)
130 SysTryReturnResult(NID_BASE_RT, __waitStatus == WAIT_OFF, E_INVALID_STATE, "The waiting loop is waiting on a thread.");
133 __waitType = WAIT_TIMEOUT;
135 result r = __pTimer->Start(timeout);
137 SysTryReturn(NID_BASE_RT, r == E_SUCCESS, r, r,"[%s]Timer does not start.", GetErrorMessage(r));
139 __waitStatus = WAIT_ON;
140 if (__threadType == THREAD_TYPE_MAIN)
142 ecore_main_loop_begin();
143 SysLog(NID_BASE_RT, "The waiting loop(ecore) is stopped.");
147 while(!__timeout && __notifyWait)
149 g_main_context_iteration(__pGmainContext, TRUE);
150 Thread::Sleep(__sleepTime);
152 SysLog(NID_BASE_RT, "The waiting loop(glib) is stopped.");
155 __waitStatus = WAIT_OFF;
157 SysTryReturn(NID_BASE_RT, __timeout != true, E_TIMEOUT, E_TIMEOUT, "[E_TIMEOUT]The time is expired.");
163 _WaitingLoopImpl::Wait(IWaitingLoopCondition& condition)
165 SysTryReturnResult(NID_BASE_RT, __waitStatus == WAIT_OFF, E_INVALID_STATE, "[E_INVALID_STATUS]The waiting loop is waiting on a thread.");
168 __waitType = WAIT_CONDITION;
169 __pWaitingLoopCondition = &condition;
171 if (__threadType == THREAD_TYPE_MAIN)
173 result r = __pTimer->StartAsRepeatable(__waitingRepeatableTime);
174 SysTryReturn(NID_BASE_RT, r == E_SUCCESS, r, r, "[%s]Timer does not start.", GetErrorMessage(r));
176 __waitStatus = WAIT_ON;
177 ecore_main_loop_begin();
178 SysLog(NID_BASE_RT, "The waiting loop(ecore) is stopped.");
184 __waitStatus = WAIT_ON;
185 while(!__pWaitingLoopCondition->IsMet() && __notifyWait)
187 g_main_context_iteration(__pGmainContext, FALSE);
188 Thread::Sleep(__sleepTime);
190 SysLog(NID_BASE_RT, "The waiting loop(glib) is stopped.");
192 __waitStatus = WAIT_OFF;
198 _WaitingLoopImpl::Wait(int timeout, IWaitingLoopCondition& condition)
200 SysTryReturnResult(NID_BASE_RT, __waitStatus == WAIT_OFF, E_INVALID_STATE, "[E_INVALID_STATUS]The waiting loop is waiting on a thread.");
203 __timerCalledCount = 0;
204 __waitType = WAIT_TIMEOUT_CONDITION;
205 __pWaitingLoopCondition = &condition;
207 if (timeout < __waitingRepeatableTime)
209 result r = __pTimer->StartAsRepeatable(__waitingRepeatableTime);
210 SysTryReturn(NID_BASE_RT, r == E_SUCCESS, r, r, "[%s]Timer does not start.", GetErrorMessage(r));
214 result r = __pTimer->StartAsRepeatable(timeout/10);
215 SysTryReturn(NID_BASE_RT, r == E_SUCCESS, r, r, "[%s]Timer does not start.", GetErrorMessage(r));
217 __waitStatus = WAIT_ON;
218 if (__threadType == THREAD_TYPE_MAIN)
220 ecore_main_loop_begin();
221 SysLog(NID_BASE_RT, "The waiting loop(ecore) is stopped.");
225 while(!__pWaitingLoopCondition->IsMet() && __timeout && __notifyWait)
227 g_main_context_iteration(__pGmainContext, TRUE);
228 Thread::Sleep(__sleepTime);
230 SysLog(NID_BASE_RT, "The waiting loop(glib) is stopped.");
234 __waitStatus = WAIT_OFF;
236 SysTryReturn(NID_BASE_RT, __timeout != true, E_TIMEOUT, E_TIMEOUT, "[E_TIMEOUT]The time is expired.");
242 _WaitingLoopImpl::Notify(void)
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;
247 SysLog(NID_BASE_RT, "The waiting loop would be stopped from Notifying.");
249 if (__threadType == THREAD_TYPE_MAIN)
251 ecore_main_loop_quit();
256 _WaitingLoopImpl::SetMaxTimeoutForWaiting(int timeout)
258 if (timeout < __maxTime)
260 __maxTimeout = __maxTime;
264 __maxTimeout = timeout;
269 _WaitingLoopImpl::OnTimerExpired(Timer& timer)
271 if (__threadType == THREAD_TYPE_MAIN)
273 if (__waitType == WAIT_TIMEOUT)
275 ecore_main_loop_quit();
276 SysLog(NID_BASE_RT, "The waiting loop is stopped from time out.");
279 else if ((__waitType == WAIT_CONDITION) && __pWaitingLoopCondition->IsMet())
281 ecore_main_loop_quit();
282 SysLog(NID_BASE_RT, "The waiting loop is stopped from firing condition.");
284 else if (__waitType == WAIT_TIMEOUT_CONDITION)
286 __timerCalledCount++;
287 if (__timerCalledCount == __waitingCount)
289 ecore_main_loop_quit();
290 SysLog(NID_BASE_RT, "The waiting loop is stopped from time out.");
295 if (__pWaitingLoopCondition->IsMet())
297 ecore_main_loop_quit();
298 SysLog(NID_BASE_RT, "The waiting loop is stopped from firing condition.");
305 if (__waitType == WAIT_TIMEOUT)
308 SysLog(NID_BASE_RT, "The waiting loop is stopped from time out.");
310 else if (__waitType == WAIT_TIMEOUT_CONDITION)
312 __timerCalledCount++;
313 if (__timerCalledCount == __waitingCount)
316 SysLog(NID_BASE_RT, "The waiting loop is stopped from time out.");
323 _WaitingLoopImpl::IsSameThread(void)
325 _ThreadImpl* pThreadImpl = _ThreadImpl::GetCurrentThreadImpl();
326 SysTryReturn(NID_BASE_RT, pThreadImpl != null, false, E_OBJ_NOT_FOUND,"This is not a OSP thread.");
328 ThreadType threadType = pThreadImpl->GetThreadType();
330 if (__threadType == threadType)
332 SysLog(NID_BASE_RT, "The waiting loop is working on the current thread.");
337 SysLog(NID_BASE_RT, "The waiting loop is working on another thread.");
342 } } } // Tizen::Base::Runtime