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