Optimize automation-event process splitting
[ardour.git] / libs / pbd / crossthread.posix.cc
index 6dbca9dcec148ab4832e7097c77d100eda171316..573671ba995801302441c19b1da4d3234175a921 100644 (file)
@@ -2,6 +2,7 @@
 
 CrossThreadChannel::CrossThreadChannel (bool non_blocking)
         : receive_channel (0)
+        , receive_source (0)
 {
        fds[0] = -1;
        fds[1] = -1;
@@ -16,7 +17,7 @@ CrossThreadChannel::CrossThreadChannel (bool non_blocking)
                        error << "cannot set non-blocking mode for x-thread pipe (read) (" << ::strerror (errno) << ')' << endmsg;
                        return;
                }
-               
+
                if (fcntl (fds[1], F_SETFL, O_NONBLOCK)) {
                        error << "cannot set non-blocking mode for x-thread pipe (write) (%2)" << ::strerror (errno) << ')' << endmsg;
                        return;
@@ -28,19 +29,28 @@ CrossThreadChannel::CrossThreadChannel (bool non_blocking)
 
 CrossThreadChannel::~CrossThreadChannel ()
 {
-        if (receive_channel) {
+       if (receive_source) {
+               /* this disconnects it from any main context it was attached in
+                  in ::attach(), this prevent its callback from being invoked
+                  after the destructor has finished.
+               */
+               g_source_destroy (receive_source);
+       }
+
+       if (receive_channel) {
                 g_io_channel_unref (receive_channel);
+                receive_channel = 0;
         }
 
        if (fds[0] >= 0) {
                close (fds[0]);
                fds[0] = -1;
-       } 
+       }
 
        if (fds[1] >= 0) {
                close (fds[1]);
                fds[1] = -1;
-       } 
+       }
 }
 
 void
@@ -87,7 +97,7 @@ CrossThreadChannel::poll_for_request()
        return false;
 }
 
-int 
+int
 CrossThreadChannel::receive (char& msg, bool wait)
 {
        if (wait) {