xref: /freebsd/crypto/krb5/src/util/verto/ev_poll.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
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