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>