1 /* Select()-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. */
4 
5 #include <string.h>
6 
7 typedef struct aeApiState
8 {
9     int maxfd;
10     fd_set rfds, wfds;
11     /* We need to have a copy of the fd sets as it's not safe to reuse
12      * FD sets after select(). */
13     fd_set _rfds, _wfds;
14 } aeApiState;
15 
aeApiCreate(EventLoop * eventLoop)16 static int aeApiCreate(EventLoop *eventLoop)
17 {
18     aeApiState *state = malloc(sizeof(aeApiState));
19 
20     if (!state) return -1;
21     FD_ZERO(&state->rfds);
22     FD_ZERO(&state->wfds);
23     eventLoop->apidata = state;
24     return 0;
25 }
26 
aeApiFree(EventLoop * eventLoop)27 static void aeApiFree(EventLoop *eventLoop)
28 {
29     free(eventLoop->apidata);
30 }
31 
aeApiAddEvent(EventLoop * eventLoop,int fd,int mask)32 static int aeApiAddEvent(EventLoop *eventLoop, int fd, int mask)
33 {
34     aeApiState *state = eventLoop->apidata;
35 
36     if (mask & AE_READABLE) FD_SET(fd,&state->rfds);
37     if (mask & AE_WRITABLE) FD_SET(fd,&state->wfds);
38 
39     if (fd > state->maxfd)
40     {
41         state->maxfd = fd;
42     }
43     return 0;
44 }
45 
aeApiUpdateEvent(EventLoop * eventLoop,int fd,int mask)46 static int aeApiUpdateEvent(EventLoop *eventLoop, int fd, int mask)
47 {
48     return aeApiAddEvent(eventLoop, fd, mask);
49 }
50 
aeApiDelEvent(EventLoop * eventLoop,int fd)51 static int aeApiDelEvent(EventLoop *eventLoop, int fd)
52 {
53     aeApiState *state = eventLoop->apidata;
54 
55     FD_CLR(fd,&state->rfds);
56     FD_CLR(fd,&state->wfds);
57     return 0;
58 }
59 
aeApiPoll(EventLoop * eventLoop,struct timeval * tvp)60 static int aeApiPoll(EventLoop *eventLoop, struct timeval *tvp)
61 {
62     aeApiState *state = eventLoop->apidata;
63     int retval, j, numevents = 0;
64 
65     memcpy(&state->_rfds,&state->rfds,sizeof(fd_set));
66     memcpy(&state->_wfds,&state->wfds,sizeof(fd_set));
67 
68     retval = select(state->maxfd+1,
69                     &state->_rfds,&state->_wfds,NULL,tvp);
70     if (retval > 0)
71     {
72         for (j = 0; j <= state->maxfd; j++)
73         {
74             if (FD_ISSET(j,&state->_rfds) || FD_ISSET(j,&state->_wfds))
75             {
76                 eventLoop->fired[numevents] = j;
77                 numevents++;
78             }
79         }
80     }
81     return numevents;
82 }
83 
aeApiName(void)84 static char *aeApiName(void)
85 {
86     return "select";
87 }
88