summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsangwan.kwon <sangwan.kwon@samsung.com>2016-05-23 18:31:06 +0900
committersangwan.kwon <sangwan.kwon@samsung.com>2016-05-24 10:54:40 +0900
commit2f1c4055b248447276cba35e1d4672f0e3d9e80a (patch)
tree83224dbdaf756c7a12d61102bccfbb98958b4165
parenta43bd5dbc3e73ddedd55b79d7ffc06ac62e1a2fd (diff)
downloadcert-checker-2f1c4055b248447276cba35e1d4672f0e3d9e80a.tar.gz
cert-checker-2f1c4055b248447276cba35e1d4672f0e3d9e80a.tar.bz2
cert-checker-2f1c4055b248447276cba35e1d4672f0e3d9e80a.zip
Add mainloop stop logic by using eventfd
Change-Id: If175379bebd20eeb60d091284f754857f59d34a7
-rw-r--r--src/common/CMakeLists.txt1
-rw-r--r--src/common/eventfd.cpp64
-rw-r--r--src/common/eventfd.h49
-rw-r--r--src/common/mainloop.cpp27
-rw-r--r--src/common/mainloop.h12
-rw-r--r--src/common/service.cpp3
-rw-r--r--src/service/ocsp-service.cpp1
7 files changed, 150 insertions, 7 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index c5e965e..8143262 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -28,6 +28,7 @@ SET(${TARGET_CERT_CHECKER_COMMON}_SRCS
${COMMON_PATH}/binary-queue.cpp
${COMMON_PATH}/connection.cpp
${COMMON_PATH}/dispatcher.cpp
+ ${COMMON_PATH}/eventfd.cpp
${COMMON_PATH}/mainloop.cpp
${COMMON_PATH}/service.cpp
${COMMON_PATH}/socket.cpp
diff --git a/src/common/eventfd.cpp b/src/common/eventfd.cpp
new file mode 100644
index 0000000..1828b1f
--- /dev/null
+++ b/src/common/eventfd.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2015 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.
+ * 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 eventfd.cpp
+ * @author Jaemin Ryu (jm77.ryu@samsung.com)
+ * @version 1.0
+ * @brief
+ */
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <exception>
+#include <system_error>
+#include <cstdint>
+
+#include "eventfd.h"
+
+namespace CCHECKER {
+
+EventFD::EventFD(unsigned int initval, int flags)
+{
+ fd = ::eventfd(initval, flags);
+ if (fd == -1) {
+ throw std::logic_error("EventFd from constructor is failed!!");
+ }
+}
+
+EventFD::~EventFD()
+{
+ if (fd != -1) {
+ ::close(fd);
+ }
+}
+
+void EventFD::send()
+{
+ const std::uint64_t val = 1;
+ if (::write(fd, &val, sizeof(val)) == -1) {
+ throw std::logic_error("EventFd send to fd is failed!!");
+ }
+}
+
+void EventFD::receive()
+{
+ std::uint64_t val;
+ if (::read(fd, &val, sizeof(val)) == -1) {
+ throw std::logic_error("EventFd read to fd is failed!!");
+ }
+}
+
+} // namespace CCHECKER
diff --git a/src/common/eventfd.h b/src/common/eventfd.h
new file mode 100644
index 0000000..f10945f
--- /dev/null
+++ b/src/common/eventfd.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2015 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.
+ * 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 eventfd.h
+ * @author Jaemin Ryu (jm77.ryu@samsung.com)
+ * @version 1.0
+ * @brief
+ */
+
+#pragma once
+
+#include <sys/eventfd.h>
+
+namespace CCHECKER {
+
+class EventFD {
+public:
+ EventFD(unsigned int initval = 0, int flags = EFD_SEMAPHORE | EFD_CLOEXEC);
+ ~EventFD();
+
+ EventFD(const EventFD&) = delete;
+ EventFD& operator=(const EventFD&) = delete;
+
+ void send();
+ void receive();
+
+ int getFd() const
+ {
+ return fd;
+ }
+
+private:
+ int fd;
+};
+
+} // namespace CCHECKER
diff --git a/src/common/mainloop.cpp b/src/common/mainloop.cpp
index 4e0f7dd..8ce7326 100644
--- a/src/common/mainloop.cpp
+++ b/src/common/mainloop.cpp
@@ -16,6 +16,7 @@
/*
* @file mainloop.cpp
* @author Kyungwook Tak (k.tak@samsung.com)
+ * @author Sangwan Kwon (sangwan.kwon@samsung.com)
* @version 1.0
* @brief Mainloop with epoll
*/
@@ -33,7 +34,8 @@ namespace CCHECKER {
Mainloop::Mainloop() :
m_isTimedOut(false),
- m_pollfd(::epoll_create1(EPOLL_CLOEXEC))
+ m_pollfd(::epoll_create1(EPOLL_CLOEXEC)),
+ m_stopped(false)
{
if (m_pollfd == -1)
throw std::system_error(
@@ -43,18 +45,35 @@ Mainloop::Mainloop() :
Mainloop::~Mainloop()
{
- if (!m_isTimedOut && !m_callbacks.empty())
+ if (!m_stopped && !m_isTimedOut && !m_callbacks.empty())
throw std::logic_error("mainloop registered callbacks should be empty "
- "except timed out case");
+ "except timed out case");
::close(m_pollfd);
}
+void Mainloop::stop()
+{
+ m_stopped = true;
+ wakeupSignal.send();
+}
+
+void Mainloop::prepare()
+{
+ auto wakeupMainloop = [&](uint32_t) {
+ wakeupSignal.receive();
+ removeEventSource(wakeupSignal.getFd());
+ };
+
+ addEventSource(wakeupSignal.getFd(), EPOLLIN, std::move(wakeupMainloop));
+}
+
void Mainloop::run(int timeout)
{
+ prepare();
m_isTimedOut = false;
- while (!m_isTimedOut) {
+ while (!m_isTimedOut && !m_stopped) {
dispatch(timeout);
}
diff --git a/src/common/mainloop.h b/src/common/mainloop.h
index c52a115..1b3ab73 100644
--- a/src/common/mainloop.h
+++ b/src/common/mainloop.h
@@ -16,20 +16,24 @@
/*
* @file mainloop.h
* @author Kyungwook Tak (k.tak@samsung.com)
+ * @author Sangwan Kwon (sangwan.kwon@samsung.com)
* @version 1.0
- * @brief Manageloop with epoll
+ * @brief Mainloop with epoll
*/
#pragma once
#include <functional>
+#include <atomic>
#include <mutex>
#include <unordered_map>
+#include "common/eventfd.h"
+
namespace CCHECKER {
class Mainloop {
public:
- typedef std::function<void(uint32_t event)> Callback;
+ using Callback = std::function<void(uint32_t)>;
Mainloop();
virtual ~Mainloop();
@@ -40,17 +44,21 @@ public:
Mainloop &operator=(Mainloop &&) = delete;
void run(int timeout);
+ void stop(void);
void addEventSource(int fd, uint32_t event, Callback &&callback);
void removeEventSource(int fd);
private:
void dispatch(int timeout);
+ void prepare();
bool m_isTimedOut;
int m_pollfd;
+ std::atomic<bool> m_stopped;
std::mutex m_mutex;
std::unordered_map<int, Callback> m_callbacks;
+ EventFD wakeupSignal;
constexpr static size_t MAX_EPOLL_EVENTS = 32;
};
diff --git a/src/common/service.cpp b/src/common/service.cpp
index 6f3c46c..0c14dc2 100644
--- a/src/common/service.cpp
+++ b/src/common/service.cpp
@@ -65,6 +65,7 @@ void Service::start()
void Service::stop()
{
LogInfo("Service stop!");
+ m_loop.stop();
}
void Service::setNewConnectionCallback(const ConnCallback &/*callback*/)
@@ -85,7 +86,7 @@ void Service::setNewConnectionCallback(const ConnCallback &/*callback*/)
*/
m_loop.addEventSource(fd, EPOLLIN | EPOLLHUP | EPOLLRDHUP,
- [ &, fd](uint32_t event) {
+ [&, fd](uint32_t event) {
LogDebug("read event comes in to fd[" << fd << "]");
if (m_connectionRegistry.count(fd) == 0)
diff --git a/src/service/ocsp-service.cpp b/src/service/ocsp-service.cpp
index 4c07fa6..5d6997d 100644
--- a/src/service/ocsp-service.cpp
+++ b/src/service/ocsp-service.cpp
@@ -40,6 +40,7 @@ OcspService::~OcspService()
void OcspService::run(void)
{
m_logic.run(TIMEOUT_G_SERVICE);
+ this->stop();
}
void OcspService::onMessageProcess(const ConnShPtr &connection)