diff options
author | Seonah Moon <seonah1.moon@samsung.com> | 2016-04-07 14:01:07 +0900 |
---|---|---|
committer | Seonah Moon <seonah1.moon@samsung.com> | 2016-04-07 14:01:28 +0900 |
commit | 9acb9eb162ab31ca7d23350c508b207a775da79f (patch) | |
tree | 42dc00b1f72e043d48e274170275bbed32dcfa70 /src/poll.c | |
parent | 282cb37dd9a95cafc948b14cb782a229f6511f71 (diff) | |
download | dnsmasq-9acb9eb162ab31ca7d23350c508b207a775da79f.tar.gz dnsmasq-9acb9eb162ab31ca7d23350c508b207a775da79f.tar.bz2 dnsmasq-9acb9eb162ab31ca7d23350c508b207a775da79f.zip |
Update to 2.74submit/tizen/20160407.062043accepted/tizen/wearable/20160407.111603accepted/tizen/tv/20160407.111550accepted/tizen/mobile/20160407.111534accepted/tizen/ivi/20160407.111623accepted/tizen/common/20160407.132919
Change-Id: Ic7e94612466be7786c3d2b0724d745c7720e01c9
Signed-off-by: Seonah Moon <seonah1.moon@samsung.com>
Diffstat (limited to 'src/poll.c')
-rw-r--r-- | src/poll.c | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/src/poll.c b/src/poll.c new file mode 100644 index 0000000..d71b1b9 --- /dev/null +++ b/src/poll.c @@ -0,0 +1,125 @@ +/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 dated June, 1991, or + (at your option) version 3 dated 29 June, 2007. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "dnsmasq.h" + +/* Wrapper for poll(). Allocates and extends array of struct pollfds, + keeps them in fd order so that we can set and test conditions on + fd using a simple but efficient binary chop. */ + +/* poll_reset() + poll_listen(fd, event) + . + . + poll_listen(fd, event); + + hits = do_poll(timeout); + + if (poll_check(fd, event) + . + . + + if (poll_check(fd, event) + . + . + + event is OR of POLLIN, POLLOUT, POLLERR, etc +*/ + +static struct pollfd *pollfds = NULL; +static nfds_t nfds, arrsize = 0; + +/* Binary search. Returns either the pollfd with fd, or + if the fd doesn't match, or return equals nfds, the entry + to the left of which a new record should be inserted. */ +static nfds_t fd_search(int fd) +{ + nfds_t left, right, mid; + + if ((right = nfds) == 0) + return 0; + + left = 0; + + while (1) + { + if (right == left + 1) + return (pollfds[left].fd >= fd) ? left : right; + + mid = (left + right)/2; + + if (pollfds[mid].fd > fd) + right = mid; + else + left = mid; + } +} + +void poll_reset(void) +{ + nfds = 0; +} + +int do_poll(int timeout) +{ + return poll(pollfds, nfds, timeout); +} + +int poll_check(int fd, short event) +{ + nfds_t i = fd_search(fd); + + if (i < nfds && pollfds[i].fd == fd) + return pollfds[i].revents & event; + + return 0; +} + +void poll_listen(int fd, short event) +{ + nfds_t i = fd_search(fd); + + if (i < nfds && pollfds[i].fd == fd) + pollfds[i].events |= event; + else + { + if (arrsize != nfds) + memmove(&pollfds[i+1], &pollfds[i], (nfds - i) * sizeof(struct pollfd)); + else + { + /* Array too small, extend. */ + struct pollfd *new; + + arrsize = (arrsize == 0) ? 64 : arrsize * 2; + + if (!(new = whine_malloc(arrsize * sizeof(struct pollfd)))) + return; + + if (pollfds) + { + memcpy(new, pollfds, i * sizeof(struct pollfd)); + memcpy(&new[i+1], &pollfds[i], (nfds - i) * sizeof(struct pollfd)); + free(pollfds); + } + + pollfds = new; + } + + pollfds[i].fd = fd; + pollfds[i].events = event; + nfds++; + } +} |