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);
88 g_source_destroy(__pSource);
94 g_io_channel_unref(__pChannel);
100 _MainLoop::Construct(GMainLoop* pGmainLoop, GMainContext* pGmainContext)
102 result r = E_SUCCESS;
103 GError* pGError = null;
105 __pGmainContext = pGmainContext;
106 g_main_context_ref(__pGmainContext);
108 int eventFd = eventfd(0, 0);
109 SysTryCatch(NID_BASE_RT, -1 != eventFd, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to open eventfd.");
112 __pChannel = g_io_channel_unix_new(eventFd);
113 SysTryCatch(NID_BASE_RT, __pChannel != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to create a channel for eventfd.");
115 g_io_channel_set_encoding(__pChannel, null, &pGError);
116 g_io_channel_set_flags(__pChannel, G_IO_FLAG_NONBLOCK, &pGError);
118 g_io_channel_set_close_on_unref(__pChannel, TRUE);
121 __pSource = g_io_create_watch(__pChannel, G_IO_IN);
122 SysTryCatch(NID_BASE_RT, __pSource != null, r = E_SYSTEM, E_SYSTEM,
123 "[E_SYSTEM] Failed to create a gsource for a channel.");
125 g_source_set_callback(__pSource, (GSourceFunc)OnMessageArrived, this, null);
126 g_source_attach(__pSource, __pGmainContext);
128 __pMutex = new (std::nothrow) Mutex();
129 SysTryCatch(NID_BASE_RT, __pMutex != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Not enough memory.");
131 r = __pMutex->Create();
132 SysTryCatch(NID_BASE_RT, !IsFailed(r), , r, "[%s] Failed to create mutex.", GetErrorMessage(r));
134 pCurrentMainLoop = this;
136 __pActive = &__messages1;
137 __pReady = &__messages2;
149 g_source_unref(__pSource);
150 g_source_destroy(__pSource);
156 g_io_channel_unref(__pChannel);
168 _MainLoop::SendUserEvent(RequestId requestId, const IList* pArgs)
170 SysTryReturnResult(NID_BASE_RT, __pGmainContext != null, E_INVALID_STATE, "Main loop is not constructed.");
174 message.requestId = requestId;
175 message.pArgs = pArgs;
179 __pActive->Add(message);
183 gsize writtenSize = 0;
186 g_io_channel_write(__pChannel, (const gchar*) &count, sizeof(count), &writtenSize);
192 _MainLoop::SetMainLoopEventListener(_IMainLoopEventListener* pListener)
194 __pListener = pListener;
198 _MainLoop::OnMessageArrived(GIOChannel* pChannel, GIOCondition condition, gpointer data)
200 _MainLoop* pMainLoop = (_MainLoop*) data;
205 ArrayListT<_Message>* pMessages = null;
207 pMainLoop->__pMutex->Acquire();
209 pMessages = pMainLoop->__pActive;
210 pMainLoop->__pActive = pMainLoop->__pReady;
211 pMainLoop->__pReady = pMessages;
213 pMainLoop->__pMutex->Release();
215 if (condition & G_IO_IN)
217 g_io_channel_read(pChannel, (gchar*) &count, sizeof(count), &readSize);
224 if (pMainLoop->__pListener)
227 IEnumeratorT<_Message>* pEnum = pMessages->GetEnumeratorN();;
228 SysTryReturn(NID_BASE_RT, pEnum, TRUE, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Not enough memory.");
230 while (pEnum->MoveNext() == E_SUCCESS)
232 pEnum->GetCurrent(message);
236 pMessages->RemoveAll();
239 count = pMainLoop->__pActive->GetCount();
242 gsize writtenSize = 0;
243 g_io_channel_write(pChannel, (const gchar*) &count, sizeof(count), &writtenSize);
250 _MainLoop::GetCurrentMainLoop(void)
252 SysTryReturn(NID_BASE_RT, pCurrentMainLoop != null, null, E_INVALID_STATE, "[E_INVALID_STATE] Main loop is exist.");
254 return pCurrentMainLoop;
258 _MainLoop::GetGmainContext(void) const
260 SysTryReturn(NID_BASE_RT, __pGmainContext != null, null, E_INVALID_STATE, "[E_INVALID_STATE] Main loop is not constructed..");
262 return __pGmainContext;
265 } } } // Tizen::Base::Runtime