Add stopper to mainloop
authorSangwan Kwon <sangwan.kwon@samsung.com>
Thu, 9 Jan 2020 04:54:20 +0000 (13:54 +0900)
committer권상완/Security 2Lab(SR)/Engineer/삼성전자 <sangwan.kwon@samsung.com>
Tue, 14 Jan 2020 01:57:30 +0000 (10:57 +0900)
Stopper is a predicate what returns a condition to stop mainloop
when timeout is occured.

Signed-off-by: Sangwan Kwon <sangwan.kwon@samsung.com>
src/vist/rmi/impl/ondemand/mainloop.cpp
src/vist/rmi/impl/ondemand/mainloop.hpp
src/vist/rmi/impl/ondemand/tests/mainloop.cpp

index aa9d5f76072b03babbe8198e92aaef585833169b..7bc028e3a32d9ad7db467a85183b86e6868c32e9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2018-present Samsung Electronics Co., Ltd All Rights Reserved
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -46,8 +46,10 @@ void Mainloop::addHandler(const int fd, OnEvent&& onEvent, OnError&& onError)
 {
        std::lock_guard<Mutex> lock(mutex);
 
-       if (this->listener.find(fd) != this->listener.end())
-               THROW(ErrCode::RuntimeError) << "Event is already registered.";
+       if (this->listener.find(fd) != this->listener.end()) {
+               WARN(VIST) << "Event is already registered.";
+               return;
+       }
 
        ::epoll_event event;
        std::memset(&event, 0, sizeof(epoll_event));
@@ -103,7 +105,7 @@ bool Mainloop::prepare(void)
        this->addHandler(this->wakeupSignal.getFd(), wakeup);
 }
 
-void Mainloop::wait(int timeout)
+void Mainloop::wait(int timeout, Stopper stopper)
 {
        int nfds = 0;
        do {
@@ -115,7 +117,10 @@ void Mainloop::wait(int timeout)
 
        if (nfds == 0) {
                DEBUG(VIST) << "Mainloop is stopped by timeout.";
-               this->stopped = true;
+
+               if (stopper())
+                       this->stopped = true;
+
                return;
        }
 
@@ -146,12 +151,16 @@ void Mainloop::dispatch(int size) {
        }
 }
 
-void Mainloop::run(int timeout)
+void Mainloop::run(int timeout, Stopper stopper)
 {
        this->stopped = false;
        this->prepare();
+
+       if (stopper == nullptr)
+               stopper = []() -> bool { return true; };
+
        while (!this->stopped)
-               this->wait(timeout);
+               this->wait(timeout, stopper);
 }
 
 void Mainloop::stop(void)
index c9307da16e99423993f224d017f7fe728b8df833..ae061b32d6fb5dd338271d082b508d1833b27914 100644 (file)
@@ -38,6 +38,7 @@ class Mainloop {
 public:
        using OnEvent = std::function<void(void)>;
        using OnError = std::function<void(void)>;
+       using Stopper = std::function<bool(void)>;
 
        Mainloop();
        virtual ~Mainloop();
@@ -51,7 +52,9 @@ public:
        void addHandler(const int fd, OnEvent&& onEvent, OnError&& = nullptr);
        void removeHandler(const int fd);
 
-       void run(int timeout = -1);
+       /// Stopper is a predicate what returns a condition to stop mainloop
+       /// when timeout is occured.
+       void run(int timeout = -1, Stopper = nullptr);
        void stop(void);
 
 private:
@@ -66,7 +69,7 @@ private:
 
        bool prepare(void);
 
-       void wait(int timeout);
+       void wait(int timeout, Stopper stopper);
        void dispatch(int size);
 
        Mutex mutex;
index b0c7d31364209d421f8040bcb46dd0e265bad0cc..435b5d14957f4a525bc4aa10cd9dfa0c5785d421 100644 (file)
@@ -116,3 +116,14 @@ TEST(MainloopTests, multiflexing)
                if (client.joinable())
                        client.join();
 }
+
+TEST(MainloopTests, stopper)
+{
+       auto stopper = []() -> bool { return true; };
+       Mainloop mainloop;
+       mainloop.run(1000, stopper);
+       EXPECT_TRUE(true);
+
+       mainloop.run(1000);
+       EXPECT_TRUE(true);
+}