e1e3e93789a661f2ea5cb33cba0319ca84592177
[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 {
40
41 }
42
43 _EventDrivenThreadImpl::~_EventDrivenThreadImpl(void)
44 {
45         delete __pEventDispatcher;
46         delete __pEventManager;
47         delete __pEvent;
48 }
49
50 result
51 _EventDrivenThreadImpl::Stop(void)
52 {
53         result r = E_SUCCESS;
54
55         _EventDrivenThreadEventArg* pEventArg = new (std::nothrow) _EventDrivenThreadEventArg(EVENT_DRIVEN_THREAD_EVENT_TYPE_STOP
56                                                                                                                                                                                   , 0, null);
57         if (__pEvent)
58         {
59                 r = __pEvent->Fire(*pEventArg);
60                 SysTryReturn(NID_BASE_RT, !IsFailed(r), r, r, "[%s] Failed to send a stop event", GetErrorMessage(r));
61         }
62         else
63         {
64                 __pendingEvents.Add(pEventArg);
65         }
66
67
68         return E_SUCCESS;
69 }
70
71 Tizen::Base::Object*
72 _EventDrivenThreadImpl::Run(void)
73 {
74         result r = E_SUCCESS;
75         _EventDrivenThreadEventArg* pArg = null;
76
77         for (int i = 0; i < __pendingEvents.GetCount(); i++)
78         {
79                 __pendingEvents.GetAt(i, pArg);
80
81                 r = __pEvent->FireAsync(*pArg);
82                 if (IsFailed(r))
83                 {
84                         continue;
85                 }
86         }
87
88         g_main_loop_run(__pGMainLoop);
89
90         return null;
91 }
92
93 result
94 _EventDrivenThreadImpl::Initialize(void)
95 {
96         result r = E_SUCCESS;
97         GMainContext* pGMainContext = null;
98         _EventManager* pEventManager = null;
99         _EventDrivenThreadEvent* pEvent = null;
100
101         _ThreadImpl::Initialize();
102
103         pGMainContext = g_main_context_new();
104         g_main_context_push_thread_default(pGMainContext);
105
106         pEventManager = new (std::nothrow) _EventManager;
107         SysTryReturn(NID_BASE_RT, pEventManager != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Not enough memory.");
108
109         r = pEventManager->Construct(pGMainContext);
110         SysTryCatch(NID_BASE_RT, !IsFailed(r), , r, "[%s] Failed to initialize event manager.", GetErrorMessage(r));
111
112         _ThreadImpl::SetEventManager(pEventManager);
113
114         // Initialize event driven thread
115         // This should be done after initialzing event manager has finished.
116         pEvent = new (std::nothrow) _EventDrivenThreadEvent;
117         SysTryReturn(NID_BASE_RT, pEvent != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Not enough memory.");
118
119         r = pEvent->Construct(*this);
120         SysTryCatch(NID_BASE_RT, !IsFailed(r), , r, "[%s] Failed to initialize event driven thread event.", GetErrorMessage(r));
121
122         __pEventManager = pEventManager;
123         __pEvent = pEvent;
124
125         __pGMainLoop = g_main_loop_new(pGMainContext, FALSE);
126
127         __pEventDispatcher = new (std::nothrow) _EventDispatcher();
128         __pEventDispatcher->Construct(pGMainContext);
129
130         return E_SUCCESS;
131
132 CATCH:
133         g_main_context_unref(pGMainContext);
134
135         delete pEvent;
136
137         delete pEventManager;
138
139         _ThreadImpl::Finalize();
140
141         return r;
142 }
143
144 result
145 _EventDrivenThreadImpl::SendUserEvent(RequestId requestId, const Tizen::Base::Collection::IList* pArgs)
146 {
147         result r = E_SUCCESS;
148         _EventDrivenThreadEventArg* pEventArg = null;
149
150         pEventArg = new (std::nothrow) _EventDrivenThreadEventArg(EVENT_DRIVEN_THREAD_EVENT_TYPE_USER_EVENT, requestId, pArgs);
151
152         if (__pEvent)
153         {
154                 r = __pEvent->FireAsync(*pEventArg);
155         }
156         else
157         {
158                 __pendingEvents.Add(pEventArg);
159         }
160
161         return r;
162 }
163
164 void
165 _EventDrivenThreadImpl::OnUserEventReceivedN(RequestId reqId, IList* pArgs)
166 {
167         if (_pThread != null)
168         {
169                 _pThread->OnUserEventReceivedN(reqId, pArgs);
170         }
171 }
172
173 void
174 _EventDrivenThreadImpl::OnStop(void)
175 {
176         if (__pGMainLoop != null)
177         {
178                 g_main_loop_quit(__pGMainLoop);
179         }
180 }
181
182 } } } // Tizen::Base::Runtime