79 lines
2.4 KiB
C
79 lines
2.4 KiB
C
/* Select()-based ae.c module
|
|
* Copyright (C) 2009 Salvatore Sanfilippo - antirez@gmail.com
|
|
* Released under the BSD license. See the COPYING file for more info. */
|
|
|
|
#include <string.h>
|
|
|
|
typedef struct aeApiState {
|
|
fd_set rfds, wfds, efds;
|
|
/* We need to have a copy of the fd sets as it's not safe to reuse
|
|
* FD sets after select(). */
|
|
fd_set _rfds, _wfds, _efds;
|
|
} aeApiState;
|
|
|
|
static int aeApiCreate(aeEventLoop *eventLoop) {
|
|
aeApiState *state = zmalloc(sizeof(aeApiState));
|
|
|
|
if (!state) return -1;
|
|
FD_ZERO(&state->rfds);
|
|
FD_ZERO(&state->wfds);
|
|
FD_ZERO(&state->efds);
|
|
eventLoop->apidata = state;
|
|
return 0;
|
|
}
|
|
|
|
static void aeApiFree(aeEventLoop *eventLoop) {
|
|
zfree(eventLoop->apidata);
|
|
}
|
|
|
|
static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) {
|
|
aeApiState *state = eventLoop->apidata;
|
|
|
|
if (mask & AE_READABLE) FD_SET(fd,&state->rfds);
|
|
if (mask & AE_WRITABLE) FD_SET(fd,&state->wfds);
|
|
if (mask & AE_EXCEPTION) FD_SET(fd,&state->efds);
|
|
return 0;
|
|
}
|
|
|
|
static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int mask) {
|
|
aeApiState *state = eventLoop->apidata;
|
|
|
|
if (mask & AE_READABLE) FD_CLR(fd,&state->rfds);
|
|
if (mask & AE_WRITABLE) FD_CLR(fd,&state->wfds);
|
|
if (mask & AE_EXCEPTION) FD_CLR(fd,&state->efds);
|
|
}
|
|
|
|
static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) {
|
|
aeApiState *state = eventLoop->apidata;
|
|
int retval, j, numevents = 0;
|
|
|
|
memcpy(&state->_rfds,&state->rfds,sizeof(fd_set));
|
|
memcpy(&state->_wfds,&state->wfds,sizeof(fd_set));
|
|
memcpy(&state->_efds,&state->efds,sizeof(fd_set));
|
|
|
|
retval = select(eventLoop->maxfd+1,
|
|
&state->_rfds,&state->_wfds,&state->_efds,tvp);
|
|
if (retval > 0) {
|
|
for (j = 0; j <= eventLoop->maxfd; j++) {
|
|
int mask = 0;
|
|
aeFileEvent *fe = &eventLoop->events[j];
|
|
|
|
if (fe->mask == AE_NONE) continue;
|
|
if (fe->mask & AE_READABLE && FD_ISSET(j,&state->_rfds))
|
|
mask |= AE_READABLE;
|
|
if (fe->mask & AE_WRITABLE && FD_ISSET(j,&state->_wfds))
|
|
mask |= AE_WRITABLE;
|
|
if (fe->mask & AE_EXCEPTION && FD_ISSET(j,&state->_efds))
|
|
mask |= AE_EXCEPTION;
|
|
eventLoop->fired[numevents].fd = j;
|
|
eventLoop->fired[numevents].mask = mask;
|
|
numevents++;
|
|
}
|
|
}
|
|
return numevents;
|
|
}
|
|
|
|
static char *aeApiName(void) {
|
|
return "select";
|
|
}
|