]> git.sesse.net Git - vlc/blob - src/os2/poll.c
a4ef1006f444a9722448adb627086de950ceb9f1
[vlc] / src / os2 / poll.c
1 /*****************************************************************************
2  * poll.c: poll() emulation for OS/2
3  *****************************************************************************
4  * Copyright © 2011 KO Myung-Hun <komh@chollian.et>
5  * Copyright © 2007 Rémi Denis-Courmont
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
20  *****************************************************************************/
21
22 #ifdef HAVE_CONFIG_H
23 # include "config.h"
24 #endif
25
26 #include <stdlib.h>
27 #include <string.h>
28 #include <errno.h>
29 #include <sys/time.h>
30
31 #include <vlc_common.h>
32 #include <vlc_network.h>
33
34 int vlc_poll (struct pollfd *fds, unsigned nfds, int timeout)
35 {
36     fd_set rdset;
37     fd_set wrset;
38     fd_set exset;
39     struct timeval tv = { 0, 0 };
40     int val;
41
42 resume:
43     val = -1;
44     vlc_testcancel ();
45
46     FD_ZERO (&rdset);
47     FD_ZERO (&wrset);
48     FD_ZERO (&exset);
49     for (unsigned i = 0; i < nfds; i++)
50     {
51         int fd = fds[i].fd;
52
53         if (fds[i].fd >= FD_SETSIZE)
54         {
55             errno = EINVAL;
56             return -1;
57         }
58
59         if (val < fd)
60             val = fd;
61
62         if (fds[i].events & POLLIN)
63             FD_SET (fd, &rdset);
64         if (fds[i].events & POLLOUT)
65             FD_SET (fd, &wrset);
66         if (fds[i].events & POLLPRI)
67             FD_SET (fd, &exset);
68     }
69
70 #ifndef HAVE_ALERTABLE_SELECT
71 # warning FIXME! Fix cancellation and remove this crap.
72     if ((timeout < 0) || (timeout > 50))
73     {
74         tv.tv_sec = 0;
75         tv.tv_usec = 50000;
76     }
77     else
78 #endif
79     if (timeout >= 0)
80     {
81         div_t d = div (timeout, 1000);
82         tv.tv_sec = d.quot;
83         tv.tv_usec = d.rem * 1000;
84     }
85
86     val = select (val + 1, &rdset, &wrset, &exset, &tv);
87
88 #ifndef HAVE_ALERTABLE_SELECT
89     if (val == 0)
90     {
91         if (timeout > 0)
92             timeout -= (timeout > 50) ? 50 : timeout;
93         if (timeout != 0)
94             goto resume;
95     }
96 #endif
97
98     if (val == -1)
99         return -1;
100
101     for (unsigned i = 0; i < nfds; i++)
102     {
103         int fd = fds[i].fd;
104         fds[i].revents = (FD_ISSET (fd, &rdset) ? POLLIN : 0)
105                        | (FD_ISSET (fd, &wrset) ? POLLOUT : 0)
106                        | (FD_ISSET (fd, &exset) ? POLLPRI : 0);
107     }
108     return val;
109 }