]>
git.saurik.com Git - redis.git/blob - ae_epoll.c
ce9ce3b0196c641f9932ad7ba178cdaab43fd6dc
1 /* Linux epoll(2) based ae.c module
2 * Copyright (C) 2009 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
[AE_SETSIZE
];
12 static int aeApiCreate(aeEventLoop
*eventLoop
) {
13 aeApiState
*state
= zmalloc(sizeof(aeApiState
));
15 if (!state
) return -1;
16 state
->epfd
= epoll_create(1024); /* 1024 is just an hint for the kernel */
17 if (state
->epfd
== -1) return -1;
18 eventLoop
->apidata
= state
;
22 static void aeApiFree(aeEventLoop
*eventLoop
) {
23 aeApiState
*state
= eventLoop
->apidata
;
29 static int aeApiAddEvent(aeEventLoop
*eventLoop
, int fd
, int mask
) {
30 aeApiState
*state
= eventLoop
->apidata
;
31 struct epoll_event ee
;
32 /* If the fd was already monitored for some event, we need a MOD
33 * operation. Otherwise we need an ADD operation. */
34 int op
= eventLoop
->events
[fd
].mask
== AE_NONE
?
35 EPOLL_CTL_ADD
: EPOLL_CTL_MOD
;
38 mask
|= eventLoop
->events
[fd
].mask
; /* Merge old events */
39 if (mask
& AE_READABLE
) ee
.events
|= EPOLLIN
;
40 if (mask
& AE_WRITABLE
) ee
.events
|= EPOLLOUT
;
41 if (mask
& AE_EXCEPTION
) ee
.events
|= EPOLLPRI
;
42 ee
.data
.u64
= 0; /* avoid valgrind warning */
44 if (epoll_ctl(state
->epfd
,op
,fd
,&ee
) == -1) return -1;
48 static void aeApiDelEvent(aeEventLoop
*eventLoop
, int fd
, int delmask
) {
49 aeApiState
*state
= eventLoop
->apidata
;
50 struct epoll_event ee
;
51 int mask
= eventLoop
->events
[fd
].mask
& (~delmask
);
54 if (mask
& AE_READABLE
) ee
.events
|= EPOLLIN
;
55 if (mask
& AE_WRITABLE
) ee
.events
|= EPOLLOUT
;
56 if (mask
& AE_EXCEPTION
) ee
.events
|= EPOLLPRI
;
57 ee
.data
.u64
= 0; /* avoid valgrind warning */
59 if (mask
!= AE_NONE
) {
60 epoll_ctl(state
->epfd
,EPOLL_CTL_MOD
,fd
,&ee
);
62 /* Note, Kernel < 2.6.9 requires a non null event pointer even for
64 epoll_ctl(state
->epfd
,EPOLL_CTL_DEL
,fd
,&ee
);
68 static int aeApiPoll(aeEventLoop
*eventLoop
, struct timeval
*tvp
) {
69 aeApiState
*state
= eventLoop
->apidata
;
70 int retval
, numevents
= 0;
72 retval
= epoll_wait(state
->epfd
,state
->events
,AE_SETSIZE
,
73 tvp
? (tvp
->tv_sec
*1000 + tvp
->tv_usec
/1000) : -1);
78 for (j
= 0; j
< numevents
; j
++) {
80 struct epoll_event
*e
= state
->events
+j
;
82 if (e
->events
& EPOLLIN
) mask
|= AE_READABLE
;
83 if (e
->events
& EPOLLOUT
) mask
|= AE_WRITABLE
;
84 if (e
->events
& EPOLLPRI
) mask
|= AE_EXCEPTION
;
85 eventLoop
->fired
[j
].fd
= e
->data
.fd
;
86 eventLoop
->fired
[j
].mask
= mask
;
92 static char *aeApiName(void) {