fiber: EVENT's members poll_list & epoll_list can use FIFO or STACK, other than RING

This commit is contained in:
zhengshuxin 2017-10-20 10:19:34 +08:00
parent 70f510b33f
commit 4235dcd1d9
4 changed files with 135 additions and 11 deletions

View File

@ -32,8 +32,17 @@ EVENT *event_create(int size)
ev->maxfd = -1;
ev->r_ndefer = 0;
ev->w_ndefer = 0;
#ifdef USE_RING
acl_ring_init(&ev->poll_list);
acl_ring_init(&ev->epoll_list);
#elif defined(USE_STACK)
ev->poll_list = acl_stack_create(100);
ev->epoll_list = acl_stack_create(100);
#else
ev->poll_list = acl_fifo_new();
ev->epoll_list = acl_fifo_new();
#endif
/* Events with mask == AE_NONE are not set. So let's initialize the
* vector with it.
@ -71,6 +80,14 @@ void event_free(EVENT *ev)
DEFER_DELETE *r_defers = ev->r_defers;
DEFER_DELETE *w_defers = ev->w_defers;
#if defined(USE_STACK)
acl_stack_destroy(ev->poll_list, NULL);
acl_stack_destroy(ev->epoll_list, NULL);
#elif !defined(USE_RING)
acl_fifo_free(ev->poll_list, NULL);
acl_fifo_free(ev->epoll_list, NULL);
#endif
ev->free(ev);
acl_myfree(events);
@ -278,7 +295,7 @@ static void __event_del(EVENT *ev, int fd, int mask)
fe = &ev->events[fd];
if (fe->mask == EVENT_NONE) {
if (fe->mask == EVENT_NONE || mask == EVENT_ERROR) {
fe->mask_fired = EVENT_NONE;
fe->r_defer = NULL;
fe->w_defer = NULL;
@ -428,7 +445,6 @@ int event_process(EVENT *ev, int timeout)
int processed = 0, numevents, j;
int mask, fd, rfired;
FILE_EVENT *fe;
ACL_RING *head;
#ifdef DEL_DELAY
int ndefer;
#endif
@ -495,20 +511,68 @@ int event_process(EVENT *ev, int timeout)
processed++;
}
#ifdef USE_RING
#define TO_APPL acl_ring_to_appl
while ((head = acl_ring_pop_head(&ev->poll_list))) {
POLL_EVENT *pe = TO_APPL(head, POLL_EVENT, me);
while (1) {
POLL_EVENT *pe;
ACL_RING *head = acl_ring_pop_head(&ev->poll_list);
if (head == NULL)
break;
pe = TO_APPL(head, POLL_EVENT, me);
pe->proc(ev, pe);
processed++;
}
while ((head = acl_ring_pop_head(&ev->epoll_list))) {
EPOLL_EVENT *ee = TO_APPL(head, EPOLL_EVENT, me);
while (1) {
EPOLL_EVENT *ee;
ACL_RING *head = acl_ring_pop_head(&ev->epoll_list);
if (head == NULL)
break;
ee = TO_APPL(head, EPOLL_EVENT, me);
ee->proc(ev, ee);
processed++;
}
#elif defined(USE_STACK)
while (1) {
POLL_EVENT *pe = acl_stack_pop(ev->poll_list);
if (pe == NULL)
break;
pe->proc(ev, pe);
processed++;
}
while (1) {
EPOLL_EVENT *ee = acl_stack_pop(ev->epoll_list);
if (ee == NULL)
break;
ee->proc(ev, ee);
processed++;
}
#else
while (1) {
POLL_EVENT *pe = acl_fifo_pop(ev->poll_list);
if (pe == NULL)
break;
pe->proc(ev, pe);
processed++;
}
while (1) {
EPOLL_EVENT *ee = acl_fifo_pop(ev->epoll_list);
if (ee == NULL)
break;
ee->proc(ev, ee);
processed++;
}
#endif
/* return the number of processed file/time events */
return processed;

View File

@ -91,9 +91,17 @@ struct EVENT {
FIRED_EVENT *fired;
DEFER_DELETE *r_defers;
DEFER_DELETE *w_defers;
ACL_RING poll_list;
ACL_RING epoll_list;
// ACL_RING_ITER iter;
#ifdef USE_RING // xxx: some bugs ?
ACL_RING poll_list;
ACL_RING epoll_list;
#elif defined(USE_STACK)
ACL_STACK *poll_list;
ACL_STACK *epoll_list;
#else
ACL_FIFO *poll_list;
ACL_FIFO *epoll_list;
#endif
const char *(*name)(void);
int (*handle)(EVENT *);

View File

@ -419,11 +419,24 @@ static void poll_events_del(EVENT *ev, POLL_EVENT *pe)
void poll_fibers_free(void)
{
ACL_RING *head;
EVENT *ev = fiber_io_event();
#ifdef USE_RING
ACL_RING *head;
while ((head = acl_ring_pop_head(&ev->poll_list))) {
POLL_EVENT *pe = TO_APPL(head, POLL_EVENT, me);
#elif defined(USE_STACK)
while (1) {
POLL_EVENT *pe = acl_stack_pop(ev->poll_list);
if (pe == NULL)
break;
#else
while (1) {
POLL_EVENT *pe = acl_fifo_pop(ev->poll_list);
if (pe == NULL)
break;
#endif
poll_events_del(ev, pe);
fiber_free(pe->fiber);
}
@ -450,7 +463,10 @@ static void pollfd_callback(EVENT *ev, int fd, void *ctx, int mask)
n |= 1 << 1;
}
#ifdef USE_RING
assert(acl_ring_size(&ev->poll_list) > 0);
#endif
if (n > 0) {
acl_assert(pe);
pe->nready++;
@ -461,7 +477,14 @@ static void event_poll_set(EVENT *ev, POLL_EVENT *pe, int timeout)
{
int i;
#ifdef USE_RING
acl_ring_prepend(&ev->poll_list, &pe->me);
#elif defined(USE_STACK)
acl_stack_append(ev->poll_list, pe);
#else
acl_fifo_push_back(ev->poll_list, pe);
#endif
pe->nready = 0;
for (i = 0; i < pe->nfds; i++) {
@ -551,7 +574,13 @@ int poll(struct pollfd *fds, nfds_t nfds, int timeout)
break;
}
#ifdef USE_RING
if (acl_ring_size(&ev->poll_list) == 0)
#elif defined(USE_STACK)
if (acl_stack_size(ev->poll_list) == 0)
#else
if (acl_fifo_size(ev->poll_list) == 0)
#endif
ev->timeout = -1;
if (pe.nready != 0 || timeout == 0)
@ -660,11 +689,24 @@ static void epoll_events_del(EVENT *ev, EPOLL_EVENT *ee)
void epoll_fibers_free(void)
{
ACL_RING *head;
EVENT *ev = fiber_io_event();
#ifdef USE_RING
ACL_RING *head;
while ((head = acl_ring_pop_head(&ev->epoll_list))) {
EPOLL_EVENT *ee = TO_APPL(head, EPOLL_EVENT, me);
#elif defined(USE_STACK)
while (1) {
EPOLL_EVENT *ee = acl_stack_pop(ev->epoll_list);
if (ee == NULL)
break;
#else
while (1) {
EPOLL_EVENT *ee = acl_fifo_pop(ev->epoll_list);
if (ee == NULL)
break;
#endif
epoll_events_del(ev, ee);
fiber_free(ee->fiber);
}
@ -984,7 +1026,14 @@ static void epoll_callback(EVENT *ev acl_unused, EPOLL_EVENT *ee)
static void event_epoll_set(EVENT *ev, EPOLL_EVENT *ee, int timeout)
{
#ifdef USE_RING
acl_ring_prepend(&ev->epoll_list, &ee->me);
#elif defined(USE_STACK)
acl_stack_append(ev->epoll_list, ee);
#else
acl_fifo_push_back(ev->epoll_list, ee);
#endif
ee->nready = 0;
if (timeout >= 0 && (ev->timeout < 0 || timeout < ev->timeout))

View File

@ -1,4 +1,7 @@
70) 2017.10.20
70.1) feature: EVENT::poll_list, epoll_list 可以采用 FIFO 或 STACK
69) 2017.10.17
69.1) feature: 增加 acl_fiber_sys_errno/acl_fiber_sys_errno_set/
acl::fiber::get_sys_errno/acl::fiber_set_sys_errno API 可用于获得/设置当前线程