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