summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2013-06-28 16:39:49 +0200
committerantirez <antirez@gmail.com>2013-06-28 16:39:49 +0200
commit8e2d082066e5b9892ead6cd30e8d3852d02fbc04 (patch)
tree1422465efe7dfb3cb8e4b78166c13800e99a72b9
parent3130670b978e0d4baa805016386e5ca56af08123 (diff)
downloadredis-8e2d082066e5b9892ead6cd30e8d3852d02fbc04.tar.gz
ae.c event loop: API to resize the fd set size on the run.
-rw-r--r--src/ae.c30
-rw-r--r--src/ae.h2
-rw-r--r--src/ae_epoll.c7
-rw-r--r--src/ae_evport.c5
-rw-r--r--src/ae_kqueue.c8
-rw-r--r--src/ae_select.c6
6 files changed, 57 insertions, 1 deletions
diff --git a/src/ae.c b/src/ae.c
index 6ca9a5153..164f8fdeb 100644
--- a/src/ae.c
+++ b/src/ae.c
@@ -91,6 +91,36 @@ err:
return NULL;
}
+/* Return the current set size. */
+int aeGetSetSize(aeEventLoop *eventLoop) {
+ return eventLoop->setsize;
+}
+
+/* Resize the maximum set size of the event loop.
+ * If the requested set size is smaller than the current set size, but
+ * there is already a file descriptor in use that is >= the requested
+ * set size minus one, AE_ERR is returned and the operation is not
+ * performed at all.
+ *
+ * Otherwise AE_OK is returned and the operation is successful. */
+int aeResizeSetSize(aeEventLoop *eventLoop, int setsize) {
+ int i;
+
+ if (setsize == eventLoop->setsize) return AE_OK;
+ if (eventLoop->maxfd >= setsize) return AE_ERR;
+ if (aeApiResize(eventLoop,setsize) == -1) return AE_ERR;
+
+ eventLoop->events = zrealloc(eventLoop->events,sizeof(aeFileEvent)*setsize);
+ eventLoop->fired = zrealloc(eventLoop->fired,sizeof(aeFiredEvent)*setsize);
+ eventLoop->setsize = setsize;
+
+ /* Make sure that if we created new slots, they are initialized with
+ * an AE_NONE mask. */
+ for (i = eventLoop->maxfd+1; i < setsize; i++)
+ eventLoop->events[i].mask = AE_NONE;
+ return AE_OK;
+}
+
void aeDeleteEventLoop(aeEventLoop *eventLoop) {
aeApiFree(eventLoop);
zfree(eventLoop->events);
diff --git a/src/ae.h b/src/ae.h
index 4d8950242..15ca1b5e7 100644
--- a/src/ae.h
+++ b/src/ae.h
@@ -114,5 +114,7 @@ int aeWait(int fd, int mask, long long milliseconds);
void aeMain(aeEventLoop *eventLoop);
char *aeGetApiName(void);
void aeSetBeforeSleepProc(aeEventLoop *eventLoop, aeBeforeSleepProc *beforesleep);
+int aeGetSetSize(aeEventLoop *eventLoop);
+int aeResizeSetSize(aeEventLoop *eventLoop, int setsize);
#endif
diff --git a/src/ae_epoll.c b/src/ae_epoll.c
index 4823c281e..41af3e874 100644
--- a/src/ae_epoll.c
+++ b/src/ae_epoll.c
@@ -55,6 +55,13 @@ static int aeApiCreate(aeEventLoop *eventLoop) {
return 0;
}
+static int aeApiResize(aeEventLoop *eventLoop, int setsize) {
+ aeApiState *state = eventLoop->apidata;
+
+ state->events = zrealloc(state->events, sizeof(struct epoll_event)*setsize);
+ return 0;
+}
+
static void aeApiFree(aeEventLoop *eventLoop) {
aeApiState *state = eventLoop->apidata;
diff --git a/src/ae_evport.c b/src/ae_evport.c
index 94413c132..5c317becb 100644
--- a/src/ae_evport.c
+++ b/src/ae_evport.c
@@ -94,6 +94,11 @@ static int aeApiCreate(aeEventLoop *eventLoop) {
return 0;
}
+static int aeApiResize(aeEventLoop *eventLoop, int setsize) {
+ /* Nothing to resize here. */
+ return 0;
+}
+
static void aeApiFree(aeEventLoop *eventLoop) {
aeApiState *state = eventLoop->apidata;
diff --git a/src/ae_kqueue.c b/src/ae_kqueue.c
index 458772f7e..dbcc5805f 100644
--- a/src/ae_kqueue.c
+++ b/src/ae_kqueue.c
@@ -54,10 +54,16 @@ static int aeApiCreate(aeEventLoop *eventLoop) {
return -1;
}
eventLoop->apidata = state;
-
return 0;
}
+static int aeApiResize(aeEventLoop *eventLoop, int setsize) {
+ aeApiState *state = eventLoop->apidata;
+
+ state->events = zrealloc(state->events, sizeof(struct kevent)*setsize);
+ return 0;
+}
+
static void aeApiFree(aeEventLoop *eventLoop) {
aeApiState *state = eventLoop->apidata;
diff --git a/src/ae_select.c b/src/ae_select.c
index f732e8e1e..e2b7a9e8a 100644
--- a/src/ae_select.c
+++ b/src/ae_select.c
@@ -48,6 +48,12 @@ static int aeApiCreate(aeEventLoop *eventLoop) {
return 0;
}
+static int aeApiResize(aeEventLoop *eventLoop, int setsize) {
+ /* Just ensure we have enough room in the fd_set type. */
+ if (setsize >= FD_SETSIZE) return -1;
+ return 0;
+}
+
static void aeApiFree(aeEventLoop *eventLoop) {
zfree(eventLoop->apidata);
}