Annotation of embedaddon/dnsmasq/src/poll.c, revision 1.1.1.1
1.1 misho 1: /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
2:
3: This program is free software; you can redistribute it and/or modify
4: it under the terms of the GNU General Public License as published by
5: the Free Software Foundation; version 2 dated June, 1991, or
6: (at your option) version 3 dated 29 June, 2007.
7:
8: This program is distributed in the hope that it will be useful,
9: but WITHOUT ANY WARRANTY; without even the implied warranty of
10: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11: GNU General Public License for more details.
12:
13: You should have received a copy of the GNU General Public License
14: along with this program. If not, see <http://www.gnu.org/licenses/>.
15: */
16:
17: #include "dnsmasq.h"
18:
19: /* Wrapper for poll(). Allocates and extends array of struct pollfds,
20: keeps them in fd order so that we can set and test conditions on
21: fd using a simple but efficient binary chop. */
22:
23: /* poll_reset()
24: poll_listen(fd, event)
25: .
26: .
27: poll_listen(fd, event);
28:
29: hits = do_poll(timeout);
30:
31: if (poll_check(fd, event)
32: .
33: .
34:
35: if (poll_check(fd, event)
36: .
37: .
38:
39: event is OR of POLLIN, POLLOUT, POLLERR, etc
40: */
41:
42: static struct pollfd *pollfds = NULL;
43: static nfds_t nfds, arrsize = 0;
44:
45: /* Binary search. Returns either the pollfd with fd, or
46: if the fd doesn't match, or return equals nfds, the entry
47: to the left of which a new record should be inserted. */
48: static nfds_t fd_search(int fd)
49: {
50: nfds_t left, right, mid;
51:
52: if ((right = nfds) == 0)
53: return 0;
54:
55: left = 0;
56:
57: while (1)
58: {
59: if (right == left + 1)
60: return (pollfds[left].fd >= fd) ? left : right;
61:
62: mid = (left + right)/2;
63:
64: if (pollfds[mid].fd > fd)
65: right = mid;
66: else
67: left = mid;
68: }
69: }
70:
71: void poll_reset(void)
72: {
73: nfds = 0;
74: }
75:
76: int do_poll(int timeout)
77: {
78: return poll(pollfds, nfds, timeout);
79: }
80:
81: int poll_check(int fd, short event)
82: {
83: nfds_t i = fd_search(fd);
84:
85: if (i < nfds && pollfds[i].fd == fd)
86: return pollfds[i].revents & event;
87:
88: return 0;
89: }
90:
91: void poll_listen(int fd, short event)
92: {
93: nfds_t i = fd_search(fd);
94:
95: if (i < nfds && pollfds[i].fd == fd)
96: pollfds[i].events |= event;
97: else
98: {
99: if (arrsize != nfds)
100: memmove(&pollfds[i+1], &pollfds[i], (nfds - i) * sizeof(struct pollfd));
101: else
102: {
103: /* Array too small, extend. */
104: struct pollfd *new;
105:
106: arrsize = (arrsize == 0) ? 64 : arrsize * 2;
107:
108: if (!(new = whine_malloc(arrsize * sizeof(struct pollfd))))
109: return;
110:
111: if (pollfds)
112: {
113: memcpy(new, pollfds, i * sizeof(struct pollfd));
114: memcpy(&new[i+1], &pollfds[i], (nfds - i) * sizeof(struct pollfd));
115: free(pollfds);
116: }
117:
118: pollfds = new;
119: }
120:
121: pollfds[i].fd = fd;
122: pollfds[i].events = event;
123: nfds++;
124: }
125: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>