"Fossies" - the Fresh Open Source Software Archive

Member "wrk-4.2.0/src/ae_epoll.c" (7 Feb 2021, 4846 Bytes) of package /linux/www/wrk-4.2.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "ae_epoll.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 4.0.2_vs_4.1.0.

    1 /* Linux epoll(2) based ae.c module
    2  *
    3  * Copyright (c) 2009-2012, Salvatore Sanfilippo <antirez at gmail dot com>
    4  * All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions are met:
    8  *
    9  *   * Redistributions of source code must retain the above copyright notice,
   10  *     this list of conditions and the following disclaimer.
   11  *   * Redistributions in binary form must reproduce the above copyright
   12  *     notice, this list of conditions and the following disclaimer in the
   13  *     documentation and/or other materials provided with the distribution.
   14  *   * Neither the name of Redis nor the names of its contributors may be used
   15  *     to endorse or promote products derived from this software without
   16  *     specific prior written permission.
   17  *
   18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
   22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   28  * POSSIBILITY OF SUCH DAMAGE.
   29  */
   30 
   31 
   32 #include <sys/epoll.h>
   33 
   34 typedef struct aeApiState {
   35     int epfd;
   36     struct epoll_event *events;
   37 } aeApiState;
   38 
   39 static int aeApiCreate(aeEventLoop *eventLoop) {
   40     aeApiState *state = zmalloc(sizeof(aeApiState));
   41 
   42     if (!state) return -1;
   43     state->events = zmalloc(sizeof(struct epoll_event)*eventLoop->setsize);
   44     if (!state->events) {
   45         zfree(state);
   46         return -1;
   47     }
   48     state->epfd = epoll_create(1024); /* 1024 is just a hint for the kernel */
   49     if (state->epfd == -1) {
   50         zfree(state->events);
   51         zfree(state);
   52         return -1;
   53     }
   54     eventLoop->apidata = state;
   55     return 0;
   56 }
   57 
   58 static int aeApiResize(aeEventLoop *eventLoop, int setsize) {
   59     aeApiState *state = eventLoop->apidata;
   60 
   61     state->events = zrealloc(state->events, sizeof(struct epoll_event)*setsize);
   62     return 0;
   63 }
   64 
   65 static void aeApiFree(aeEventLoop *eventLoop) {
   66     aeApiState *state = eventLoop->apidata;
   67 
   68     close(state->epfd);
   69     zfree(state->events);
   70     zfree(state);
   71 }
   72 
   73 static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) {
   74     aeApiState *state = eventLoop->apidata;
   75     struct epoll_event ee = {0}; /* avoid valgrind warning */
   76     /* If the fd was already monitored for some event, we need a MOD
   77      * operation. Otherwise we need an ADD operation. */
   78     int op = eventLoop->events[fd].mask == AE_NONE ?
   79             EPOLL_CTL_ADD : EPOLL_CTL_MOD;
   80 
   81     ee.events = 0;
   82     mask |= eventLoop->events[fd].mask; /* Merge old events */
   83     if (mask & AE_READABLE) ee.events |= EPOLLIN;
   84     if (mask & AE_WRITABLE) ee.events |= EPOLLOUT;
   85     ee.data.fd = fd;
   86     if (epoll_ctl(state->epfd,op,fd,&ee) == -1) return -1;
   87     return 0;
   88 }
   89 
   90 static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int delmask) {
   91     aeApiState *state = eventLoop->apidata;
   92     struct epoll_event ee = {0}; /* avoid valgrind warning */
   93     int mask = eventLoop->events[fd].mask & (~delmask);
   94 
   95     ee.events = 0;
   96     if (mask & AE_READABLE) ee.events |= EPOLLIN;
   97     if (mask & AE_WRITABLE) ee.events |= EPOLLOUT;
   98     ee.data.fd = fd;
   99     if (mask != AE_NONE) {
  100         epoll_ctl(state->epfd,EPOLL_CTL_MOD,fd,&ee);
  101     } else {
  102         /* Note, Kernel < 2.6.9 requires a non null event pointer even for
  103          * EPOLL_CTL_DEL. */
  104         epoll_ctl(state->epfd,EPOLL_CTL_DEL,fd,&ee);
  105     }
  106 }
  107 
  108 static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) {
  109     aeApiState *state = eventLoop->apidata;
  110     int retval, numevents = 0;
  111 
  112     retval = epoll_wait(state->epfd,state->events,eventLoop->setsize,
  113             tvp ? (tvp->tv_sec*1000 + tvp->tv_usec/1000) : -1);
  114     if (retval > 0) {
  115         int j;
  116 
  117         numevents = retval;
  118         for (j = 0; j < numevents; j++) {
  119             int mask = 0;
  120             struct epoll_event *e = state->events+j;
  121 
  122             if (e->events & EPOLLIN) mask |= AE_READABLE;
  123             if (e->events & EPOLLOUT) mask |= AE_WRITABLE;
  124             if (e->events & EPOLLERR) mask |= AE_WRITABLE;
  125             if (e->events & EPOLLHUP) mask |= AE_WRITABLE;
  126             eventLoop->fired[j].fd = e->data.fd;
  127             eventLoop->fired[j].mask = mask;
  128         }
  129     }
  130     return numevents;
  131 }
  132 
  133 static char *aeApiName(void) {
  134     return "epoll";
  135 }