]> git.sesse.net Git - nageru/commitdiff
Shut down the ALSA inotify thread using an eventfd instead of busypolling every 100 ms.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sat, 8 Oct 2016 17:05:11 +0000 (19:05 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Wed, 19 Oct 2016 22:55:44 +0000 (00:55 +0200)
alsa_pool.cpp
alsa_pool.h

index 5983446e37ab4f687cfaa7a9e4db11d497eff711..0a7da5946292a45291bae50cf9c21a373596e177 100644 (file)
@@ -6,6 +6,7 @@
 #include <assert.h>
 #include <limits.h>
 #include <stdio.h>
+#include <sys/eventfd.h>
 #include <sys/inotify.h>
 #include <unistd.h>
 #include <algorithm>
 using namespace std;
 using namespace std::placeholders;
 
+ALSAPool::ALSAPool()
+{
+       should_quit_fd = eventfd(/*initval=*/0, /*flags=*/0);
+       assert(should_quit_fd != -1);
+}
+
 ALSAPool::~ALSAPool()
 {
        for (Device &device : devices) {
@@ -28,6 +35,8 @@ ALSAPool::~ALSAPool()
                }
        }
        should_quit = true;
+       const uint64_t one = 1;
+       write(should_quit_fd, &one, sizeof(one));
        inotify_thread.join();
 
        while (retry_threads_running > 0) {
@@ -289,12 +298,15 @@ void ALSAPool::inotify_thread_func()
        int size = sizeof(inotify_event) + NAME_MAX + 1;
        unique_ptr<char[]> buf(new char[size]);
        while (!should_quit) {
-               pollfd fds;
-               fds.fd = inotify_fd;
-               fds.events = POLLIN;
-               fds.revents = 0;
-
-               int ret = poll(&fds, 1, 100);
+               pollfd fds[2];
+               fds[0].fd = inotify_fd;
+               fds[0].events = POLLIN;
+               fds[0].revents = 0;
+               fds[1].fd = should_quit_fd;
+               fds[1].events = POLLIN;
+               fds[1].revents = 0;
+
+               int ret = poll(fds, 2, -1);
                if (ret == -1) {
                        if (errno == EINTR) {
                                continue;
@@ -307,6 +319,8 @@ void ALSAPool::inotify_thread_func()
                        continue;
                }
 
+               if (fds[1].revents) break;  // should_quit_fd asserted.
+
                ret = read(inotify_fd, buf.get(), size);
                if (ret == -1) {
                        if (errno == EINTR) {
@@ -350,6 +364,7 @@ void ALSAPool::inotify_thread_func()
        }
        close(watch_fd);
        close(inotify_fd);
+       close(should_quit_fd);
 }
 
 void ALSAPool::reset_device(unsigned index)
index c9cd61abda1e8ecbbbaa575bf6021b5ecae141bd..7bab80806f309828f160e8bc4580e56d2fe30ff3 100644 (file)
@@ -21,6 +21,7 @@ class DeviceSpecProto;
 // In particular, it deals with enumeration of cards, and hotplug of new ones.
 class ALSAPool {
 public:
+       ALSAPool();
        ~ALSAPool();
 
        struct Device {
@@ -149,6 +150,7 @@ private:
                                        const std::string &address);
 
        std::atomic<bool> should_quit{false};
+       int should_quit_fd;
        std::thread inotify_thread;
        std::atomic<int> retry_threads_running{0};