Epoll refactor 24/36524/2
authorPiotr Bartosiewicz <p.bartosiewi@partner.samsung.com>
Mon, 9 Mar 2015 12:34:27 +0000 (13:34 +0100)
committerPiotr Bartosiewicz <p.bartosiewi@partner.samsung.com>
Mon, 9 Mar 2015 13:19:05 +0000 (14:19 +0100)
[Bug/Feature]   N/A
[Cause]         N/A
[Solution]      N/A
[Verification]  Run tests

Change-Id: Iabb0557aa42ff09d0a2b3f9c36b451cf5fdad10f

common/epoll/event-poll.cpp [moved from common/utils/event-poll.cpp with 98% similarity]
common/epoll/event-poll.hpp [moved from common/utils/event-poll.hpp with 89% similarity]
common/epoll/events.cpp [new file with mode: 0644]
common/epoll/events.hpp [new file with mode: 0644]
common/epoll/glib-poll-dispatcher.cpp [moved from common/utils/glib-poll-dispatcher.cpp with 70% similarity]
common/epoll/glib-poll-dispatcher.hpp [moved from common/utils/glib-poll-dispatcher.hpp with 80% similarity]
common/epoll/thread-poll-dispatcher.cpp [moved from common/utils/thread-poll-dispatcher.cpp with 73% similarity]
common/epoll/thread-poll-dispatcher.hpp [moved from common/utils/thread-poll-dispatcher.hpp with 77% similarity]
tests/unit_tests/epoll/ut-event-poll.cpp [moved from tests/unit_tests/utils/ut-event-poll.cpp with 58% similarity]
tests/unit_tests/ipc/ut-ipc.cpp

similarity index 98%
rename from common/utils/event-poll.cpp
rename to common/epoll/event-poll.cpp
index b37d727..dc1c1bc 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "config.hpp"
-#include "utils/event-poll.hpp"
+#include "epoll/event-poll.hpp"
 #include "utils/fd-utils.hpp"
 #include "utils/exception.hpp"
 #include "logger/logger.hpp"
@@ -34,7 +34,7 @@
 #include <assert.h>
 
 namespace vasum {
-namespace utils {
+namespace epoll {
 
 EventPoll::EventPoll()
     : mPollFD(::epoll_create1(EPOLL_CLOEXEC))
@@ -147,5 +147,5 @@ void EventPoll::removeFDInternal(const int fd)
     }
 }
 
-} // namespace utils
+} // namespace epoll
 } // namespace vasum
similarity index 89%
rename from common/utils/event-poll.hpp
rename to common/epoll/event-poll.hpp
index 1a7ae2c..2d37aaa 100644 (file)
  * @brief   C++ epoll wrapper
  */
 
-#ifndef COMMON_UTILS_EVENT_POLL_HPP
-#define COMMON_UTILS_EVENT_POLL_HPP
+#ifndef COMMON_EPOLL_EVENT_POLL_HPP
+#define COMMON_EPOLL_EVENT_POLL_HPP
+
+#include "epoll/events.hpp"
 
 #include <functional>
 #include <mutex>
 #include <memory>
 
 namespace vasum {
-namespace utils {
+namespace epoll {
 
 class EventPoll {
 public:
-
-    typedef unsigned int Events;
     typedef std::function<bool(int fd, Events events)> Callback;
 
     EventPoll();
@@ -62,7 +62,7 @@ private:
 };
 
 
-} // namespace utils
+} // namespace epoll
 } // namespace vasum
 
-#endif // COMMON_UTILS_EVENT_POLL_HPP
+#endif // COMMON_EPOLL_EVENT_POLL_HPP
diff --git a/common/epoll/events.cpp b/common/epoll/events.cpp
new file mode 100644 (file)
index 0000000..1ee27e0
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Piotr Bartosiewicz <p.bartosiewi@partner.samsung.com>
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+/**
+ * @file
+ * @author  Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com)
+ * @brief   Epoll events
+ */
+
+#include "config.hpp"
+#include "epoll/events.hpp"
+
+#include <sstream>
+
+namespace vasum {
+namespace epoll {
+
+namespace {
+
+std::string eventToString(Events event)
+{
+    switch (event) {
+    case EPOLLIN: return "IN";
+    case EPOLLOUT: return "OUT";
+    case EPOLLERR: return "ERR";
+    case EPOLLHUP: return "HUP";
+    case EPOLLRDHUP: return "RDHUP";
+    default:
+        std::ostringstream ss;
+        ss << "0x" << std::hex << event;
+        return ss.str();
+    }
+}
+
+} // namespace
+
+std::string eventsToString(Events events)
+{
+    if (events == 0) {
+        return "<NONE>";
+    }
+    std::string ret;
+    for (unsigned int i = 0; i<32; ++i) {
+        Events event = 1u << i;
+        if (events & event) {
+            if (!ret.empty()) {
+                ret.append(", ");
+            }
+            ret.append(eventToString(event));
+        }
+    }
+    return ret;
+}
+
+} // namespace epoll
+} // namespace vasum
diff --git a/common/epoll/events.hpp b/common/epoll/events.hpp
new file mode 100644 (file)
index 0000000..62eb00a
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Piotr Bartosiewicz <p.bartosiewi@partner.samsung.com>
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+/**
+ * @file
+ * @author  Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com)
+ * @brief   Epoll events
+ */
+
+#ifndef COMMON_EPOLL_EVENTS_HPP
+#define COMMON_EPOLL_EVENTS_HPP
+
+#include <string>
+#include <sys/epoll.h> // for EPOLL* constatnts
+
+namespace vasum {
+namespace epoll {
+
+typedef unsigned int Events; ///< bitmask of EPOLL* constants
+
+std::string eventsToString(Events events);
+
+} // namespace epoll
+} // namespace vasum
+
+#endif // COMMON_EPOLL_EVENTS_HPP
similarity index 70%
rename from common/utils/glib-poll-dispatcher.cpp
rename to common/epoll/glib-poll-dispatcher.cpp
index 5c66d16..cde535d 100644 (file)
  */
 
 #include "config.hpp"
-#include "utils/glib-poll-dispatcher.hpp"
+#include "epoll/glib-poll-dispatcher.hpp"
 #include "utils/callback-wrapper.hpp"
 
 namespace vasum {
-namespace utils {
+namespace epoll {
 
-GlibPollDispatcher::GlibPollDispatcher(EventPoll& poll)
+GlibPollDispatcher::GlibPollDispatcher()
 {
-    mChannel = g_io_channel_unix_new(poll.getPollFD());
+    mChannel = g_io_channel_unix_new(mPoll.getPollFD());
 
-    auto dispatchCallback = [&]() {
-        poll.dispatchIteration(0);
+    auto dispatchCallback = [this]() {
+        mPoll.dispatchIteration(0);
     };
 
     auto cCallback = [](GIOChannel*, GIOCondition, gpointer data) -> gboolean {
-        getCallbackFromPointer<decltype(dispatchCallback)>(data)();
+        utils::getCallbackFromPointer<decltype(dispatchCallback)>(data)();
         return TRUE;
     };
 
@@ -46,8 +46,8 @@ GlibPollDispatcher::GlibPollDispatcher(EventPoll& poll)
                                    G_PRIORITY_DEFAULT,
                                    G_IO_IN,
                                    cCallback,
-                                   createCallbackWrapper(dispatchCallback, mGuard.spawn()),
-                                   &deleteCallbackWrapper<decltype(dispatchCallback)>);
+                                   utils::createCallbackWrapper(dispatchCallback, mGuard.spawn()),
+                                   &utils::deleteCallbackWrapper<decltype(dispatchCallback)>);
 }
 
 GlibPollDispatcher::~GlibPollDispatcher()
@@ -57,5 +57,10 @@ GlibPollDispatcher::~GlibPollDispatcher()
     // mGuard destructor will wait for full unregister of dispatchCallback
 }
 
-} // namespace utils
+EventPoll& GlibPollDispatcher::getPoll()
+{
+    return mPoll;
+}
+
+} // namespace epoll
 } // namespace vasum
similarity index 80%
rename from common/utils/glib-poll-dispatcher.hpp
rename to common/epoll/glib-poll-dispatcher.hpp
index 07da0c3..cf300bb 100644 (file)
  * @brief   glib epoll dispatcher
  */
 
-#ifndef COMMON_UTILS_GLIB_POLL_DISPATCHER_HPP
-#define COMMON_UTILS_GLIB_POLL_DISPATCHER_HPP
+#ifndef COMMON_EPOLL_GLIB_POLL_DISPATCHER_HPP
+#define COMMON_EPOLL_GLIB_POLL_DISPATCHER_HPP
 
-#include "utils/event-poll.hpp"
+#include "epoll/event-poll.hpp"
 #include "utils/callback-guard.hpp"
 
 #include <gio/gio.h>
 
 namespace vasum {
-namespace utils {
+namespace epoll {
 
 /**
  * Will dispatch poll events in glib thread
  */
 class GlibPollDispatcher {
 public:
-    GlibPollDispatcher(EventPoll& poll);
+    GlibPollDispatcher();
     ~GlibPollDispatcher();
+
+    EventPoll& getPoll();
 private:
-    CallbackGuard mGuard;
+    EventPoll mPoll; // before mGuard!
+    utils::CallbackGuard mGuard;
     GIOChannel* mChannel;
     guint mWatchId;
 };
 
 
-} // namespace utils
+} // namespace epoll
 } // namespace vasum
 
 #endif // COMMON_UTILS_GLIB_POLL_DISPATCHER_HPP
similarity index 73%
rename from common/utils/thread-poll-dispatcher.cpp
rename to common/epoll/thread-poll-dispatcher.cpp
index f350587..797a8c4 100644 (file)
  */
 
 #include "config.hpp"
-#include "utils/thread-poll-dispatcher.hpp"
-
-#include <sys/epoll.h>
+#include "epoll/thread-poll-dispatcher.hpp"
 
 namespace vasum {
-namespace utils {
+namespace epoll {
 
-ThreadPollDispatcher::ThreadPollDispatcher(EventPoll& poll)
-    : mPoll(poll)
-    , mThread([&]{ poll.dispatchLoop(); })
+ThreadPollDispatcher::ThreadPollDispatcher()
 {
-    auto controlCallback = [this](int, EventPoll::Events) -> bool {
+    auto controlCallback = [this](int, Events) -> bool {
         mStopEvent.receive();
         return false; // break the loop
     };
 
-    poll.addFD(mStopEvent.getFD(), EPOLLIN, std::move(controlCallback));
+    mPoll.addFD(mStopEvent.getFD(), EPOLLIN, std::move(controlCallback));
+    mThread = std::thread([this] {
+        mPoll.dispatchLoop();
+    });
 }
 
 ThreadPollDispatcher::~ThreadPollDispatcher()
@@ -49,5 +48,10 @@ ThreadPollDispatcher::~ThreadPollDispatcher()
     mPoll.removeFD(mStopEvent.getFD());
 }
 
-} // namespace utils
+EventPoll& ThreadPollDispatcher::getPoll()
+{
+    return mPoll;
+}
+
+} // namespace epoll
 } // namespace vasum
similarity index 77%
rename from common/utils/thread-poll-dispatcher.hpp
rename to common/epoll/thread-poll-dispatcher.hpp
index e54cb4e..af6b278 100644 (file)
  * @brief   Thread epoll dispatcher
  */
 
-#ifndef COMMON_UTILS_THREAD_POLL_DISPATCHER_HPP
-#define COMMON_UTILS_THREAD_POLL_DISPATCHER_HPP
+#ifndef COMMON_EPOLL_THREAD_POLL_DISPATCHER_HPP
+#define COMMON_EPOLL_THREAD_POLL_DISPATCHER_HPP
 
-#include "utils/event-poll.hpp"
+#include "epoll/event-poll.hpp"
 #include "utils/eventfd.hpp"
 
 #include <thread>
 
 namespace vasum {
-namespace utils {
+namespace epoll {
 
 /**
  * Will dispatch poll events in a newly created thread
  */
 class ThreadPollDispatcher {
 public:
-    ThreadPollDispatcher(EventPoll& poll);
+    ThreadPollDispatcher();
     ~ThreadPollDispatcher();
+
+    EventPoll& getPoll();
 private:
-    EventPoll& mPoll;
-    EventFD mStopEvent;
+    EventPoll mPoll;
+    utils::EventFD mStopEvent;
     std::thread mThread;
 };
 
-} // namespace utils
+} // namespace epoll
 } // namespace vasum
 
-#endif // COMMON_UTILS_THREAD_POLL_DISPATCHER_HPP
+#endif // COMMON_EPOLL_THREAD_POLL_DISPATCHER_HPP
similarity index 58%
rename from tests/unit_tests/utils/ut-event-poll.cpp
rename to tests/unit_tests/epoll/ut-event-poll.cpp
index e387393..0bcbe81 100644 (file)
 #include "config.hpp"
 #include "ut.hpp"
 
-#include "utils/event-poll.hpp"
+#include "epoll/event-poll.hpp"
 #include "logger/logger.hpp"
 #include "ipc/internals/socket.hpp"
 #include "utils/latch.hpp"
 #include "utils/glib-loop.hpp"
-#include "utils/glib-poll-dispatcher.hpp"
-#include "utils/thread-poll-dispatcher.hpp"
-
-#include <map>
-#include <sys/epoll.h>
+#include "epoll/glib-poll-dispatcher.hpp"
+#include "epoll/thread-poll-dispatcher.hpp"
 
 using namespace vasum::utils;
+using namespace vasum::epoll;
 using namespace vasum::ipc;
 
 namespace {
 
 const int unsigned TIMEOUT = 1000;
-#define ADD_EVENT(e) {EPOLL##e, #e}
-const std::map<EventPoll::Events, std::string> EVENT_NAMES = {
-    ADD_EVENT(IN),
-    ADD_EVENT(OUT),
-    ADD_EVENT(ERR),
-    ADD_EVENT(HUP),
-    ADD_EVENT(RDHUP),
-};
-#undef ADD_EVENT
-
-std::string strEvents(EventPoll::Events events)
-{
-    if (events == 0) {
-        return "<none>";
-    }
-    std::ostringstream ss;
-    for (const auto& p : EVENT_NAMES) {
-        if (events & p.first) {
-            ss << p.second << ", ";
-            events &= ~p.first;
-        }
-    }
-    if (events != 0) {
-        ss << std::hex << events;
-        return ss.str();
-    } else {
-        std::string ret = ss.str();
-        ret.resize(ret.size() - 2);
-        return ret;
-    }
-}
 
 } // namespace
 
@@ -87,28 +54,29 @@ BOOST_AUTO_TEST_CASE(EmptyPoll)
 
 BOOST_AUTO_TEST_CASE(ThreadedPoll)
 {
-    EventPoll poll;
-    ThreadPollDispatcher dispatcher(poll);
+    ThreadPollDispatcher dispatcher;
 }
 
 BOOST_AUTO_TEST_CASE(GlibPoll)
 {
     ScopedGlibLoop loop;
 
-    EventPoll poll;
-    GlibPollDispatcher dispatcher(poll);
+    GlibPollDispatcher dispatcher;
 }
 
-void doSocketTest(EventPoll& poll, Latch& goodMessage, Latch& remoteClosed)
+void doSocketTest(EventPoll& poll)
 {
     const std::string PATH = "/tmp/ut-poll.sock";
     const std::string MESSAGE = "This is a test message";
 
+    Latch goodMessage;
+    Latch remoteClosed;
+
     Socket listen = Socket::createSocket(PATH);
     std::shared_ptr<Socket> server;
 
-    auto serverCallback = [&](int, EventPoll::Events events) -> bool {
-        LOGD("Server events: " << strEvents(events));
+    auto serverCallback = [&](int, Events events) -> bool {
+        LOGD("Server events: " << eventsToString(events));
 
         if (events & EPOLLOUT) {
             server->write(MESSAGE.data(), MESSAGE.size());
@@ -118,8 +86,8 @@ void doSocketTest(EventPoll& poll, Latch& goodMessage, Latch& remoteClosed)
         return true;
     };
 
-    auto listenCallback = [&](int, EventPoll::Events events) -> bool {
-        LOGD("Listen events: " << strEvents(events));
+    auto listenCallback = [&](int, Events events) -> bool {
+        LOGD("Listen events: " << eventsToString(events));
         if (events & EPOLLIN) {
             server = listen.accept();
             poll.addFD(server->getFD(), EPOLLHUP | EPOLLRDHUP | EPOLLOUT, serverCallback);
@@ -131,8 +99,8 @@ void doSocketTest(EventPoll& poll, Latch& goodMessage, Latch& remoteClosed)
 
     Socket client = Socket::connectSocket(PATH);
 
-    auto clientCallback = [&](int, EventPoll::Events events) -> bool {
-        LOGD("Client events: " << strEvents(events));
+    auto clientCallback = [&](int, Events events) -> bool {
+        LOGD("Client events: " << eventsToString(events));
 
         if (events & EPOLLIN) {
             std::string ret(MESSAGE.size(), 'x');
@@ -158,47 +126,33 @@ void doSocketTest(EventPoll& poll, Latch& goodMessage, Latch& remoteClosed)
 
 BOOST_AUTO_TEST_CASE(ThreadedPollSocket)
 {
-    Latch goodMessage;
-    Latch remoteClosed;
+    ThreadPollDispatcher dispatcher;
 
-    EventPoll poll;
-    ThreadPollDispatcher dispatcher(poll);
-
-    doSocketTest(poll, goodMessage, remoteClosed);
+    doSocketTest(dispatcher.getPoll());
 }
 
 BOOST_AUTO_TEST_CASE(GlibPollSocket)
 {
-    Latch goodMessage;
-    Latch remoteClosed;
-
     ScopedGlibLoop loop;
 
-    EventPoll poll;
-    GlibPollDispatcher dispatcher(poll);
+    GlibPollDispatcher dispatcher;
 
-    doSocketTest(poll, goodMessage, remoteClosed);
+    doSocketTest(dispatcher.getPoll());
 }
 
 BOOST_AUTO_TEST_CASE(PollStacking)
 {
-    Latch goodMessage;
-    Latch remoteClosed;
+    ThreadPollDispatcher dispatcher;
 
-    EventPoll outer;
-    EventPoll inner;
+    EventPoll innerPoll;
 
-    auto dispatchInner = [&](int, EventPoll::Events) -> bool {
-        inner.dispatchIteration(0);
+    auto dispatchInner = [&](int, Events) -> bool {
+        innerPoll.dispatchIteration(0);
         return true;
     };
-
-    outer.addFD(inner.getPollFD(), EPOLLIN, dispatchInner);
-
-    ThreadPollDispatcher dispatcher(outer);
-    doSocketTest(inner, goodMessage, remoteClosed);
-
-    outer.removeFD(inner.getPollFD());
+    dispatcher.getPoll().addFD(innerPoll.getPollFD(), EPOLLIN, dispatchInner);
+    doSocketTest(innerPoll);
+    dispatcher.getPoll().removeFD(innerPoll.getPollFD());
 }
 
 BOOST_AUTO_TEST_SUITE_END()
index fa0de22..088f576 100644 (file)
@@ -70,7 +70,6 @@ const std::string SOCKET_PATH = TEST_DIR + "/test.socket";
 
 struct Fixture {
     ScopedDir mTestPathGuard;
-    std::string SOCKET_PATH;
 
     Fixture()
         : mTestPathGuard(TEST_DIR)