diff --git a/src/kernel/mpoller.c b/src/kernel/mpoller.c index 65941d63..aa4929ef 100644 --- a/src/kernel/mpoller.c +++ b/src/kernel/mpoller.c @@ -21,24 +21,36 @@ #include "poller.h" #include "mpoller.h" +extern poller_t *__poller_create(void **, const struct poller_params *); +extern void __poller_destroy(poller_t *); + static int __mpoller_create(const struct poller_params *params, mpoller_t *mpoller) { + void **nodes_buf = (void **)calloc(params->max_open_files, sizeof (void *)); unsigned int i; - for (i = 0; i < mpoller->nthreads; i++) + if (nodes_buf) { - mpoller->poller[i] = poller_create(params); - if (!mpoller->poller[i]) - break; + for (i = 0; i < mpoller->nthreads; i++) + { + mpoller->poller[i] = __poller_create(nodes_buf, params); + if (!mpoller->poller[i]) + break; + } + + if (i == mpoller->nthreads) + { + mpoller->nodes_buf = nodes_buf; + return 0; + } + + while (i > 0) + poller_destroy(mpoller->poller[--i]); + + free(nodes_buf); } - if (i == mpoller->nthreads) - return 0; - - while (i > 0) - poller_destroy(mpoller->poller[--i]); - return -1; } @@ -96,8 +108,9 @@ void mpoller_destroy(mpoller_t *mpoller) size_t i; for (i = 0; i < mpoller->nthreads; i++) - poller_destroy(mpoller->poller[i]); + __poller_destroy(mpoller->poller[i]); + free(mpoller->nodes_buf); free(mpoller); } diff --git a/src/kernel/mpoller.h b/src/kernel/mpoller.h index b8941600..b9211ff4 100644 --- a/src/kernel/mpoller.h +++ b/src/kernel/mpoller.h @@ -41,6 +41,7 @@ void mpoller_destroy(mpoller_t *mpoller); struct __mpoller { + void **nodes_buf; unsigned int nthreads; poller_t *poller[1]; }; diff --git a/src/kernel/poller.c b/src/kernel/poller.c index 95993ee0..e315aef9 100644 --- a/src/kernel/poller.c +++ b/src/kernel/poller.c @@ -42,9 +42,7 @@ #include "poller.h" #define POLLER_BUFSIZE (256 * 1024) -#define POLLER_NODES_MAX 65536 #define POLLER_EVENTS_MAX 256 -#define POLLER_NODE_ERROR ((struct __poller_node *)-1) struct __poller_node { @@ -1075,70 +1073,81 @@ static int __poller_create_timer(poller_t *poller) return -1; } -poller_t *poller_create(const struct poller_params *params) +poller_t *__poller_create(void **nodes_buf, const struct poller_params *params) { poller_t *poller = (poller_t *)malloc(sizeof (poller_t)); - size_t n; int ret; if (!poller) return NULL; - n = params->max_open_files; - if (n == 0) - n = POLLER_NODES_MAX; - - poller->nodes = (struct __poller_node **)calloc(n, sizeof (void *)); - if (poller->nodes) + poller->pfd = __poller_create_pfd(); + if (poller->pfd >= 0) { - poller->pfd = __poller_create_pfd(); - if (poller->pfd >= 0) + if (__poller_create_timer(poller) >= 0) { - if (__poller_create_timer(poller) >= 0) + ret = pthread_mutex_init(&poller->mutex, NULL); + if (ret == 0) { - ret = pthread_mutex_init(&poller->mutex, NULL); - if (ret == 0) - { - poller->max_open_files = n; - poller->create_message = params->create_message; - poller->partial_written = params->partial_written; - poller->cb = params->callback; - poller->ctx = params->context; + poller->nodes = (struct __poller_node **)nodes_buf; + poller->max_open_files = params->max_open_files; + poller->create_message = params->create_message; + poller->partial_written = params->partial_written; + poller->cb = params->callback; + poller->ctx = params->context; - poller->timeo_tree.rb_node = NULL; - poller->tree_first = NULL; - poller->tree_last = NULL; - INIT_LIST_HEAD(&poller->timeo_list); - INIT_LIST_HEAD(&poller->no_timeo_list); - poller->nodes[poller->timerfd] = POLLER_NODE_ERROR; - poller->nodes[poller->pfd] = POLLER_NODE_ERROR; - poller->stopped = 1; - return poller; - } + poller->timeo_tree.rb_node = NULL; + poller->tree_first = NULL; + poller->tree_last = NULL; + INIT_LIST_HEAD(&poller->timeo_list); + INIT_LIST_HEAD(&poller->no_timeo_list); - errno = ret; - close(poller->timerfd); + poller->stopped = 1; + return poller; } - close(poller->pfd); + errno = ret; + close(poller->timerfd); } - free(poller->nodes); + close(poller->pfd); } free(poller); return NULL; } -void poller_destroy(poller_t *poller) +poller_t *poller_create(const struct poller_params *params) +{ + void **nodes_buf = (void **)calloc(params->max_open_files, sizeof (void *)); + poller_t *poller; + + if (nodes_buf) + { + poller = __poller_create(nodes_buf, params); + if (poller) + return poller; + + free(nodes_buf); + } + + return NULL; +} + +void __poller_destroy(poller_t *poller) { pthread_mutex_destroy(&poller->mutex); close(poller->timerfd); close(poller->pfd); - free(poller->nodes); free(poller); } +void poller_destroy(poller_t *poller) +{ + free(poller->nodes); + __poller_destroy(poller); +} + int poller_start(poller_t *poller) { pthread_t tid; @@ -1151,8 +1160,6 @@ int poller_start(poller_t *poller) if (ret == 0) { poller->tid = tid; - poller->nodes[poller->pipe_rd] = POLLER_NODE_ERROR; - poller->nodes[poller->pipe_wr] = POLLER_NODE_ERROR; poller->stopped = 0; } else @@ -1294,9 +1301,6 @@ int poller_add(const struct poller_data *data, int timeout, poller_t *poller) node = NULL; } } - else if (poller->nodes[data->fd] == POLLER_NODE_ERROR) - errno = EINVAL; - else errno = EEXIST; pthread_mutex_unlock(&poller->mutex); @@ -1391,7 +1395,7 @@ int poller_mod(const struct poller_data *data, int timeout, poller_t *poller) pthread_mutex_lock(&poller->mutex); old = poller->nodes[data->fd]; - if (old && old != POLLER_NODE_ERROR) + if (old) { if (__poller_mod_fd(data->fd, old->event, event, node, poller) >= 0) { @@ -1422,8 +1426,6 @@ int poller_mod(const struct poller_data *data, int timeout, poller_t *poller) node = NULL; } } - else if (old == POLLER_NODE_ERROR) - errno = EINVAL; else errno = ENOENT;