File Coverage

libev/ev_poll.c
Criterion Covered Total %
statement 0 53 0.0
branch 0 38 0.0
condition n/a
subroutine n/a
pod n/a
total 0 91 0.0


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