2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
9 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 * @file FBaseRt_WaitingLoopImpl.cpp
20 * @brief This is the implementation for the %_WaitingLoopImpl class.
25 #include <unique_ptr.h>
26 #include <FBaseRtWaitingLoop.h>
27 #include <FBaseSysLog.h>
28 #include "FBaseRt_ThreadImpl.h"
29 #include "FBaseRt_EventDispatcher.h"
30 #include "FBaseRt_WaitingLoopImpl.h"
32 using namespace Tizen::Base;
34 namespace Tizen { namespace Base { namespace Runtime
38 static int __sleepTime = 10;
39 static int __waitingCount = 10;
40 static int __waitingRepeatableTime = 100;
41 static int __maxTime = 50;
43 _WaitingLoopImpl::_WaitingLoopImpl(void)
47 , __threadType(THREAD_TYPE_MAIN)
48 , __pGmainContext(null)
49 , __waitType(WAIT_DEFAULT)
50 , __waitStatus(WAIT_OFF)
51 , __pWaitingLoopCondition(null)
52 , __timerCalledCount(0)
58 _WaitingLoopImpl::~_WaitingLoopImpl(void)
68 _WaitingLoopImpl::Construct(void)
70 _ThreadImpl* pThreadImpl = _ThreadImpl::GetCurrentThreadImpl();
71 SysTryReturnResult(NID_BASE_RT, pThreadImpl != null, E_OBJ_NOT_FOUND,"This is not a OSP thread.");
73 ThreadType threadType = pThreadImpl->GetThreadType();
75 if(threadType == THREAD_TYPE_MAIN)
77 SysLog(NID_BASE_RT, "This is a the main thread which supports the waiting loop using ecore.");
79 else if(threadType == THREAD_TYPE_EVENT_DRIVEN)
81 SysLog(NID_BASE_RT, "This is a a event driven thread which supports the waiting loop using glib.");
83 _EventDispatcher* pEventDispatcher = _EventDispatcher::GetCurrentEventDispatcher();
84 if (pEventDispatcher != null)
86 __pGmainContext = pEventDispatcher->GetGMainContext();
87 SysLog(NID_BASE_RT, "This thread already has the gmaincontext.");
91 SysLog(NID_BASE_RT, "This thread does not create the gmaincontext.");
96 SysLog(NID_BASE_RT, "This ia a worker thread which does not support the waiting loop.");
97 return E_INVALID_OPERATION;
99 __threadType = threadType;
101 std::unique_ptr< Timer > pTimer(new (std::nothrow) Timer());
102 SysTryReturnResult(NID_BASE_RT, pThreadImpl != null, E_OUT_OF_MEMORY,"Fail to create a timer instance.");
104 result r = pTimer->Construct(*this);
105 SysTryReturn(NID_BASE_RT, r == E_SUCCESS, null, r,"[%s]Fail to create a timer instance.", GetErrorMessage(r));
107 __pTimer = pTimer.release();
112 _WaitingLoopImpl::GetInstanceN(void)
114 std::unique_ptr< _WaitingLoopImpl > pWaitingLoopImpl(new (std::nothrow) _WaitingLoopImpl());
115 SysTryReturn(NID_APP, pWaitingLoopImpl != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY]Fail to create a _WaitingLoopImpl instance.");
117 result r = pWaitingLoopImpl->Construct();
118 SysTryReturn(NID_BASE_RT, r == E_SUCCESS, null, r,"[%s]Fail to create a _WaitingLoopImpl instance.", GetErrorMessage(r));
120 WaitingLoop* pWaitingLoop = new WaitingLoop();
121 SysTryReturn(NID_BASE_RT, pWaitingLoop != null, null, E_OUT_OF_MEMORY,"[E_OUT_OF_MEMORY]Fail to create a WaitingLoop instance.");
123 pWaitingLoop->__pWaitingLoopImpl = pWaitingLoopImpl.release();
129 _WaitingLoopImpl::Wait(int timeout)
131 SysTryReturnResult(NID_BASE_RT, __waitStatus == WAIT_OFF, E_INVALID_STATE, "The waiting loop is waiting on a thread.");
134 __waitType = WAIT_TIMEOUT;
136 if (__maxTimeout < timeout)
138 timeout = __maxTimeout;
141 result r = __pTimer->Start(timeout);
143 SysTryReturn(NID_BASE_RT, r == E_SUCCESS, r, r,"[%s]Timer does not start.", GetErrorMessage(r));
145 __waitStatus = WAIT_ON;
146 if (__threadType == THREAD_TYPE_MAIN)
148 ecore_main_loop_begin();
149 SysLog(NID_BASE_RT, "The waiting loop(ecore) is stopped.");
153 while(!__timeout && __notifyWait)
155 g_main_context_iteration(__pGmainContext, TRUE);
156 Thread::Sleep(__sleepTime);
158 SysLog(NID_BASE_RT, "The waiting loop(glib) is stopped.");
161 __waitStatus = WAIT_OFF;
163 SysTryReturn(NID_BASE_RT, __timeout != true, E_TIMEOUT, E_TIMEOUT, "[E_TIMEOUT]The time is expired.");
169 _WaitingLoopImpl::Wait(IWaitingLoopCondition& condition)
171 SysTryReturnResult(NID_BASE_RT, __waitStatus == WAIT_OFF, E_INVALID_STATE, "[E_INVALID_STATUS]The waiting loop is waiting on a thread.");
174 __waitType = WAIT_CONDITION;
175 __pWaitingLoopCondition = &condition;
177 if (__threadType == THREAD_TYPE_MAIN)
179 result r = __pTimer->StartAsRepeatable(__waitingRepeatableTime);
180 SysTryReturn(NID_BASE_RT, r == E_SUCCESS, r, r, "[%s]Timer does not start.", GetErrorMessage(r));
182 __waitStatus = WAIT_ON;
183 ecore_main_loop_begin();
184 SysLog(NID_BASE_RT, "The waiting loop(ecore) is stopped.");
190 __waitStatus = WAIT_ON;
191 while(!__pWaitingLoopCondition->IsMet() && __notifyWait)
193 g_main_context_iteration(__pGmainContext, FALSE);
194 Thread::Sleep(__sleepTime);
196 SysLog(NID_BASE_RT, "The waiting loop(glib) is stopped.");
198 __waitStatus = WAIT_OFF;
204 _WaitingLoopImpl::Wait(int timeout, IWaitingLoopCondition& condition)
206 SysTryReturnResult(NID_BASE_RT, __waitStatus == WAIT_OFF, E_INVALID_STATE, "[E_INVALID_STATUS]The waiting loop is waiting on a thread.");
209 __timerCalledCount = 0;
210 __waitType = WAIT_TIMEOUT_CONDITION;
211 __pWaitingLoopCondition = &condition;
213 if(timeout > __maxTimeout)
215 timeout = __maxTimeout;
218 if (timeout < __waitingRepeatableTime)
220 result r = __pTimer->StartAsRepeatable(__waitingRepeatableTime);
221 SysTryReturn(NID_BASE_RT, r == E_SUCCESS, r, r, "[%s]Timer does not start.", GetErrorMessage(r));
225 result r = __pTimer->StartAsRepeatable(timeout/10);
226 SysTryReturn(NID_BASE_RT, r == E_SUCCESS, r, r, "[%s]Timer does not start.", GetErrorMessage(r));
228 __waitStatus = WAIT_ON;
229 if (__threadType == THREAD_TYPE_MAIN)
231 ecore_main_loop_begin();
232 SysLog(NID_BASE_RT, "The waiting loop(ecore) is stopped.");
236 while(!__pWaitingLoopCondition->IsMet() && __timeout && __notifyWait)
238 g_main_context_iteration(__pGmainContext, TRUE);
239 Thread::Sleep(__sleepTime);
241 SysLog(NID_BASE_RT, "The waiting loop(glib) is stopped.");
245 __waitStatus = WAIT_OFF;
247 SysTryReturn(NID_BASE_RT, __timeout != true, E_TIMEOUT, E_TIMEOUT, "[E_TIMEOUT]The time is expired.");
253 _WaitingLoopImpl::Notify(void)
255 SysTryReturnVoidResult(NID_BASE_RT, __waitStatus == WAIT_ON, E_INVALID_STATE, "[E_INVALID_STATUS]The waiting loop is not waiting on a thread.");
256 __notifyWait = false;
258 SysLog(NID_BASE_RT, "The waiting loop would be stopped from Notifying.");
260 if (__threadType == THREAD_TYPE_MAIN)
262 ecore_main_loop_quit();
267 _WaitingLoopImpl::SetMaxTimeoutForWaiting(int timeout)
269 if (timeout < __maxTime)
271 __maxTimeout = __maxTime;
275 __maxTimeout = timeout;
280 _WaitingLoopImpl::OnTimerExpired(Timer& timer)
282 if (__threadType == THREAD_TYPE_MAIN)
284 if (__waitType == WAIT_TIMEOUT)
286 ecore_main_loop_quit();
287 SysLog(NID_BASE_RT, "The waiting loop is stopped from time out.");
290 else if ((__waitType == WAIT_CONDITION) && __pWaitingLoopCondition->IsMet())
292 ecore_main_loop_quit();
293 SysLog(NID_BASE_RT, "The waiting loop is stopped from firing condition.");
295 else if (__waitType == WAIT_TIMEOUT_CONDITION)
297 __timerCalledCount++;
298 if (__timerCalledCount == __waitingCount)
300 ecore_main_loop_quit();
301 SysLog(NID_BASE_RT, "The waiting loop is stopped from time out.");
306 if (__pWaitingLoopCondition->IsMet())
308 ecore_main_loop_quit();
309 SysLog(NID_BASE_RT, "The waiting loop is stopped from firing condition.");
316 if (__waitType == WAIT_TIMEOUT)
319 SysLog(NID_BASE_RT, "The waiting loop is stopped from time out.");
321 else if (__waitType == WAIT_TIMEOUT_CONDITION)
323 __timerCalledCount++;
324 if (__timerCalledCount == __waitingCount)
327 SysLog(NID_BASE_RT, "The waiting loop is stopped from time out.");
334 _WaitingLoopImpl::IsSameThread(void)
336 _ThreadImpl* pThreadImpl = _ThreadImpl::GetCurrentThreadImpl();
337 SysTryReturn(NID_BASE_RT, pThreadImpl != null, false, E_OBJ_NOT_FOUND,"This is not a OSP thread.");
339 ThreadType threadType = pThreadImpl->GetThreadType();
341 if (__threadType == threadType)
343 SysLog(NID_BASE_RT, "The waiting loop is working on the current thread.");
348 SysLog(NID_BASE_RT, "The waiting loop is working on another thread.");
353 } } } // Tizen::Base::Runtime