]> git.saurik.com Git - redis.git/blob - ae_select.c
New vararg BLPOP able to block against multiple keys
[redis.git] / ae_select.c
1 /* Select()-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. */
4
5 #include <string.h>
6
7 typedef struct aeApiState {
8 fd_set rfds, wfds, efds;
9 /* We need to have a copy of the fd sets as it's not safe to reuse
10 * FD sets after select(). */
11 fd_set _rfds, _wfds, _efds;
12 } aeApiState;
13
14 static int aeApiCreate(aeEventLoop *eventLoop) {
15 aeApiState *state = zmalloc(sizeof(aeApiState));
16
17 if (!state) return -1;
18 FD_ZERO(&state->rfds);
19 FD_ZERO(&state->wfds);
20 FD_ZERO(&state->efds);
21 eventLoop->apidata = state;
22 return 0;
23 }
24
25 static void aeApiFree(aeEventLoop *eventLoop) {
26 zfree(eventLoop->apidata);
27 }
28
29 static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) {
30 aeApiState *state = eventLoop->apidata;
31
32 if (mask & AE_READABLE) FD_SET(fd,&state->rfds);
33 if (mask & AE_WRITABLE) FD_SET(fd,&state->wfds);
34 if (mask & AE_EXCEPTION) FD_SET(fd,&state->efds);
35 return 0;
36 }
37
38 static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int mask) {
39 aeApiState *state = eventLoop->apidata;
40
41 if (mask & AE_READABLE) FD_CLR(fd,&state->rfds);
42 if (mask & AE_WRITABLE) FD_CLR(fd,&state->wfds);
43 if (mask & AE_EXCEPTION) FD_CLR(fd,&state->efds);
44 }
45
46 static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) {
47 aeApiState *state = eventLoop->apidata;
48 int retval, j, numevents = 0;
49
50 memcpy(&state->_rfds,&state->rfds,sizeof(fd_set));
51 memcpy(&state->_wfds,&state->wfds,sizeof(fd_set));
52 memcpy(&state->_efds,&state->efds,sizeof(fd_set));
53
54 retval = select(eventLoop->maxfd+1,
55 &state->_rfds,&state->_wfds,&state->_efds,tvp);
56 if (retval > 0) {
57 for (j = 0; j <= eventLoop->maxfd; j++) {
58 int mask = 0;
59 aeFileEvent *fe = &eventLoop->events[j];
60
61 if (fe->mask == AE_NONE) continue;
62 if (fe->mask & AE_READABLE && FD_ISSET(j,&state->_rfds))
63 mask |= AE_READABLE;
64 if (fe->mask & AE_WRITABLE && FD_ISSET(j,&state->_wfds))
65 mask |= AE_WRITABLE;
66 if (fe->mask & AE_EXCEPTION && FD_ISSET(j,&state->_efds))
67 mask |= AE_EXCEPTION;
68 eventLoop->fired[numevents].fd = j;
69 eventLoop->fired[numevents].mask = mask;
70 numevents++;
71 }
72 }
73 return numevents;
74 }
75
76 static char *aeApiName(void) {
77 return "select";
78 }