From f7343169315b1aa9e5d68acfc2c2d9247cfc9a3b Mon Sep 17 00:00:00 2001 From: Enrico Scholz Date: Fri, 4 Jan 2013 16:50:35 +0100 Subject: fixed shutdown of plugin epoll_wait() does not return when the epoll-fd is closed by another thread. Use a helper pipe which is added to the epoll. Closing one end allows to terminate the thread cleanly --- inputdev.cc | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'inputdev.cc') diff --git a/inputdev.cc b/inputdev.cc index 30a15af..75d044c 100644 --- a/inputdev.cc +++ b/inputdev.cc @@ -565,11 +565,16 @@ void cInputDevice::handle(void) cInputDeviceController::cInputDeviceController(cPlugin &p) : cRemote("inputdev"), plugin_(p), fd_udev_(-1), fd_epoll_(-1) { + fd_alive_[0] = -1; + fd_alive_[1] = -1; + SetDescription("inpudev handler"); } cInputDeviceController::~cInputDeviceController(void) { + this->close(fd_alive_[0]); + this->close(fd_alive_[1]); this->close(fd_udev_); this->close(fd_epoll_); } @@ -624,6 +629,19 @@ bool cInputDeviceController::open_generic(int fd_udev) goto err; } + rc = pipe2(fd_alive_, O_CLOEXEC); + if (rc < 0) { + esyslog("%s: pipe2(): %s\n", plugin_.Name(), strerror(errno)); + goto err; + } + + rc = epoll_ctl(fd_epoll, EPOLL_CTL_ADD, fd_alive_[0], &ev); + if (rc < 0) { + esyslog("%s: epoll_ctl(ADD, ) failed: %s\n", + plugin_.Name(), fd_alive_[0], strerror(errno)); + goto err; + } + this->fd_udev_ = fd_udev; this->fd_epoll_ = fd_epoll; @@ -981,6 +999,9 @@ bool cInputDeviceController::start(void) void cInputDeviceController::stop(void) { Cancel(-1); + this->close(fd_epoll_); + this->close(fd_alive_[1]); + Cancel(5); } -- cgit v1.2.3