diff options
author | Luo Jinghua <sunmoon1997@gmail.com> | 2009-10-31 18:10:41 +0800 |
---|---|---|
committer | Luo Jinghua <sunmoon1997@gmail.com> | 2009-10-31 18:10:41 +0800 |
commit | 36d3e546e459efe2694e8f382e884e721d94c794 (patch) | |
tree | e6fba6df164a17abd065093c35d0b5d3d85dcd40 | |
parent | 2d981726ee0bf836418390132aec30ff83e15829 (diff) |
milkway: simpiled poll interface and implement them
-rw-r--r-- | milkway/mw-poll-select.c | 74 | ||||
-rw-r--r-- | milkway/mw-poll-sys-private.h | 3 | ||||
-rw-r--r-- | milkway/mw-poll-sys.c | 93 | ||||
-rw-r--r-- | milkway/mw-poll-win32.c | 36 | ||||
-rw-r--r-- | milkway/mw-poll.c | 59 | ||||
-rw-r--r-- | milkway/mw-poll.h | 49 |
6 files changed, 124 insertions, 190 deletions
diff --git a/milkway/mw-poll-select.c b/milkway/mw-poll-select.c index 20838c2..b724977 100644 --- a/milkway/mw-poll-select.c +++ b/milkway/mw-poll-select.c @@ -71,38 +71,52 @@ mw_poll_select_new(void) } static mw_bool_t -mw_poll_select_add_fd(mw_poll_t *super, - mw_pollfd_t *fd, - mw_error_t **reterr) -{ - mw_poll_select_t *self = (mw_poll_select_t*)super; - - if (!MW_SUPER_TYPE_MTH(super, MW_POLL_SELECT_TYPE, - mw_poll_type_t, add_fd) - (super, fd, reterr)) - return MW_FALSE; - return MW_TRUE; -} - -static mw_bool_t -mw_poll_select_remove_fd(mw_poll_t *super, - mw_uintptr_t fd, - mw_error_t **reterr) -{ - mw_poll_select_t *self = (mw_poll_select_t*)super; - - if (!MW_SUPER_TYPE_MTH(super, MW_POLL_SELECT_TYPE, - mw_poll_type_t, remove_fd) - (super, fd, reterr)) - return MW_FALSE; - return MW_TRUE; -} - -static mw_bool_t mw_poll_select_poll(mw_poll_t *super, - int timeout) + mw_pollfd_t *fds, + mw_uint_t nfds, + int timeout) { mw_poll_select_t *self = (mw_poll_select_t*)super; + struct timeval tv; + SELECT_MASK rset, wset, xset; + mw_pollfd_t *f; + int ready; + int maxfd = 0; + + FD_ZERO (&rset); + FD_ZERO (&wset); + FD_ZERO (&xset); + + for (f = fds; f < &fds[nfds]; ++f) + if (f->fd >= 0) { + if (f->events & MW_IO_IN) + FD_SET (f->fd, &rset); + if (f->events & MW_IO_OUT) + FD_SET (f->fd, &wset); + if (f->events & MW_IO_PRI) + FD_SET (f->fd, &xset); + if (f->fd > maxfd && (f->events & (MW_IO_IN | MW_IO_OUT | MW_IO_PRI))) + maxfd = f->fd; + } + + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + + ready = select (maxfd + 1, &rset, &wset, &xset, + timeout == -1 ? NULL : &tv); + if (ready > 0) { + for (f = fds; f < &fds[nfds]; ++f) { + f->revents = 0; + if (f->fd >= 0) { + if (FD_ISSET (f->fd, &rset)) + f->revents |= MW_IO_IN; + if (FD_ISSET (f->fd, &wset)) + f->revents |= MW_IO_OUT; + if (FD_ISSET (f->fd, &xset)) + f->revents |= MW_IO_PRI; + } + } + } return MW_FALSE; } @@ -120,8 +134,6 @@ static void mw_poll_select_type_init(mw_poll_select_type_t *self) { self->base.base.finalize = mw_poll_select_finalize; - self->base.add_fd = mw_poll_select_add_fd; - self->base.remove_fd = mw_poll_select_remove_fd; self->base.poll = mw_poll_select_poll; } diff --git a/milkway/mw-poll-sys-private.h b/milkway/mw-poll-sys-private.h index 6b57e09..7db29ec 100644 --- a/milkway/mw-poll-sys-private.h +++ b/milkway/mw-poll-sys-private.h @@ -27,6 +27,7 @@ #ifdef HAVE_POLL #include <milkway/mw-poll.h> +#include <milkway/mw-array.h> typedef struct mw_poll_sys_type mw_poll_sys_type_t; typedef struct mw_poll_sys mw_poll_sys_t; @@ -35,6 +36,8 @@ typedef struct mw_poll_sys mw_poll_sys_t; struct mw_poll_sys_type { mw_poll_type_t base; + + mw_array_t *array; }; mw_private mw_poll_t* diff --git a/milkway/mw-poll-sys.c b/milkway/mw-poll-sys.c index d48b7c9..9cc350e 100644 --- a/milkway/mw-poll-sys.c +++ b/milkway/mw-poll-sys.c @@ -46,6 +46,8 @@ extern int poll (struct pollfd *fds, unsigned int nfsd, int timeout); struct mw_poll_sys { mw_poll_t base; + + mw_array_t *array; }; static mw_poll_sys_t* @@ -54,6 +56,12 @@ mw_poll_sys_init(mw_poll_sys_t *self) if (!mw_poll_init(&self->base)) return NULL; + self->array = mw_array_sized_new(MW_FALSE, MW_FALSE, + sizeof(struct pollfd), 64); + if (!self->array) { + MW_SUPER_FINALIZE(self, MW_POLL_SYS_TYPE)((mw_object_t*)self); + return NULL; + } return self; } @@ -66,41 +74,70 @@ mw_poll_sys_new(void) return (mw_poll_t*)mw_poll_sys_init(self); } -static mw_bool_t -mw_poll_sys_add_fd(mw_poll_t *super, - mw_pollfd_t *fd, - mw_error_t **reterr) +static mw_inline unsigned short +poll_event_to_system_event(unsigned short e) { - mw_poll_sys_t *self = (mw_poll_sys_t*)super; - - if (!MW_SUPER_TYPE_MTH(super, MW_POLL_SYS_TYPE, - mw_poll_type_t, add_fd) - (super, fd, reterr)) - return MW_FALSE; - return MW_TRUE; + unsigned short r = 0; + if (e & MW_IO_IN) + r |= POLLIN; + if (e & MW_IO_OUT) + r |= POLLOUT; + if (e & MW_IO_PRI) + r |= POLLPRI; + + return r; } +static mw_inline unsigned short +poll_event_from_system_event(unsigned short e) +{ + unsigned short r = 0; + if (e & POLLIN) + r |= MW_IO_IN; + if (e & POLLOUT) + r |= MW_IO_OUT; + if (e & POLLPRI) + r |= MW_IO_PRI; + if (e & POLLERR) + r |= MW_IO_ERR; + if (e & POLLHUP) + r |= MW_IO_HUP; + if (e & POLLNVAL) + r |= MW_IO_NVAL; + + return r; +} static mw_bool_t -mw_poll_sys_remove_fd(mw_poll_t *super, - mw_uintptr_t fd, - mw_error_t **reterr) +mw_poll_sys_poll(mw_poll_t *super, + mw_pollfd_t *fds, + mw_uint_t nfds, + int timeout) { mw_poll_sys_t *self = (mw_poll_sys_t*)super; + mw_uint_t i; + int ret; - if (!MW_SUPER_TYPE_MTH(super, MW_POLL_SYS_TYPE, - mw_poll_type_t, remove_fd) - (super, fd, reterr)) + if (nfds) return MW_FALSE; - return MW_TRUE; -} -static mw_bool_t -mw_poll_sys_poll(mw_poll_t *super, - int timeout) -{ - mw_poll_sys_t *self = (mw_poll_sys_t*)super; + mw_array_set_size(self->array, nfds); + for (i = 0; i < nfds; i++) { + struct pollfd *fd = &mw_array_index(self->array, struct pollfd, i); + fd->fd = fds[i].fd; + fd->events = poll_event_to_system_event(fds[i].events); + fd->revents = 0; + } + + ret = poll (&mw_array_index(self->array, struct pollfd, 0), + nfds, timeout); + if (!ret || ret == 0) + return MW_FALSE; - return MW_FALSE; + for (i = 0; i < nfds; i++) { + struct pollfd *fd = &mw_array_index(self->array, struct pollfd, i); + fds[i].revents = poll_event_from_system_event(fd->revents); + } + return MW_TRUE; } static void @@ -108,16 +145,14 @@ mw_poll_sys_finalize(mw_object_t *super) { mw_poll_sys_t *self = (mw_poll_sys_t*)super; - - MW_SUPER_TYPE_BASE(super, MW_POLL_SYS_TYPE)->finalize(super); + mw_object_unref(self->array); + MW_SUPER_FINALIZE(super, MW_POLL_SYS_TYPE)(super); } static void mw_poll_sys_type_init(mw_poll_sys_type_t *self) { self->base.base.finalize = mw_poll_sys_finalize; - self->base.add_fd = mw_poll_sys_add_fd; - self->base.remove_fd = mw_poll_sys_remove_fd; self->base.poll = mw_poll_sys_poll; } diff --git a/milkway/mw-poll-win32.c b/milkway/mw-poll-win32.c index 3982eb0..730cd00 100644 --- a/milkway/mw-poll-win32.c +++ b/milkway/mw-poll-win32.c @@ -46,36 +46,10 @@ mw_poll_win32_new(void) } static mw_bool_t -mw_poll_win32_add_fd(mw_poll_t *super, - mw_pollfd_t *fd, - mw_error_t **reterr) -{ - mw_poll_win32_t *self = (mw_poll_win32_t*)super; - - if (!MW_SUPER_TYPE_MTH(super, MW_POLL_WIN32_TYPE, - mw_poll_type_t, add_fd) - (super, fd, reterr)) - return MW_FALSE; - return MW_TRUE; -} - -static mw_bool_t -mw_poll_win32_remove_fd(mw_poll_t *super, - mw_uintptr_t fd, - mw_error_t **reterr) -{ - mw_poll_win32_t *self = (mw_poll_win32_t*)super; - - if (!MW_SUPER_TYPE_MTH(super, MW_POLL_WIN32_TYPE, - mw_poll_type_t, remove_fd) - (super, fd, reterr)) - return MW_FALSE; - return MW_TRUE; -} - -static mw_bool_t -mw_poll_win32_poll(mw_poll_t *super, - int timeout) +mw_poll_win32_poll(mw_poll_t *super, + mw_pollfd_t *fds; + mw_uint_t nfds; + int timeout) { mw_poll_win32_t *self = (mw_poll_win32_t*)super; @@ -95,8 +69,6 @@ static void mw_poll_win32_type_init(mw_poll_win32_type_t *self) { self->base.base.finalize = mw_poll_win32_finalize; - self->base.add_fd = mw_poll_win32_add_fd; - self->base.remove_fd = mw_poll_win32_remove_fd; self->base.poll = mw_poll_win32_poll; } diff --git a/milkway/mw-poll.c b/milkway/mw-poll.c index dc8ad79..bba8dc7 100644 --- a/milkway/mw-poll.c +++ b/milkway/mw-poll.c @@ -26,66 +26,9 @@ mw_poll_init(mw_poll_t *self) { if (!mw_object_init(&self->base)) return NULL; - self->fds = mw_hash_new(mw_pointer_hash, mw_pointer_equal, NULL, NULL); - if (!self->fds) { - MW_SUPER_FINALIZE(self, MW_POLL_TYPE)(&self->base); - return NULL; - } return self; } -static mw_bool_t -mw_poll_default_add_fd(mw_poll_t *super, - mw_pollfd_t *fd, - mw_error_t **reterr) -{ - mw_poll_t *self = (mw_poll_t*)super; - - if (!mw_hash_insert(self->fds, (mw_pointer_t)fd->fd, NULL)) { - mw_error_set(reterr, "poll", MW_OUT_OF_MEM, - "failed to record the fd"); - return MW_FALSE; - } - return MW_TRUE; -} - -static mw_bool_t -mw_poll_default_remove_fd(mw_poll_t *super, - mw_uintptr_t fd, - mw_error_t **reterr) -{ - mw_poll_t *self = (mw_poll_t*)super; - - if (!mw_hash_remove(self->fds, (mw_pointer_t)fd)) { - mw_error_set(reterr, "poll", MW_OUT_OF_MEM, - "failed to remove the fd"); - return MW_FALSE; - } - return MW_TRUE; -} - -void -mw_poll_clear(mw_poll_t *self) -{ - mw_ptr_array_t *array; - mw_hash_iter_t iter, *it = &iter; - mw_uint_t i; - - if (!mw_hash_get_size(self->fds)) - return; - - array = mw_ptr_array_sized_new(mw_hash_get_size(self->fds)); - for (it = mw_hash_first(self->fds, it); it; - it = mw_hash_next(self->fds, it)) - mw_ptr_array_add(array, it->key); - - for (i = 0; i < array->len; i++) - mw_poll_remove_fd(self, - (mw_uintptr_t)mw_ptr_array_index(array, i), - NULL); - mw_object_unref(array); -} - static void mw_poll_finalize(mw_object_t *super) { @@ -99,8 +42,6 @@ static void mw_poll_type_init(mw_poll_type_t *self) { self->base.finalize = mw_poll_finalize; - self->add_fd = mw_poll_default_add_fd; - self->remove_fd = mw_poll_default_remove_fd; } MW_DEFINE_GET_TYPE(mw_poll, mw_poll_type_t, diff --git a/milkway/mw-poll.h b/milkway/mw-poll.h index 1c2e7b0..5d84269 100644 --- a/milkway/mw-poll.h +++ b/milkway/mw-poll.h @@ -34,18 +34,10 @@ struct mw_poll_type { mw_object_type_t base; mw_bool_t - (*add_fd) (mw_poll_t *self, - mw_pollfd_t *fd, - mw_error_t **reterr); - - mw_bool_t - (*remove_fd) (mw_poll_t *self, - mw_uintptr_t fd, - mw_error_t **reterr); - - mw_bool_t - (*poll) (mw_poll_t *self, - int timeout_); + (*poll) (mw_poll_t *self, + mw_pollfd_t *fds, + mw_uint_t nfds, + int timeout_); }; struct mw_poll { @@ -65,7 +57,7 @@ typedef enum } mw_poll_event_t; struct mw_pollfd { - mw_uintptr_t fd; + mw_intptr_t fd; unsigned short events; unsigned short revents; @@ -78,35 +70,14 @@ mw_public mw_poll_t* mw_poll_init(mw_poll_t *self); static mw_inline mw_bool_t -mw_poll_add_fd(mw_poll_t *self, - mw_pollfd_t *fd, - mw_error_t **reterr) +mw_poll_poll(mw_poll_t *self, + mw_pollfd_t *fds, + mw_uint_t nfds, + int timeout_) { mw_poll_type_t *type = (mw_poll_type_t *)MW_TYPE(self); - return type->add_fd(self, fd, reterr); + return type->poll(self, fds, nfds, timeout_); } -static mw_inline mw_bool_t -mw_poll_remove_fd(mw_poll_t *self, - mw_uintptr_t fd, - mw_error_t **reterr) -{ - mw_poll_type_t *type = (mw_poll_type_t *)MW_TYPE(self); - - return type->remove_fd(self, fd, reterr); -} - -static mw_inline mw_bool_t -mw_poll_poll(mw_poll_t *self, - int timeout_) -{ - mw_poll_type_t *type = (mw_poll_type_t *)MW_TYPE(self); - - return type->poll(self, timeout_); -} - -mw_public void -mw_poll_clear(mw_poll_t *self); - #endif |