Checks Service idle with client connection 98/76898/1
authorKyungwook Tak <k.tak@samsung.com>
Tue, 28 Jun 2016 00:55:21 +0000 (09:55 +0900)
committerKyungwook Tak <k.tak@samsung.com>
Tue, 28 Jun 2016 00:55:50 +0000 (09:55 +0900)
Change-Id: Iba6c0d725e98d5c5e8e81252873923278bd0d194
Signed-off-by: Kyungwook Tak <k.tak@samsung.com>
src/framework/common/mainloop.cpp
src/framework/common/mainloop.h
src/framework/common/service.cpp
src/framework/common/service.h
src/framework/service/server-service.cpp

index 3316c0a..55eb7c8 100644 (file)
@@ -61,6 +61,8 @@ void Mainloop::run(int timeout)
 
 void Mainloop::addEventSource(int fd, uint32_t event, Callback &&callback)
 {
+       std::lock_guard<std::mutex> l(this->m_mutex);
+
        if (this->m_callbacks.count(fd) != 0)
                ThrowExc(CSR_ERROR_SERVER, "event source on fd[" << fd << "] already added!");
 
@@ -81,25 +83,31 @@ void Mainloop::addEventSource(int fd, uint32_t event, Callback &&callback)
 
 void Mainloop::removeEventSource(int fd)
 {
+       std::lock_guard<std::mutex> l(this->m_mutex);
+
        if (this->m_callbacks.count(fd) == 0)
                ThrowExc(CSR_ERROR_SERVER, "event source on fd[" << fd << "] isn't added at all");
 
        DEBUG("Remove event source on fd[" << fd << "]");
 
-       {
-               this->m_callbacks.erase(fd);
+       this->m_callbacks.erase(fd);
 
-               if (::epoll_ctl(m_pollfd, EPOLL_CTL_DEL, fd, nullptr) == -1) {
-                       if (errno == ENOENT)
-                               ThrowExc(CSR_ERROR_SERVER, "Tried to delete epoll item which wasn't added");
-                       else
-                               throw std::system_error(
-                                       std::error_code(errno, std::generic_category()),
-                                       "epoll_ctl failed to EPOLL_CTL_DEL.");
-               }
+       if (::epoll_ctl(m_pollfd, EPOLL_CTL_DEL, fd, nullptr) == -1) {
+               if (errno == ENOENT)
+                       ThrowExc(CSR_ERROR_SERVER, "Tried to delete epoll item which wasn't added");
+               else
+                       throw std::system_error(
+                               std::error_code(errno, std::generic_category()),
+                               "epoll_ctl failed to EPOLL_CTL_DEL.");
        }
 }
 
+size_t Mainloop::countEventSource() const
+{
+       std::lock_guard<std::mutex> l(this->m_mutex);
+       return this->m_callbacks.size();
+}
+
 void Mainloop::dispatch(int timeout)
 {
        int nfds = -1;
index a4f438f..7a16bab 100644 (file)
@@ -29,7 +29,7 @@
 
 namespace Csr {
 
-class Mainloop {
+class API Mainloop {
 public:
        using Callback = std::function<void(uint32_t event)>;
 
@@ -47,6 +47,7 @@ public:
 
        void addEventSource(int fd, uint32_t event, Callback &&callback);
        void removeEventSource(int fd);
+       size_t countEventSource(void) const;
 
        void setIdleChecker(std::function<bool()> &&idleChecker);
 
@@ -55,7 +56,7 @@ private:
 
        bool m_isTimedOut;
        int m_pollfd;
-       std::mutex m_mutex;
+       mutable std::mutex m_mutex;
        std::unordered_map<int, Callback> m_callbacks;
 
        std::function<bool()> m_isIdle;
index 2ab7530..aef65e6 100644 (file)
@@ -38,11 +38,6 @@ Service::~Service()
 {
 }
 
-void Service::setIdleChecker(std::function<bool()> &&idleChecker)
-{
-       this->m_loop.setIdleChecker(std::move(idleChecker));
-}
-
 void Service::add(const SockId &id)
 {
        this->m_sockIds.insert(id);
index 7025d8f..0e4195c 100644 (file)
@@ -47,7 +47,7 @@ public:
        virtual void start(int timeout) final;
 
 protected:
-       void setIdleChecker(std::function<bool()> &&idleChecker);
+       Mainloop m_loop;
 
 private:
        virtual void onMessageProcess(const ConnShPtr &) = 0;
@@ -57,7 +57,6 @@ private:
 
        mutable std::mutex m_crMtx;
        std::unordered_map<int, ConnShPtr> m_connectionRegistry;
-       Mainloop m_loop;
 
        std::set<SockId> m_sockIds;
 };
index 6b1ac4f..1ade03a 100644 (file)
@@ -113,7 +113,9 @@ ServerService::ServerService() : Service(), m_workqueue(5)
        this->add(SockId::ADMIN);
 
        // if task is not running in workqueue, it's idle.
-       this->setIdleChecker([this]() { return !this->m_workqueue.isTaskRunning(); });
+       this->m_loop.setIdleChecker([this]()->bool {
+               return (!this->m_workqueue.isTaskRunning() && this->m_loop.countEventSource() == 3);
+       });
 }
 
 RawBuffer ServerService::processCs(const ConnShPtr &conn, RawBuffer &data)