Refactor mainloop
authorSangwan Kwon <sangwan.kwon@samsung.com>
Tue, 7 Jan 2020 06:19:08 +0000 (15:19 +0900)
committer권상완/Security 2Lab(SR)/Engineer/삼성전자 <sangwan.kwon@samsung.com>
Tue, 14 Jan 2020 01:57:30 +0000 (10:57 +0900)
Signed-off-by: Sangwan Kwon <sangwan.kwon@samsung.com>
src/vist/rmi/impl/ondemand/mainloop.cpp
src/vist/rmi/impl/ondemand/mainloop.hpp

index dd7a038..aa9d5f7 100644 (file)
@@ -73,13 +73,24 @@ void Mainloop::removeHandler(const int fd)
 
        auto iter = this->listener.find(fd);
        if (iter == this->listener.end())
-               return;
+               THROW(ErrCode::RuntimeError) << "Not found file descriptor.";
 
        this->listener.erase(iter);
 
        ::epoll_ctl(epollFd, EPOLL_CTL_DEL, fd, NULL);
 }
 
+Mainloop::Handler Mainloop::getHandler(const int fd)
+{
+       std::lock_guard<Mutex> lock(mutex);
+
+       auto iter = this->listener.find(fd);
+       if (iter == this->listener.end())
+               THROW(ErrCode::RuntimeError) << "Not found file descriptor.";
+
+       return std::make_pair(iter->second.first, iter->second.second);
+}
+
 bool Mainloop::prepare(void)
 {
        auto wakeup = [this]() {
@@ -92,36 +103,36 @@ bool Mainloop::prepare(void)
        this->addHandler(this->wakeupSignal.getFd(), wakeup);
 }
 
-bool Mainloop::dispatch(int timeout) noexcept
+void Mainloop::wait(int timeout)
 {
-       int nfds;
-       ::epoll_event event[MAX_EPOLL_EVENTS];
-
+       int nfds = 0;
        do {
                errno = 0;
-               nfds = ::epoll_wait(epollFd, event, MAX_EPOLL_EVENTS, timeout);
+               nfds = ::epoll_wait(this->epollFd, this->events.data(), MAX_EVENTS, timeout);
+               if (errno == EINTR)
+                       WARN(VIST) << "The call was interrupted by a signal handler.";
        } while ((nfds == -1) && (errno == EINTR));
 
-       if (nfds <= 0)
-               return false;
+       if (nfds == 0) {
+               DEBUG(VIST) << "Mainloop is stopped by timeout.";
+               this->stopped = true;
+               return;
+       }
 
-       for (int i = 0; i < nfds; i++) {
-               std::shared_ptr<OnEvent> onEvent;
-               std::shared_ptr<OnError> onError;
+       if (nfds < 0)
+               THROW(ErrCode::RuntimeError) << "Failed to wait epoll events: " << errno;
 
-               {
-                       std::lock_guard<Mutex> lock(mutex);
+       this->dispatch(nfds);
+}
 
-                       auto iter = this->listener.find(event[i].data.fd);
-                       if (iter == this->listener.end())
-                               continue;
-
-                       onEvent = iter->second.first;
-                       onError = iter->second.second;
-               }
+void Mainloop::dispatch(int size) {
+       for (int i = 0; i < size; i++) {
+               auto handler = this->getHandler(this->events[i].data.fd);
+               auto onEvent = handler.first;
+               auto onError = handler.second;
 
                try {
-                       if ((event[i].events & (EPOLLHUP | EPOLLRDHUP))) {
+                       if ((this->events[i].events & (EPOLLHUP | EPOLLRDHUP))) {
                                WARN(VIST) << "Connected client might be disconnected.";
                                if (onError != nullptr)
                                        (*onError)();
@@ -133,19 +144,14 @@ bool Mainloop::dispatch(int timeout) noexcept
                        ERROR(VIST) << e.what();
                }
        }
-
-       return true;
 }
 
 void Mainloop::run(int timeout)
 {
-       bool done = false;
        this->stopped = false;
-
        this->prepare();
-
-       while (!this->stopped && !done)
-               done = !dispatch(timeout);
+       while (!this->stopped)
+               this->wait(timeout);
 }
 
 void Mainloop::stop(void)
index 6c76d9a..c9307da 100644 (file)
@@ -19,6 +19,7 @@
 #include <vist/rmi/impl/ondemand/eventfd.hpp>
 
 #include <atomic>
+#include <array>
 #include <functional>
 #include <memory>
 #include <mutex>
@@ -61,9 +62,12 @@ private:
        using Handler = std::pair<std::shared_ptr<OnEvent>, std::shared_ptr<OnError>>;
        using Listener = std::unordered_map<int, Handler>;
 
+       Handler getHandler(const int fd);
+
        bool prepare(void);
 
-       bool dispatch(const int timeout) noexcept;
+       void wait(int timeout);
+       void dispatch(int size);
 
        Mutex mutex;
        Listener listener;
@@ -72,7 +76,8 @@ private:
        int epollFd;
        std::atomic<bool> stopped;
 
-       const int MAX_EPOLL_EVENTS = 16;
+       static constexpr int MAX_EVENTS = 16;
+       std::array<::epoll_event, MAX_EVENTS> events;
 };
 
 } // namespace ondemand