* limitations under the License
*/
-#include <sys/epoll.h>
-#include <string.h>
+#include <cstring>
+#include <iostream>
#include <unistd.h>
#include <assert.h>
-
-#include <iostream>
+#include <gio/gio.h>
+#include <sys/epoll.h>
#include "error.h"
#include "exception.h"
namespace runtime {
+namespace {
+
+gboolean GIOCallback(GIOChannel* channel, GIOCondition condition, void *data)
+{
+ Mainloop* mainloop = reinterpret_cast<Mainloop*>(data);
+ mainloop->dispatch(-1);
+ return TRUE;
+}
+
+} // namespace
+
Mainloop::Mainloop() :
pollFd(::epoll_create1(EPOLL_CLOEXEC)),
stopped(false)
wakeupSignal.send();
}
-void Mainloop::run()
+void Mainloop::prepare()
{
auto wakeupMainloop = [this](int fd, Mainloop::Event event) {
wakeupSignal.receive();
};
addEventSource(wakeupSignal.getFd(), EPOLLIN, wakeupMainloop);
+}
+
+void Mainloop::run(bool useGMainloop)
+{
+ prepare();
+
+ if (useGMainloop) {
+ GIOChannel* channel;
+ channel = g_io_channel_unix_new(pollFd);
+ if (channel == NULL) {
+ std::cout << "GMAINLOOP CHANNEL ALLOC FAILED" << std::endl;
+ return;
+ }
+ g_io_add_watch(channel, (GIOCondition)(G_IO_IN|G_IO_HUP), GIOCallback, this);
+ g_io_channel_unref(channel);
- while (!stopped) {
- dispatch(-1);
+ while (!stopped) {
+ g_main_iteration(TRUE);
+ }
+ } else {
+ while (!stopped) {
+ dispatch(-1);
+ }
}
}
void addEventSource(const int fd, const Event events, Callback&& callback);
void removeEventSource(const int fd);
bool dispatch(const int timeout);
- void run();
+ void run(bool useGMainloop = false);
void stop();
private:
int pollFd;
std::atomic<bool> stopped;
runtime::EventFD wakeupSignal;
+
+ void prepare();
};
} // namespace runtime
{
}
-void Service::start()
+void Service::start(bool useGMainloop)
{
Socket socket(Socket::create(address));
mainloop.addEventSource(socket.getFd(),
EPOLLIN | EPOLLHUP | EPOLLRDHUP,
accept);
- mainloop.run();
+
+ mainloop.run(useGMainloop);
}
void Service::stop()
Service(const Service&) = delete;
Service& operator=(const Service&) = delete;
- void start();
+ void start(bool useGMainloop = false);
void stop();
void setNewConnectionCallback(const ConnectionCallback& callback);