Annotation of embedaddon/dnsmasq/src/poll.c, revision 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>