File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / dnsmasq / src / poll.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Sep 27 11:02:07 2023 UTC (9 months, 1 week ago) by misho
Branches: dnsmasq, MAIN
CVS tags: v8_2p1, HEAD
Version 8.2p1

    1: /* dnsmasq is Copyright (c) 2000-2022 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: 	 {
  101: 	   /* Array too small, extend. */
  102: 	   struct pollfd *new;
  103: 
  104: 	   arrsize = (arrsize == 0) ? 64 : arrsize * 2;
  105: 
  106: 	   if (!(new = whine_realloc(pollfds, arrsize * sizeof(struct pollfd))))
  107: 	     return;
  108: 
  109: 	   pollfds = new;
  110: 	 }
  111: 
  112:        memmove(&pollfds[i+1], &pollfds[i], (nfds - i) * sizeof(struct pollfd));
  113: 
  114:        pollfds[i].fd = fd;
  115:        pollfds[i].events = event;
  116:        nfds++;
  117:      }
  118: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>