Merge "Update deprecated libprivilege-control API functions." into tizen
[platform/framework/native/appfw.git] / src / base / runtime / FBaseRt_EventDrivenThreadImpl.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_EventDrivenThreadImpl.cpp
19  * @brief       This is the implementation file for the _EventDrivenThreadImpl class.
20  *
21  */
22
23 #include <new>
24 #include <FBaseSysLog.h>
25 #include "FBaseRt_EventDrivenThreadImpl.h"
26
27 using namespace Tizen::Base::Collection;
28
29 namespace Tizen { namespace Base { namespace Runtime
30 {
31
32 _EventDrivenThreadImpl::_EventDrivenThreadImpl(Thread& thread, const String& name, long stackSize, ThreadPriority priority)
33         : _ThreadImpl(thread, name, stackSize, priority, THREAD_TYPE_EVENT_DRIVEN)
34         , __pGMainLoop(null)
35         , __pEventDispatcher(null)
36         , __pEventManager(null)
37         , __pEvent(null)
38         , __pGmainContext(null)
39         , __pLock(null)
40 {
41         __pLock = new (std::nothrow) Tizen::Base::Runtime::Mutex();
42         SysTryLog(NID_BASE, __pLock != null, "Failed to allocate the mutex instance");
43
44         result r = __pLock->Create();
45         SysTryLog(NID_BASE, !IsFailed(r), "Failed to create the mutex instance");
46 }
47
48 _EventDrivenThreadImpl::~_EventDrivenThreadImpl(void)
49 {
50         delete __pEventDispatcher;
51         delete __pEventManager;
52         delete __pEvent;
53         delete __pLock;
54         g_main_loop_unref(__pGMainLoop);
55 }
56
57 result
58 _EventDrivenThreadImpl::Stop(void)
59 {
60         result r = E_SUCCESS;
61
62         _EventDrivenThreadEventArg* pEventArg = new (std::nothrow) _EventDrivenThreadEventArg(EVENT_DRIVEN_THREAD_EVENT_TYPE_STOP, 0, null);
63         SysTryReturnResult(NID_BASE, pEventArg != null, E_OUT_OF_MEMORY, "Not enough memory.");
64
65         r = __pLock->Acquire();
66         SysTryLog(NID_BASE, !IsFailed(r), "Failed to acquire mutex");
67
68         if (__pEvent)
69         {
70                 r = __pEvent->Fire(*pEventArg);
71                 SysTryLog(NID_BASE_RT, !IsFailed(r), "[%s] Failed to send a stop event", GetErrorMessage(r));
72         }
73         else
74         {
75                 __pendingEvents.Add(pEventArg);
76         }
77
78         r = __pLock->Release();
79         SysTryLog(NID_BASE, !IsFailed(r), "Failed to release mutex");
80
81         return r;
82 }
83
84 Tizen::Base::Object*
85 _EventDrivenThreadImpl::Run(void)
86 {
87         result r = E_SUCCESS;
88         _EventDrivenThreadEventArg* pArg = null;
89
90         r = __pLock->Acquire();
91         SysTryLog(NID_BASE, !IsFailed(r), "Failed to acquire mutex");
92
93         for (int i = 0; i < __pendingEvents.GetCount(); i++)
94         {
95                 __pendingEvents.GetAt(i, pArg);
96
97                 r = __pEvent->FireAsync(*pArg);
98                 if (IsFailed(r))
99                 {
100                         continue;
101                 }
102         }
103         r = __pLock->Release();
104         SysTryLog(NID_BASE, !IsFailed(r), "Failed to release mutex");
105
106         g_main_loop_run(__pGMainLoop);
107
108         return null;
109 }
110
111 result
112 _EventDrivenThreadImpl::Initialize(void)
113 {
114         result r = E_SUCCESS;
115         GMainContext* pGMainContext = null;
116         _EventManager* pEventManager = null;
117         _EventDrivenThreadEvent* pEvent = null;
118
119         _ThreadImpl::Initialize();
120
121         pGMainContext = g_main_context_new();
122         g_main_context_push_thread_default(pGMainContext);
123
124         pEventManager = new (std::nothrow) _EventManager;
125         SysTryReturn(NID_BASE_RT, pEventManager != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Not enough memory.");
126
127         r = pEventManager->Construct(pGMainContext);
128         SysTryCatch(NID_BASE_RT, !IsFailed(r), , r, "[%s] Failed to initialize event manager.", GetErrorMessage(r));
129
130         _ThreadImpl::SetEventManager(pEventManager);
131
132         // Initialize event driven thread
133         // This should be done after initialzing event manager has finished.
134         pEvent = new (std::nothrow) _EventDrivenThreadEvent;
135         SysTryReturn(NID_BASE_RT, pEvent != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Not enough memory.");
136
137         r = pEvent->Construct(*this);
138         SysTryCatch(NID_BASE_RT, !IsFailed(r), , r, "[%s] Failed to initialize event driven thread event.", GetErrorMessage(r));
139
140         __pEventManager = pEventManager;
141         __pEvent = pEvent;
142
143         __pGMainLoop = g_main_loop_new(pGMainContext, FALSE);
144
145         __pEventDispatcher = new (std::nothrow) _EventDispatcher();
146         __pEventDispatcher->Construct(pGMainContext);
147
148         __pGmainContext = pGMainContext;
149         return E_SUCCESS;
150
151 CATCH:
152         g_main_context_unref(pGMainContext);
153
154         delete pEvent;
155
156         delete pEventManager;
157
158         _ThreadImpl::Finalize();
159
160         return r;
161 }
162
163 result
164 _EventDrivenThreadImpl::SendUserEvent(RequestId requestId, const Tizen::Base::Collection::IList* pArgs)
165 {
166         result r = __pLock->Acquire();
167         SysTryLog(NID_BASE, !IsFailed(r), "Failed to acquire mutex");
168
169         _EventDrivenThreadEventArg* pEventArg = null;
170
171         pEventArg = new (std::nothrow) _EventDrivenThreadEventArg(EVENT_DRIVEN_THREAD_EVENT_TYPE_USER_EVENT, requestId, pArgs);
172
173         if (__pEvent)
174         {
175                 r = __pEvent->FireAsync(*pEventArg);
176         }
177         else
178         {
179                 __pendingEvents.Add(pEventArg);
180         }
181         r = __pLock->Release();
182         SysTryLog(NID_BASE, !IsFailed(r), "Failed to release mutex");
183
184         return r;
185 }
186
187 void
188 _EventDrivenThreadImpl::OnUserEventReceivedN(RequestId reqId, IList* pArgs)
189 {
190         if (_pThread != null)
191         {
192                 _pThread->OnUserEventReceivedN(reqId, pArgs);
193         }
194 }
195
196 void
197 _EventDrivenThreadImpl::OnStop(void)
198 {
199         if (__pGMainLoop != null)
200         {
201                 g_main_loop_quit(__pGMainLoop);
202         }
203 }
204
205 } } } // Tizen::Base::Runtime