Refactor the non-portable parts of Butler thread into new functions
authorPaul Davis <paul@linuxaudiosystems.com>
Thu, 11 Jul 2013 18:36:43 +0000 (14:36 -0400)
committerPaul Davis <paul@linuxaudiosystems.com>
Thu, 11 Jul 2013 18:36:43 +0000 (14:36 -0400)
libs/ardour/ardour/butler.h
libs/ardour/butler.cc

index 321755197c2ba9a9f7a1ad16aad73ec18b9493be..8799899004a2afd5680ee14d8d53c6d513a0f79e 100644 (file)
@@ -82,6 +82,24 @@ private:
        void config_changed (std::string);
 
        int setup_request_pipe ();
+
+       /**
+        * return true if there are requests to be processed
+        */
+       bool wait_for_requests ();
+
+       /**
+        * Remove request from butler request queue
+        *
+        * return true if there was another request and req is valid
+        */
+       bool dequeue_request (Request::Type& req);
+
+       /**
+        * Add request to butler thread request queue
+        */
+       void queue_request (Request::Type r);
+
 };
 
 } // namespace ARDOUR
index 38ffef6fbc860ea8eaff7a7899099aab65425f9c..ad54e7dee7699c4e55408e5530e73bf06809c0ad 100644 (file)
@@ -127,8 +127,7 @@ Butler::terminate_thread ()
 {
        if (thread) {
                void* status;
-               const char c = Request::Quit;
-               (void) ::write (request_pipe[1], &c, 1);
+               queue_request (Request::Quit);
                pthread_join (thread, &status);
        }
 }
@@ -141,28 +140,24 @@ Butler::_thread_work (void* arg)
        return ((Butler *) arg)->thread_work ();
 }
 
-void *
-Butler::thread_work ()
+bool
+Butler::wait_for_requests ()
 {
-       uint32_t err = 0;
-
        struct pollfd pfd[1];
-       bool disk_work_outstanding = false;
-       RouteList::iterator i;
 
-       while (true) {
-               pfd[0].fd = request_pipe[0];
-               pfd[0].events = POLLIN|POLLERR|POLLHUP;
+       pfd[0].fd = request_pipe[0];
+       pfd[0].events = POLLIN|POLLERR|POLLHUP;
 
-               if (poll (pfd, 1, (disk_work_outstanding ? 0 : -1)) < 0) {
+       while(true) {
+               if (poll (pfd, 1, -1) < 0) {
 
                        if (errno == EINTR) {
                                continue;
                        }
 
                        error << string_compose (_("poll on butler request pipe failed (%1)"),
-                                         strerror (errno))
-                             << endmsg;
+                                       strerror (errno))
+                               << endmsg;
                        break;
                }
 
@@ -172,16 +167,47 @@ Butler::thread_work ()
                }
 
                if (pfd[0].revents & POLLIN) {
+                       return true;
+               }
+       }
+       return false;
+}
 
-                       char req;
+bool
+Butler::dequeue_request (Request::Type& r)
+{
+       char req;
+       size_t nread = ::read (request_pipe[0], &req, sizeof (req));
+       if (nread == 1) {
+               r = (Request::Type) req;
+               return true;
+       } else if (nread == 0) {
+               return false;
+       } else if (errno == EAGAIN) {
+               return false;
+       } else {
+               fatal << _("Error reading from butler request pipe") << endmsg;
+               /*NOTREACHED*/
+       }
+       return false;
+}
 
-                       /* empty the pipe of all current requests */
+       void *
+Butler::thread_work ()
+{
+       uint32_t err = 0;
+
+       bool disk_work_outstanding = false;
+       RouteList::iterator i;
 
-                       while (1) {
-                               size_t nread = ::read (request_pipe[0], &req, sizeof (req));
-                               if (nread == 1) {
+       while (true) {
+               if(!disk_work_outstanding) {
+                       if (wait_for_requests ()) {
+                               Request::Type req;
 
-                                       switch ((Request::Type) req) {
+                               /* empty the pipe of all current requests */
+                               while(dequeue_request(req)) {
+                                       switch (req) {
 
                                        case Request::Run:
                                                should_run = true;
@@ -199,14 +225,6 @@ Butler::thread_work ()
                                        default:
                                                break;
                                        }
-
-                               } else if (nread == 0) {
-                                       break;
-                               } else if (errno == EAGAIN) {
-                                       break;
-                               } else {
-                                       fatal << _("Error reading from butler request pipe") << endmsg;
-                                       /*NOTREACHED*/
                                }
                        }
                }
@@ -347,18 +365,23 @@ Butler::schedule_transport_work ()
 }
 
 void
-Butler::summon ()
+Butler::queue_request (Request::Type r)
 {
-       char c = Request::Run;
+       char c = r;
        (void) ::write (request_pipe[1], &c, 1);
 }
 
+void
+Butler::summon ()
+{
+       queue_request (Request::Run);
+}
+
 void
 Butler::stop ()
 {
        Glib::Threads::Mutex::Lock lm (request_lock);
-       char c = Request::Pause;
-       (void) ::write (request_pipe[1], &c, 1);
+       queue_request (Request::Pause);
        paused.wait(request_lock);
 }
 
@@ -366,8 +389,7 @@ void
 Butler::wait_until_finished ()
 {
        Glib::Threads::Mutex::Lock lm (request_lock);
-       char c = Request::Pause;
-       (void) ::write (request_pipe[1], &c, 1);
+       queue_request (Request::Pause);
        paused.wait(request_lock);
 }