]>
git.saurik.com Git - redis.git/blob - src/ae_epoll.c
   1 /* Linux epoll(2) based ae.c module 
   2  * Copyright (C) 2009-2010 Salvatore Sanfilippo - antirez@gmail.com 
   3  * Released under the BSD license. See the COPYING file for more info. */ 
   7 typedef struct aeApiState 
{ 
   9     struct epoll_event 
*events
; 
  12 static int aeApiCreate(aeEventLoop 
*eventLoop
) { 
  13     aeApiState 
*state 
= zmalloc(sizeof(aeApiState
)); 
  15     if (!state
) return -1; 
  16     state
->events 
= zmalloc(sizeof(struct epoll_event
)*eventLoop
->setsize
); 
  21     state
->epfd 
= epoll_create(1024); /* 1024 is just an hint for the kernel */ 
  22     if (state
->epfd 
== -1) { 
  27     eventLoop
->apidata 
= state
; 
  31 static void aeApiFree(aeEventLoop 
*eventLoop
) { 
  32     aeApiState 
*state 
= eventLoop
->apidata
; 
  39 static int aeApiAddEvent(aeEventLoop 
*eventLoop
, int fd
, int mask
) { 
  40     aeApiState 
*state 
= eventLoop
->apidata
; 
  41     struct epoll_event ee
; 
  42     /* If the fd was already monitored for some event, we need a MOD 
  43      * operation. Otherwise we need an ADD operation. */ 
  44     int op 
= eventLoop
->events
[fd
].mask 
== AE_NONE 
? 
  45             EPOLL_CTL_ADD 
: EPOLL_CTL_MOD
; 
  48     mask 
|= eventLoop
->events
[fd
].mask
; /* Merge old events */ 
  49     if (mask 
& AE_READABLE
) ee
.events 
|= EPOLLIN
; 
  50     if (mask 
& AE_WRITABLE
) ee
.events 
|= EPOLLOUT
; 
  51     ee
.data
.u64 
= 0; /* avoid valgrind warning */ 
  53     if (epoll_ctl(state
->epfd
,op
,fd
,&ee
) == -1) return -1; 
  57 static void aeApiDelEvent(aeEventLoop 
*eventLoop
, int fd
, int delmask
) { 
  58     aeApiState 
*state 
= eventLoop
->apidata
; 
  59     struct epoll_event ee
; 
  60     int mask 
= eventLoop
->events
[fd
].mask 
& (~delmask
); 
  63     if (mask 
& AE_READABLE
) ee
.events 
|= EPOLLIN
; 
  64     if (mask 
& AE_WRITABLE
) ee
.events 
|= EPOLLOUT
; 
  65     ee
.data
.u64 
= 0; /* avoid valgrind warning */ 
  67     if (mask 
!= AE_NONE
) { 
  68         epoll_ctl(state
->epfd
,EPOLL_CTL_MOD
,fd
,&ee
); 
  70         /* Note, Kernel < 2.6.9 requires a non null event pointer even for 
  72         epoll_ctl(state
->epfd
,EPOLL_CTL_DEL
,fd
,&ee
); 
  76 static int aeApiPoll(aeEventLoop 
*eventLoop
, struct timeval 
*tvp
) { 
  77     aeApiState 
*state 
= eventLoop
->apidata
; 
  78     int retval
, numevents 
= 0; 
  80     retval 
= epoll_wait(state
->epfd
,state
->events
,eventLoop
->setsize
, 
  81             tvp 
? (tvp
->tv_sec
*1000 + tvp
->tv_usec
/1000) : -1); 
  86         for (j 
= 0; j 
< numevents
; j
++) { 
  88             struct epoll_event 
*e 
= state
->events
+j
; 
  90             if (e
->events 
& EPOLLIN
) mask 
|= AE_READABLE
; 
  91             if (e
->events 
& EPOLLOUT
) mask 
|= AE_WRITABLE
; 
  92             if (e
->events 
& EPOLLERR
) mask 
|= AE_WRITABLE
; 
  93             if (e
->events 
& EPOLLHUP
) mask 
|= AE_WRITABLE
; 
  94             eventLoop
->fired
[j
].fd 
= e
->data
.fd
; 
  95             eventLoop
->fired
[j
].mask 
= mask
; 
 101 static char *aeApiName(void) {