xref: /redis-3.2.3/src/ae_select.c (revision ad4c0b41)
1 /* Select()-based ae.c module
2  * Copyright (C) 2009-2010 Salvatore Sanfilippo - [email protected]
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;
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;
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     eventLoop->apidata = state;
21     return 0;
22 }
23 
24 static void aeApiFree(aeEventLoop *eventLoop) {
25     zfree(eventLoop->apidata);
26 }
27 
28 static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) {
29     aeApiState *state = eventLoop->apidata;
30 
31     if (mask & AE_READABLE) FD_SET(fd,&state->rfds);
32     if (mask & AE_WRITABLE) FD_SET(fd,&state->wfds);
33     return 0;
34 }
35 
36 static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int mask) {
37     aeApiState *state = eventLoop->apidata;
38 
39     if (mask & AE_READABLE) FD_CLR(fd,&state->rfds);
40     if (mask & AE_WRITABLE) FD_CLR(fd,&state->wfds);
41 }
42 
43 static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) {
44     aeApiState *state = eventLoop->apidata;
45     int retval, j, numevents = 0;
46 
47     memcpy(&state->_rfds,&state->rfds,sizeof(fd_set));
48     memcpy(&state->_wfds,&state->wfds,sizeof(fd_set));
49 
50     retval = select(eventLoop->maxfd+1,
51                 &state->_rfds,&state->_wfds,NULL,tvp);
52     if (retval > 0) {
53         for (j = 0; j <= eventLoop->maxfd; j++) {
54             int mask = 0;
55             aeFileEvent *fe = &eventLoop->events[j];
56 
57             if (fe->mask == AE_NONE) continue;
58             if (fe->mask & AE_READABLE && FD_ISSET(j,&state->_rfds))
59                 mask |= AE_READABLE;
60             if (fe->mask & AE_WRITABLE && FD_ISSET(j,&state->_wfds))
61                 mask |= AE_WRITABLE;
62             eventLoop->fired[numevents].fd = j;
63             eventLoop->fired[numevents].mask = mask;
64             numevents++;
65         }
66     }
67     return numevents;
68 }
69 
70 static char *aeApiName(void) {
71     return "select";
72 }
73