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 result r = __pTimer->Start(timeout);
138 SysTryReturn(NID_BASE_RT, r == E_SUCCESS, r, r,"[%s]Timer does not start.", GetErrorMessage(r));
140 __waitStatus = WAIT_ON;
141 if (__threadType == THREAD_TYPE_MAIN)
143 ecore_main_loop_begin();
144 SysLog(NID_BASE_RT, "The waiting loop(ecore) is stopped.");
148 while(!__timeout && __notifyWait)
150 g_main_context_iteration(__pGmainContext, TRUE);
151 Thread::Sleep(__sleepTime);
153 SysLog(NID_BASE_RT, "The waiting loop(glib) is stopped.");
156 __waitStatus = WAIT_OFF;
158 SysTryReturn(NID_BASE_RT, __timeout != true, E_TIMEOUT, E_TIMEOUT, "[E_TIMEOUT]The time is expired.");
164 _WaitingLoopImpl::Wait(IWaitingLoopCondition& condition)
166 SysTryReturnResult(NID_BASE_RT, __waitStatus == WAIT_OFF, E_INVALID_STATE, "[E_INVALID_STATUS]The waiting loop is waiting on a thread.");
169 __waitType = WAIT_CONDITION;
170 __pWaitingLoopCondition = &condition;
172 if (__threadType == THREAD_TYPE_MAIN)
174 result r = __pTimer->StartAsRepeatable(__waitingRepeatableTime);
175 SysTryReturn(NID_BASE_RT, r == E_SUCCESS, r, r, "[%s]Timer does not start.", GetErrorMessage(r));
177 __waitStatus = WAIT_ON;
178 ecore_main_loop_begin();
179 SysLog(NID_BASE_RT, "The waiting loop(ecore) is stopped.");
185 __waitStatus = WAIT_ON;
186 while(!__pWaitingLoopCondition->IsMet() && __notifyWait)
188 g_main_context_iteration(__pGmainContext, FALSE);
189 Thread::Sleep(__sleepTime);
191 SysLog(NID_BASE_RT, "The waiting loop(glib) is stopped.");
193 __waitStatus = WAIT_OFF;
199 _WaitingLoopImpl::Wait(int timeout, IWaitingLoopCondition& condition)
201 SysTryReturnResult(NID_BASE_RT, __waitStatus == WAIT_OFF, E_INVALID_STATE, "[E_INVALID_STATUS]The waiting loop is waiting on a thread.");
204 __timerCalledCount = 0;
205 __waitType = WAIT_TIMEOUT_CONDITION;
206 __pWaitingLoopCondition = &condition;
208 if (timeout < __waitingRepeatableTime)
210 result r = __pTimer->StartAsRepeatable(__waitingRepeatableTime);
211 SysTryReturn(NID_BASE_RT, r == E_SUCCESS, r, r, "[%s]Timer does not start.", GetErrorMessage(r));
215 result r = __pTimer->StartAsRepeatable(timeout/10);
216 SysTryReturn(NID_BASE_RT, r == E_SUCCESS, r, r, "[%s]Timer does not start.", GetErrorMessage(r));
218 __waitStatus = WAIT_ON;
219 if (__threadType == THREAD_TYPE_MAIN)
221 ecore_main_loop_begin();
222 SysLog(NID_BASE_RT, "The waiting loop(ecore) is stopped.");
226 while(!__pWaitingLoopCondition->IsMet() && __timeout && __notifyWait)
228 g_main_context_iteration(__pGmainContext, TRUE);
229 Thread::Sleep(__sleepTime);
231 SysLog(NID_BASE_RT, "The waiting loop(glib) is stopped.");
235 __waitStatus = WAIT_OFF;
237 SysTryReturn(NID_BASE_RT, __timeout != true, E_TIMEOUT, E_TIMEOUT, "[E_TIMEOUT]The time is expired.");
243 _WaitingLoopImpl::Notify(void)
245 SysTryReturnVoidResult(NID_BASE_RT, __waitStatus == WAIT_ON, E_INVALID_STATE, "[E_INVALID_STATUS]The waiting loop is not waiting on a thread.");
246 __notifyWait = false;
248 SysLog(NID_BASE_RT, "The waiting loop would be stopped from Notifying.");
250 if (__threadType == THREAD_TYPE_MAIN)
252 ecore_main_loop_quit();
257 _WaitingLoopImpl::SetMaxTimeoutForWaiting(int timeout)
259 if (timeout < __maxTime)
261 __maxTimeout = __maxTime;
265 __maxTimeout = timeout;
270 _WaitingLoopImpl::OnTimerExpired(Timer& timer)
272 if (__threadType == THREAD_TYPE_MAIN)
274 if (__waitType == WAIT_TIMEOUT)
276 ecore_main_loop_quit();
277 SysLog(NID_BASE_RT, "The waiting loop is stopped from time out.");
280 else if ((__waitType == WAIT_CONDITION) && __pWaitingLoopCondition->IsMet())
282 ecore_main_loop_quit();
283 SysLog(NID_BASE_RT, "The waiting loop is stopped from firing condition.");
285 else if (__waitType == WAIT_TIMEOUT_CONDITION)
287 __timerCalledCount++;
288 if (__timerCalledCount == __waitingCount)
290 ecore_main_loop_quit();
291 SysLog(NID_BASE_RT, "The waiting loop is stopped from time out.");
296 if (__pWaitingLoopCondition->IsMet())
298 ecore_main_loop_quit();
299 SysLog(NID_BASE_RT, "The waiting loop is stopped from firing condition.");
306 if (__waitType == WAIT_TIMEOUT)
309 SysLog(NID_BASE_RT, "The waiting loop is stopped from time out.");
311 else if (__waitType == WAIT_TIMEOUT_CONDITION)
313 __timerCalledCount++;
314 if (__timerCalledCount == __waitingCount)
317 SysLog(NID_BASE_RT, "The waiting loop is stopped from time out.");
324 _WaitingLoopImpl::IsSameThread(void)
326 _ThreadImpl* pThreadImpl = _ThreadImpl::GetCurrentThreadImpl();
327 SysTryReturn(NID_BASE_RT, pThreadImpl != null, false, E_OBJ_NOT_FOUND,"This is not a OSP thread.");
329 ThreadType threadType = pThreadImpl->GetThreadType();
331 if (__threadType == threadType)
333 SysLog(NID_BASE_RT, "The waiting loop is working on the current thread.");
338 SysLog(NID_BASE_RT, "The waiting loop is working on another thread.");
343 } } } // Tizen::Base::Runtime