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 +++++++++++++++++++++ inputdev.h | 1 + 2 files changed, 22 insertions(+) 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); } diff --git a/inputdev.h b/inputdev.h index 7038442..a11ab6d 100644 --- a/inputdev.h +++ b/inputdev.h @@ -29,6 +29,7 @@ private: cPlugin &plugin_; int fd_udev_; int fd_epoll_; + int fd_alive_[2]; cList devices_; cList gc_devices_; -- cgit v1.2.3