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