]>
git.saurik.com Git - redis.git/blob - ae_kqueue.c
1 /* Kqueue(2)-based ae.c module
2 * Copyright (C) 2009 Harish Mallipeddi - harish.mallipeddi@gmail.com
3 * Released under the BSD license. See the COPYING file for more info. */
9 typedef struct aeApiState
{
11 struct kevent events
[AE_SETSIZE
];
14 static int aeApiCreate(aeEventLoop
*eventLoop
) {
15 aeApiState
*state
= zmalloc(sizeof(aeApiState
));
17 if (!state
) return -1;
18 state
->kqfd
= kqueue();
19 if (state
->kqfd
== -1) return -1;
20 eventLoop
->apidata
= state
;
25 static void aeApiFree(aeEventLoop
*eventLoop
) {
26 aeApiState
*state
= eventLoop
->apidata
;
32 static int aeApiAddEvent(aeEventLoop
*eventLoop
, int fd
, int mask
) {
33 aeApiState
*state
= eventLoop
->apidata
;
36 if (mask
& AE_READABLE
) {
37 EV_SET(&ke
, fd
, EVFILT_READ
, EV_ADD
, 0, 0, NULL
);
38 if (kevent(state
->kqfd
, &ke
, 1, NULL
, 0, NULL
) == -1) return -1;
40 if (mask
& AE_WRITABLE
) {
41 EV_SET(&ke
, fd
, EVFILT_WRITE
, EV_ADD
, 0, 0, NULL
);
42 if (kevent(state
->kqfd
, &ke
, 1, NULL
, 0, NULL
) == -1) return -1;
47 static void aeApiDelEvent(aeEventLoop
*eventLoop
, int fd
, int mask
) {
48 aeApiState
*state
= eventLoop
->apidata
;
51 if (mask
& AE_READABLE
) {
52 EV_SET(&ke
, fd
, EVFILT_READ
, EV_DELETE
, 0, 0, NULL
);
53 kevent(state
->kqfd
, &ke
, 1, NULL
, 0, NULL
);
55 if (mask
& AE_WRITABLE
) {
56 EV_SET(&ke
, fd
, EVFILT_WRITE
, EV_DELETE
, 0, 0, NULL
);
57 kevent(state
->kqfd
, &ke
, 1, NULL
, 0, NULL
);
61 static int aeApiPoll(aeEventLoop
*eventLoop
, struct timeval
*tvp
) {
62 aeApiState
*state
= eventLoop
->apidata
;
63 int retval
, numevents
= 0;
66 struct timespec timeout
;
67 timeout
.tv_sec
= tvp
->tv_sec
;
68 timeout
.tv_nsec
= tvp
->tv_usec
* 1000;
69 retval
= kevent(state
->kqfd
, NULL
, 0, state
->events
, AE_SETSIZE
, &timeout
);
71 retval
= kevent(state
->kqfd
, NULL
, 0, state
->events
, AE_SETSIZE
, NULL
);
78 for(j
= 0; j
< numevents
; j
++) {
80 struct kevent
*e
= state
->events
+j
;
82 if (e
->filter
== EVFILT_READ
) mask
|= AE_READABLE
;
83 if (e
->filter
== EVFILT_WRITE
) mask
|= AE_WRITABLE
;
84 eventLoop
->fired
[j
].fd
= e
->ident
;
85 eventLoop
->fired
[j
].mask
= mask
;