1e3a38431SPaul Bohm /*
2e3a38431SPaul Bohm * libev poll fd activity backend
3e3a38431SPaul Bohm *
4e3a38431SPaul Bohm * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <[email protected]>
5e3a38431SPaul Bohm * All rights reserved.
6e3a38431SPaul Bohm *
7e3a38431SPaul Bohm * Redistribution and use in source and binary forms, with or without modifica-
8e3a38431SPaul Bohm * tion, are permitted provided that the following conditions are met:
9e3a38431SPaul Bohm *
10e3a38431SPaul Bohm * 1. Redistributions of source code must retain the above copyright notice,
11e3a38431SPaul Bohm * this list of conditions and the following disclaimer.
12e3a38431SPaul Bohm *
13e3a38431SPaul Bohm * 2. Redistributions in binary form must reproduce the above copyright
14e3a38431SPaul Bohm * notice, this list of conditions and the following disclaimer in the
15e3a38431SPaul Bohm * documentation and/or other materials provided with the distribution.
16e3a38431SPaul Bohm *
17e3a38431SPaul Bohm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
18e3a38431SPaul Bohm * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
19e3a38431SPaul Bohm * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
20e3a38431SPaul Bohm * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
21e3a38431SPaul Bohm * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22e3a38431SPaul Bohm * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23e3a38431SPaul Bohm * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24e3a38431SPaul Bohm * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
25e3a38431SPaul Bohm * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
26e3a38431SPaul Bohm * OF THE POSSIBILITY OF SUCH DAMAGE.
27e3a38431SPaul Bohm *
28e3a38431SPaul Bohm * Alternatively, the contents of this file may be used under the terms of
29e3a38431SPaul Bohm * the GNU General Public License ("GPL") version 2 or any later version,
30e3a38431SPaul Bohm * in which case the provisions of the GPL are applicable instead of
31e3a38431SPaul Bohm * the above. If you wish to allow the use of your version of this file
32e3a38431SPaul Bohm * only under the terms of the GPL and not to allow others to use your
33e3a38431SPaul Bohm * version of this file under the BSD license, indicate your decision
34e3a38431SPaul Bohm * by deleting the provisions above and replace them with the notice
35e3a38431SPaul Bohm * and other provisions required by the GPL. If you do not delete the
36e3a38431SPaul Bohm * provisions above, a recipient may use your version of this file under
37e3a38431SPaul Bohm * either the BSD or the GPL.
38e3a38431SPaul Bohm */
39e3a38431SPaul Bohm
40e3a38431SPaul Bohm #include <poll.h>
41e3a38431SPaul Bohm
42e3a38431SPaul Bohm void inline_size
pollidx_init(int * base,int count)43e3a38431SPaul Bohm pollidx_init (int *base, int count)
44e3a38431SPaul Bohm {
45e3a38431SPaul Bohm /* consider using memset (.., -1, ...), which is practically guaranteed
46e3a38431SPaul Bohm * to work on all systems implementing poll */
47e3a38431SPaul Bohm while (count--)
48e3a38431SPaul Bohm *base++ = -1;
49e3a38431SPaul Bohm }
50e3a38431SPaul Bohm
51e3a38431SPaul Bohm static void
poll_modify(EV_P_ int fd,int oev,int nev)52e3a38431SPaul Bohm poll_modify (EV_P_ int fd, int oev, int nev)
53e3a38431SPaul Bohm {
54e3a38431SPaul Bohm int idx;
55e3a38431SPaul Bohm
56e3a38431SPaul Bohm if (oev == nev)
57e3a38431SPaul Bohm return;
58e3a38431SPaul Bohm
59e3a38431SPaul Bohm array_needsize (int, pollidxs, pollidxmax, fd + 1, pollidx_init);
60e3a38431SPaul Bohm
61e3a38431SPaul Bohm idx = pollidxs [fd];
62e3a38431SPaul Bohm
63e3a38431SPaul Bohm if (idx < 0) /* need to allocate a new pollfd */
64e3a38431SPaul Bohm {
65e3a38431SPaul Bohm pollidxs [fd] = idx = pollcnt++;
66e3a38431SPaul Bohm array_needsize (struct pollfd, polls, pollmax, pollcnt, EMPTY2);
67e3a38431SPaul Bohm polls [idx].fd = fd;
68e3a38431SPaul Bohm }
69e3a38431SPaul Bohm
70e3a38431SPaul Bohm assert (polls [idx].fd == fd);
71e3a38431SPaul Bohm
72e3a38431SPaul Bohm if (nev)
73e3a38431SPaul Bohm polls [idx].events =
74e3a38431SPaul Bohm (nev & EV_READ ? POLLIN : 0)
75e3a38431SPaul Bohm | (nev & EV_WRITE ? POLLOUT : 0);
76e3a38431SPaul Bohm else /* remove pollfd */
77e3a38431SPaul Bohm {
78e3a38431SPaul Bohm pollidxs [fd] = -1;
79e3a38431SPaul Bohm
80e3a38431SPaul Bohm if (expect_true (idx < --pollcnt))
81e3a38431SPaul Bohm {
82e3a38431SPaul Bohm polls [idx] = polls [pollcnt];
83e3a38431SPaul Bohm pollidxs [polls [idx].fd] = idx;
84e3a38431SPaul Bohm }
85e3a38431SPaul Bohm }
86e3a38431SPaul Bohm }
87e3a38431SPaul Bohm
88e3a38431SPaul Bohm static void
poll_poll(EV_P_ ev_tstamp timeout)89e3a38431SPaul Bohm poll_poll (EV_P_ ev_tstamp timeout)
90e3a38431SPaul Bohm {
91e3a38431SPaul Bohm struct pollfd *p;
92e3a38431SPaul Bohm int res;
93e3a38431SPaul Bohm
94e3a38431SPaul Bohm EV_RELEASE_CB;
95*93823e6cSPaul Bohm res = poll (polls, pollcnt, timeout * 1e3);
96e3a38431SPaul Bohm EV_ACQUIRE_CB;
97e3a38431SPaul Bohm
98e3a38431SPaul Bohm if (expect_false (res < 0))
99e3a38431SPaul Bohm {
100e3a38431SPaul Bohm if (errno == EBADF)
101e3a38431SPaul Bohm fd_ebadf (EV_A);
102e3a38431SPaul Bohm else if (errno == ENOMEM && !syserr_cb)
103e3a38431SPaul Bohm fd_enomem (EV_A);
104e3a38431SPaul Bohm else if (errno != EINTR)
105e3a38431SPaul Bohm ev_syserr ("(libev) poll");
106e3a38431SPaul Bohm }
107e3a38431SPaul Bohm else
108e3a38431SPaul Bohm for (p = polls; res; ++p)
109e3a38431SPaul Bohm {
110e3a38431SPaul Bohm assert (("libev: poll() returned illegal result, broken BSD kernel?", p < polls + pollcnt));
111e3a38431SPaul Bohm
112e3a38431SPaul Bohm if (expect_false (p->revents)) /* this expect is debatable */
113e3a38431SPaul Bohm {
114e3a38431SPaul Bohm --res;
115e3a38431SPaul Bohm
116e3a38431SPaul Bohm if (expect_false (p->revents & POLLNVAL))
117e3a38431SPaul Bohm fd_kill (EV_A_ p->fd);
118e3a38431SPaul Bohm else
119e3a38431SPaul Bohm fd_event (
120e3a38431SPaul Bohm EV_A_
121e3a38431SPaul Bohm p->fd,
122e3a38431SPaul Bohm (p->revents & (POLLOUT | POLLERR | POLLHUP) ? EV_WRITE : 0)
123e3a38431SPaul Bohm | (p->revents & (POLLIN | POLLERR | POLLHUP) ? EV_READ : 0)
124e3a38431SPaul Bohm );
125e3a38431SPaul Bohm }
126e3a38431SPaul Bohm }
127e3a38431SPaul Bohm }
128e3a38431SPaul Bohm
129e3a38431SPaul Bohm int inline_size
poll_init(EV_P_ int flags)130e3a38431SPaul Bohm poll_init (EV_P_ int flags)
131e3a38431SPaul Bohm {
132*93823e6cSPaul Bohm backend_mintime = 1e-3;
133e3a38431SPaul Bohm backend_modify = poll_modify;
134e3a38431SPaul Bohm backend_poll = poll_poll;
135e3a38431SPaul Bohm
136e3a38431SPaul Bohm pollidxs = 0; pollidxmax = 0;
137e3a38431SPaul Bohm polls = 0; pollmax = 0; pollcnt = 0;
138e3a38431SPaul Bohm
139e3a38431SPaul Bohm return EVBACKEND_POLL;
140e3a38431SPaul Bohm }
141e3a38431SPaul Bohm
142e3a38431SPaul Bohm void inline_size
poll_destroy(EV_P)143e3a38431SPaul Bohm poll_destroy (EV_P)
144e3a38431SPaul Bohm {
145e3a38431SPaul Bohm ev_free (pollidxs);
146e3a38431SPaul Bohm ev_free (polls);
147e3a38431SPaul Bohm }
148e3a38431SPaul Bohm
149