summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuo Jinghua <sunmoon1997@gmail.com>2009-10-31 18:10:41 +0800
committerLuo Jinghua <sunmoon1997@gmail.com>2009-10-31 18:10:41 +0800
commit36d3e546e459efe2694e8f382e884e721d94c794 (patch)
treee6fba6df164a17abd065093c35d0b5d3d85dcd40
parent2d981726ee0bf836418390132aec30ff83e15829 (diff)
milkway: simpiled poll interface and implement them
-rw-r--r--milkway/mw-poll-select.c74
-rw-r--r--milkway/mw-poll-sys-private.h3
-rw-r--r--milkway/mw-poll-sys.c93
-rw-r--r--milkway/mw-poll-win32.c36
-rw-r--r--milkway/mw-poll.c59
-rw-r--r--milkway/mw-poll.h49
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