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_MainLoop.cpp
20 * @brief This is the implementation file for the _MainLoop class.
28 #include <sys/eventfd.h>
31 #include <FBaseColIEnumeratorT.h>
33 #include <FBaseSysLog.h>
34 #include "FBaseRt_MainLoop.h"
36 using namespace Tizen::Base;
37 using namespace Tizen::Base::Collection;
38 using namespace Tizen::Base::Runtime;
40 namespace Tizen { namespace Base { namespace Runtime
42 __thread _MainLoop* pCurrentMainLoop = null;
45 _MainLoop::_Message::operator==(const _Message& rhs) const
47 if (requestId == rhs.requestId && pArgs == rhs.pArgs)
56 _MainLoop::_Message::operator!=(const _Message& rhs) const
58 if (requestId != rhs.requestId || pArgs != rhs.pArgs)
66 _MainLoop::_MainLoop(void)
68 , __pGmainContext(null)
79 _MainLoop::~_MainLoop(void)
87 g_source_unref(__pSource);
93 g_io_channel_unref(__pChannel);
99 _MainLoop::Construct(GMainLoop* pGmainLoop, GMainContext* pGmainContext)
101 result r = E_SUCCESS;
102 GError* pGError = null;
104 __pGmainContext = pGmainContext;
105 g_main_context_ref(__pGmainContext);
107 int eventFd = eventfd(0, 0);
108 SysTryCatch(NID_BASE_RT, -1 != eventFd, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to open eventfd.");
111 __pChannel = g_io_channel_unix_new(eventFd);
112 SysTryCatch(NID_BASE_RT, __pChannel != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to create a channel for eventfd.");
114 g_io_channel_set_encoding(__pChannel, null, &pGError);
115 g_io_channel_set_flags(__pChannel, G_IO_FLAG_NONBLOCK, &pGError);
117 __pSource = g_io_create_watch(__pChannel, G_IO_IN);
118 SysTryCatch(NID_BASE_RT, __pSource != null, r = E_SYSTEM, E_SYSTEM,
119 "[E_SYSTEM] Failed to create a gsource for a channel.");
121 g_source_set_callback(__pSource, (GSourceFunc)OnMessageArrived, this, null);
122 g_source_attach(__pSource, __pGmainContext);
124 __pMutex = new (std::nothrow) Mutex();
125 SysTryCatch(NID_BASE_RT, __pMutex != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Not enough memory.");
127 r = __pMutex->Create();
128 SysTryCatch(NID_BASE_RT, !IsFailed(r), , r, "[%s] Failed to create mutex.", GetErrorMessage(r));
130 pCurrentMainLoop = this;
132 __pActive = &__messages1;
133 __pReady = &__messages2;
145 g_source_unref(__pSource);
151 g_io_channel_unref(__pChannel);
159 _MainLoop::SendUserEvent(RequestId requestId, const IList* pArgs)
161 SysTryReturnResult(NID_BASE_RT, __pGmainContext != null, E_INVALID_STATE, "Main loop is not constructed.");
165 message.requestId = requestId;
166 message.pArgs = pArgs;
170 __pActive->Add(message);
174 gsize writtenSize = 0;
177 g_io_channel_write(__pChannel, (const gchar*) &count, sizeof(count), &writtenSize);
183 _MainLoop::SetMainLoopEventListener(_IMainLoopEventListener* pListener)
185 __pListener = pListener;
189 _MainLoop::OnMessageArrived(GIOChannel* pChannel, GIOCondition condition, gpointer data)
191 _MainLoop* pMainLoop = (_MainLoop*) data;
196 ArrayListT<_Message>* pMessages = null;
198 pMainLoop->__pMutex->Acquire();
200 pMessages = pMainLoop->__pActive;
201 pMainLoop->__pActive = pMainLoop->__pReady;
202 pMainLoop->__pReady = pMessages;
204 pMainLoop->__pMutex->Release();
206 if (condition & G_IO_IN)
208 g_io_channel_read(pChannel, (gchar*) &count, sizeof(count), &readSize);
215 if (pMainLoop->__pListener)
218 IEnumeratorT<_Message>* pEnum = pMessages->GetEnumeratorN();;
219 SysTryReturn(NID_BASE_RT, pEnum, TRUE, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Not enough memory.");
221 while (pEnum->MoveNext() == E_SUCCESS)
223 pEnum->GetCurrent(message);
227 pMessages->RemoveAll();
230 count = pMainLoop->__pActive->GetCount();
233 gsize writtenSize = 0;
234 g_io_channel_write(pChannel, (const gchar*) &count, sizeof(count), &writtenSize);
241 _MainLoop::GetCurrentMainLoop(void)
243 SysTryReturn(NID_BASE_RT, pCurrentMainLoop != null, null, E_INVALID_STATE, "[E_INVALID_STATE] Main loop is exist.");
245 return pCurrentMainLoop;
249 _MainLoop::GetGmainContext(void) const
251 SysTryReturn(NID_BASE_RT, __pGmainContext != null, null, E_INVALID_STATE, "[E_INVALID_STATE] Main loop is not constructed..");
253 return __pGmainContext;
256 } } } // Tizen::Base::Runtime