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_EventDispatcher.cpp
20 * @brief This is the implementation file for the _EventDispatcher class.
28 #include <sys/eventfd.h>
30 #include <FBaseObject.h>
31 #include <FBaseRtIRunnable.h>
32 #include <FBaseSysLog.h>
33 #include "FBaseRt_ITask.h"
34 #include "FBaseRt_EventDispatcher.h"
35 #include "FBaseRt_ThreadManager.h"
37 using namespace Tizen::Base;
38 using namespace Tizen::Base::Runtime;
40 namespace Tizen { namespace Base { namespace Runtime
42 __thread _EventDispatcher* pCurrentEventDispatcher = null;
44 _EventDispatcher::_EventDispatcher(void)
46 , __pGMainContext(null)
48 , __pEventFdSource(null)
53 _EventDispatcher::~_EventDispatcher(void)
57 g_source_destroy(__pEventFdSource);
58 g_source_unref(__pEventFdSource);
59 __pEventFdSource = null;
64 g_io_channel_unref(__pEventFdIo);
73 g_main_context_unref(__pGMainContext);
77 _EventDispatcher::Construct(GMainContext* pGMainContext)
80 GError* pGError = null;
83 __pGMainContext = pGMainContext;
85 eventFd = eventfd(0, 0);
86 SysTryCatch(NID_BASE_RT, -1 != eventFd, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to open eventfd.");
88 __pEventFdIo = g_io_channel_unix_new(eventFd);
89 SysTryCatch(NID_BASE_RT, __pEventFdIo != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to create a channel for eventfd.");
90 g_io_channel_set_encoding(__pEventFdIo, null, &pGError);
91 g_io_channel_set_flags(__pEventFdIo, G_IO_FLAG_NONBLOCK, &pGError);
93 g_io_channel_set_close_on_unref(__pEventFdIo, TRUE);
96 __pEventFdSource = g_io_create_watch(__pEventFdIo, G_IO_IN);
97 SysTryCatch(NID_BASE_RT, __pEventFdSource != null, r = E_SYSTEM, E_SYSTEM,
98 "[E_SYSTEM] Failed to create a gsource for a channel.");
100 g_source_set_callback(__pEventFdSource, (GSourceFunc) _EventDispatcher::OnEventReceived, this, null);
101 g_source_attach(__pEventFdSource, __pGMainContext);
103 __pMutex = new (std::nothrow) Mutex();
104 SysTryCatch(NID_BASE_RT, __pMutex != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Not enough memory.");
106 r = __pMutex->Create();
107 SysTryCatch(NID_BASE_RT, !IsFailed(r), , r, "[%s] Failed to create mutex.", GetErrorMessage(r));
109 pCurrentEventDispatcher = this;
120 if (__pEventFdSource)
122 g_source_destroy(__pEventFdSource);
123 g_source_unref(__pEventFdSource);
124 __pEventFdSource = null;
129 g_io_channel_unref(__pEventFdIo);
142 _EventDispatcher::PutTask(_ITask* pITask, void* pParam)
144 gsize writtenSize = 0;
146 _EventMessage* pMessage = null;
148 SysTryReturn(NID_BASE_RT, __pMutex != null, E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] Not constructed.");
150 pMessage = new (std::nothrow) _EventMessage;
152 SysTryReturn(NID_BASE_RT, pMessage != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Not enough memory.");
154 pMessage->pITask = pITask;
155 pMessage->pParam = pParam;
159 __events.Add(pMessage);
163 g_io_channel_write(__pEventFdIo, (const gchar*) &tmp, sizeof(tmp), &writtenSize);
169 _EventDispatcher::OnEventReceived(GIOChannel* pGIOChannel, GIOCondition condition, gpointer data)
171 _EventMessage* pMessage = null;
172 _EventDispatcher* pEventDispatcher = (_EventDispatcher*) data;
176 if (condition & G_IO_IN)
178 g_io_channel_read(pGIOChannel, (gchar*) &tmp, sizeof(tmp), &readSize);
187 pEventDispatcher->__pMutex->Acquire();
190 if (pEventDispatcher->__events.GetAt(0, pMessage) == E_SUCCESS)
192 pEventDispatcher->__events.RemoveAt(0);
195 pEventDispatcher->__pMutex->Release();
199 pMessage->pITask->DoTask(pMessage->pParam);
214 _EventDispatcher::GetCurrentEventDispatcher(void)
216 return pCurrentEventDispatcher;
220 _EventDispatcher::GetGMainContext(void)
222 SysTryReturn(NID_BASE_RT, __pMutex != null, null, E_INVALID_STATE, "[E_INVALID_STATE] Not constructed.");
224 return __pGMainContext;
227 } } } // Tizen::Base::Runtime