Add tests that show the timing differences between the Glib/mm based timeouts
[ardour.git] / libs / pbd / crossthread.posix.cc
1 CrossThreadChannel::CrossThreadChannel (bool non_blocking)
2         : receive_channel (0)
3 {
4         fds[0] = -1;
5         fds[1] = -1;
6
7         if (pipe (fds)) {
8                 error << "cannot create x-thread pipe for read (%2)" << ::strerror (errno) << endmsg;
9                 return;
10         }
11
12         if (non_blocking) {
13                 if (fcntl (fds[0], F_SETFL, O_NONBLOCK)) {
14                         error << "cannot set non-blocking mode for x-thread pipe (read) (" << ::strerror (errno) << ')' << endmsg;
15                         return;
16                 }
17                 
18                 if (fcntl (fds[1], F_SETFL, O_NONBLOCK)) {
19                         error << "cannot set non-blocking mode for x-thread pipe (write) (%2)" << ::strerror (errno) << ')' << endmsg;
20                         return;
21                 }
22         }
23
24         receive_channel = g_io_channel_unix_new (fds[0]);
25 }
26
27 CrossThreadChannel::~CrossThreadChannel ()
28 {
29         if (receive_channel) {
30                 g_io_channel_unref (receive_channel);
31         }
32
33         if (fds[0] >= 0) {
34                 close (fds[0]);
35                 fds[0] = -1;
36         } 
37
38         if (fds[1] >= 0) {
39                 close (fds[1]);
40                 fds[1] = -1;
41         } 
42 }
43
44 void
45 CrossThreadChannel::wakeup ()
46 {
47         char c = 0;
48         (void) ::write (fds[1], &c, 1);
49 }
50
51 void
52 CrossThreadChannel::drain ()
53 {
54         char buf[64];
55         while (::read (fds[0], buf, sizeof (buf)) > 0) {};
56 }
57
58 int
59 CrossThreadChannel::deliver (char msg)
60 {
61         return ::write (fds[1], &msg, 1);
62 }
63
64 int 
65 CrossThreadChannel::receive (char& msg)
66 {
67         return ::read (fds[0], &msg, 1);
68 }