2 Copyright (C) 2009 John Emmas
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 //#include <glib/gtimer.h>
23 #include "pbd/msvc_pbd.h"
25 #ifndef _DWORD_DEFINED
26 #define _DWORD_DEFINED
27 typedef unsigned long DWORD;
28 #endif // !_DWORD_DEFINED
30 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
32 * Note that this entire strategy failed to work, at least for pipes. It turned *
33 * out that Windows 'tell()' always returns 0 when used on a pipe. This strategy *
34 * is now deprecated, having been replaced by a new pipe-like object, which I've *
35 * called 'PBD::pipex'. This polling functionality is included here mostly so *
36 * that Ardour will build and launch under Windows. However, any module that *
37 * relies on polling a pipe will eventually need to use the new pipex object. *
38 * This code will allow it to compile and link successfully, although it won't *
39 * poll successfully at run time. Having said that, these functions might well *
40 * work for ports and/or other machanisms that get represented by a file handle. *
42 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
44 int poll_input (struct pollfd *fds, nfds_t nfds, int& elapsed_time, int timeout)
47 dwNewTickCount = GetTickCount();
55 short ev_mask = (POLLOUT|POLLWRNORM|POLLWRBAND);
61 dwOldTickCount = dwNewTickCount;
63 for (loop=0; loop<nfds; loop++)
64 fds[loop].revents = 0;
66 for (loop=0; (loop<nfds && !error); loop++)
68 if (!(fds[loop].events & ev_mask))
70 long pos = _tell(fds[loop].fd);
74 // An error occured ('errno' should have been set by '_tell()')
76 fds[loop].revents = POLLERR;
77 if (fds[loop].events & POLLRDNORM)
78 fds[loop].revents |= POLLRDNORM;
79 if (fds[loop].events & POLLRDBAND)
80 fds[loop].revents |= POLLRDBAND;
81 if (fds[loop].events & POLLPRI)
82 fds[loop].revents |= POLLPRI;
84 // Do we want to abort on error?
85 if (fds[loop].events & POLLERR)
90 // Input characters were found for this fd
92 if (fds[loop].events & POLLRDNORM)
93 fds[loop].revents |= POLLRDNORM;
94 if (fds[loop].events & POLLRDBAND)
95 fds[loop].revents |= POLLRDBAND;
96 if (fds[loop].events & POLLPRI)
97 fds[loop].revents |= POLLPRI;
99 // Do we want to abort on input?
100 if ((fds[loop].events & POLLIN) ||
101 (fds[loop].events & POLLPRI) ||
102 (fds[loop].events & POLLRDNORM) ||
103 (fds[loop].events & POLLRDBAND))
112 dwNewTickCount = GetTickCount();
113 elapsed_time += (dwNewTickCount-dwOldTickCount);
114 // Note that the above will wrap round if the user leaves
115 // his computer powered up for more than about 50 days!
117 // Sleep briefly because GetTickCount() only has an accuracy of 10mS
118 Sleep(10); // For some reason 'g_usleep()' craps over everything here. Different 'C' runtimes???
120 } while ((!error) && ((timeout == (-1)) || (elapsed_time < timeout)));
124 errno = ERROR_BAD_ARGUMENTS;
131 int poll_output (struct pollfd *fds, nfds_t nfds, int& elapsed_time, int timeout)
133 int ret = 0; // This functionality is not yet implemented
137 // Just flag whichever pollfd was specified for writing
138 short ev_mask = (POLLOUT|POLLWRNORM|POLLWRBAND);
143 for (nfds_t loop=0; loop<nfds; loop++)
145 if (fds[loop].events & ev_mask)
147 fds[loop].revents = POLLNVAL;
148 errno = ERROR_INVALID_ACCESS;
155 errno = ERROR_BAD_ARGUMENTS;
162 //***************************************************************
166 // Emulates POSIX poll() using Win32 _tell().
170 // On Success: A positive integer indicating the total number
171 // of file descriptors that were available for
172 // writing or had data available for reading.
173 // On Failure: -1 (the actual error is saved in 'errno').
175 PBD_API int PBD_APICALLTYPE
176 poll (struct pollfd *fds, nfds_t nfds, int timeout)
178 int elapsed_time = 0;
181 // Note that this functionality is not fully implemented.
182 // At the time of writing, Ardour seems only to poll on
183 // read pipes. Therefore return an error if any write
184 // pipe seems to have been specified or if too many file
185 // descriptors were passed.
186 short ev_mask = (POLLOUT|POLLWRNORM|POLLWRBAND);
188 if ((nfds > OPEN_MAX) || (nfds > NPOLLFILE))
190 errno = ERROR_TOO_MANY_OPEN_FILES;
196 for (nfds_t loop=0; loop<nfds; loop++)
198 if (fds[loop].events & ev_mask)
200 ret = poll_output(fds, nfds, elapsed_time, timeout);
208 ret = poll_input(fds, nfds, elapsed_time, timeout);
215 #endif //COMPILER_MSVC