void run_init(int argc, char **argv) { L = luaL_newstate(); luaL_openlibs (L); setup_modules (L); luanative_start (L); internet_start (L); #ifdef _WIN32 winapigpu_init (L); #endif fb_start (L); termutils_start (L); event_prepare(); int status = luaL_loadbuffer(L, lua_init, strlen(lua_init), "=INIT"); if (status) { fprintf(stderr, "Couldn't load init: %s\n", lua_tostring(L, -1)); exit(1); } for(int i = 0; i < argc; i++) { lua_pushstring(L, argv[i]); } lua_call(L, argc, 0); lua_close(L); }
int event_process(EVENT *ev, int timeout) { int ret; if (ev->timeout < 0) { if (timeout < 0) { timeout = 100; } } else if (timeout < 0) { timeout = ev->timeout; } else if (timeout > ev->timeout) { timeout = ev->timeout; } /* limit the event wait time just for fiber schedule exiting * quickly when no tasks left */ if (timeout > 1000 || timeout <= 0) { timeout = 100; } event_prepare(ev); ret = ev->event_wait(ev, timeout); #ifdef HAS_POLL event_process_poll(ev); #endif #ifdef HAS_EPOLL event_process_epoll(ev); #endif return ret; }
static void event_loop(ACL_EVENT *eventp) { const char *myname = "event_loop"; EVENT_SELECT *ev = (EVENT_SELECT *) eventp; ACL_EVENT_NOTIFY_TIME timer_fn; void *timer_arg; ACL_SOCKET sockfd; ACL_EVENT_TIMER *timer; int nready, i; acl_int64 delay; ACL_EVENT_FDTABLE *fdp; struct timeval tv, *tvp; fd_set rmask; /* enabled read events */ fd_set wmask; /* enabled write events */ fd_set xmask; /* for bad news mostly */ delay = eventp->delay_sec * 1000000 + eventp->delay_usec; /* 调整事件引擎的时间截 */ SET_TIME(eventp->present); /* 根据定时器任务的最近任务计算 select 的检测超时上限 */ if ((timer = ACL_FIRST_TIMER(&eventp->timer_head)) != 0) { acl_int64 n = timer->when - eventp->present; if (n <= 0) delay = 0; else if (n < delay) delay = n; } /* 调用 event_prepare 检查有多少个描述字需要通过 select 进行检测 */ if (event_prepare(eventp) == 0) { if (eventp->ready_cnt == 0) { delay /= 1000000; if (delay <= 0) delay = 1; /* 为避免循环过快,休眠一下 */ sleep((int) delay); } goto TAG_DONE; } if (eventp->ready_cnt > 0) { tv.tv_sec = 0; tv.tv_usec = 0; tvp = &tv; } else if (delay >= 0) { #if defined(ACL_WINDOWS) tv.tv_sec = (long) delay / 1000000; tv.tv_usec = (unsigned long) (delay - tv.tv_sec * 1000000); #else tv.tv_sec = (time_t) delay / 1000000; tv.tv_usec = (suseconds_t) (delay - tv.tv_sec * 1000000); #endif tvp = &tv; } else tvp = NULL; rmask = ev->rmask; wmask = ev->wmask; xmask = ev->xmask; /* 调用 select 系统调用检测可用描述字 */ #ifdef ACL_WINDOWS nready = select(0, &rmask, &wmask, &xmask, tvp); #else nready = select(eventp->maxfd + 1, &rmask, &wmask, &xmask, tvp); #endif if (eventp->nested++ > 0) acl_msg_fatal("%s(%d): recursive call(%d)", myname, __LINE__, eventp->nested); if (nready < 0) { if (acl_last_error() != ACL_EINTR) { acl_msg_fatal("%s(%d), %s: select: %s", __FILE__, __LINE__, myname, acl_last_serror()); } goto TAG_DONE; } else if (nready == 0) goto TAG_DONE; /* 检查 select 的检测结果集合 */ /* if some fdp was cleared from eventp->fdtabs in timer callback, * which has no effection on the rest fdp in eventp->fdtabs */ for (i = 0; i < eventp->fdcnt; i++) { fdp = eventp->fdtabs[i]; /* 如果该描述字对象已经在被设置为异常或超时状态则继续 */ if ((fdp->event_type & (ACL_EVENT_XCPT | ACL_EVENT_RW_TIMEOUT))) continue; sockfd = ACL_VSTREAM_SOCK(fdp->stream); /* 检查描述字是否出现异常 */ if (FD_ISSET(sockfd, &xmask)) { fdp->event_type |= ACL_EVENT_XCPT; fdp->fdidx_ready = eventp->ready_cnt; eventp->ready[eventp->ready_cnt++] = fdp; continue; } /* 检查描述字是否可读 */ if (FD_ISSET(sockfd, &rmask)) { /* 给该描述字对象附加可读属性 */ if ((fdp->event_type & (ACL_EVENT_READ | ACL_EVENT_WRITE)) == 0) { fdp->event_type |= ACL_EVENT_READ; fdp->fdidx_ready = eventp->ready_cnt; eventp->ready[eventp->ready_cnt++] = fdp; } if (fdp->listener) fdp->event_type |= ACL_EVENT_ACCEPT; /* 该描述字可读则设置 ACL_VSTREAM 的系统可读标志从而 * 触发 ACL_VSTREAM 流在读时调用系统的 read 函数 */ else fdp->stream->read_ready = 1; } /* 检查描述字是否可写 */ if (FD_ISSET(sockfd, &wmask)) { /* 给该描述字对象附加可写属性 */ if ((fdp->event_type & (ACL_EVENT_READ | ACL_EVENT_WRITE)) == 0) { fdp->event_type |= ACL_EVENT_WRITE; fdp->fdidx_ready = eventp->ready_cnt; eventp->ready[eventp->ready_cnt++] = fdp; } } } TAG_DONE: /* 调整事件引擎的时间截 */ SET_TIME(eventp->present); /* 优先处理定时器中的任务 */ while ((timer = ACL_FIRST_TIMER(&eventp->timer_head)) != 0) { if (timer->when > eventp->present) break; timer_fn = timer->callback; timer_arg = timer->context; /* 如果定时器的时间间隔 > 0 且允许定时器被循环调用, * 则再重设定时器 */ if (timer->delay > 0 && timer->keep) { timer->ncount++; eventp->timer_request(eventp, timer->callback, timer->context, timer->delay, timer->keep); } else { acl_ring_detach(&timer->ring); /* first this */ timer->nrefer--; if (timer->nrefer != 0) acl_msg_fatal("%s(%d): nrefer(%d) != 0", myname, __LINE__, timer->nrefer); acl_myfree(timer); } timer_fn(ACL_EVENT_TIME, eventp, timer_arg); } /* 处理准备好的描述字事件 */ if (eventp->ready_cnt > 0) event_fire(eventp); eventp->nested--; }
static void event_loop(ACL_EVENT *eventp) { const char *myname = "event_loop"; EVENT_POLL *ev = (EVENT_POLL *) eventp; ACL_EVENT_TIMER *timer; int nready, i, revents; acl_int64 delay; ACL_EVENT_FDTABLE *fdp; delay = eventp->delay_sec * 1000000 + eventp->delay_usec; if (delay < DELAY_MIN) delay = DELAY_MIN; /* 调整事件引擎的时间截 */ SET_TIME(eventp->present); /* 根据定时器任务的最近任务计算 poll 的检测超时上限 */ if ((timer = ACL_FIRST_TIMER(&eventp->timer_head)) != 0) { acl_int64 n = timer->when - eventp->present; if (n <= 0) delay = 0; else if (n < delay) delay = n; } /* 调用 event_prepare 检查有多少个描述字需要通过 poll 进行检测 */ if (event_prepare(eventp) == 0) { /* 说明无须 poll 检测 */ if (eventp->ready_cnt == 0) /* 为避免循环过快,休眠一下 */ acl_doze(delay > DELAY_MIN ? (int) delay / 1000 : 1); goto TAG_DONE; } /* 如果已经有描述字准备好则 poll 检测超时时间置 0 */ if (eventp->ready_cnt > 0) delay = 0; /* 调用 poll 系统调用检测可用描述字 */ nready = poll(ev->fds, eventp->fdcnt, (int) (delay / 1000)); if (eventp->nested++ > 0) { acl_msg_error("%s(%d): recursive call", myname, __LINE__); exit (1); } if (nready < 0) { if (acl_last_error() != ACL_EINTR) { acl_msg_error("%s(%d), %s: select: %s", __FILE__, __LINE__, myname, acl_last_serror()); exit (1); } goto TAG_DONE; } else if (nready == 0) goto TAG_DONE; /* 检查 poll 的检测结果集合 */ for (i = 0; i < eventp->fdcnt; i++) { fdp = acl_fdmap_ctx(ev->fdmap, ev->fds[i].fd); if (fdp == NULL || fdp->stream == NULL) continue; /* 如果该描述字对象已经在被设置为异常或超时状态则继续 */ if ((fdp->event_type & (ACL_EVENT_XCPT | ACL_EVENT_RW_TIMEOUT))) continue; revents = ev->fds[i].revents; /* 检查描述字是否出现异常 */ if ((revents & (POLLHUP | POLLERR)) != 0) { fdp->event_type |= ACL_EVENT_XCPT; fdp->fdidx_ready = eventp->ready_cnt; eventp->ready[eventp->ready_cnt++] = fdp; continue; } /* 检查描述字是否可读 */ if ((fdp->flag & EVENT_FDTABLE_FLAG_READ) && (revents & POLLIN) ) { /* 给该描述字对象附加可读属性 */ if ((fdp->event_type & (ACL_EVENT_READ | ACL_EVENT_WRITE)) == 0) { fdp->event_type |= ACL_EVENT_READ; fdp->fdidx_ready = eventp->ready_cnt; eventp->ready[eventp->ready_cnt++] = fdp; } if (fdp->listener) fdp->event_type |= ACL_EVENT_ACCEPT; /* 该描述字可读则设置 ACL_VSTREAM 的系统可读标志从而 * 触发 ACL_VSTREAM 流在读时调用系统的 read 函数 */ else fdp->stream->read_ready = 1; } /* 检查描述字是否可写 */ if ((fdp->flag & EVENT_FDTABLE_FLAG_WRITE) && (revents & POLLOUT)) { /* 给该描述字对象附加可写属性 */ if ((fdp->event_type & (ACL_EVENT_READ | ACL_EVENT_WRITE)) == 0) { fdp->event_type |= ACL_EVENT_WRITE; fdp->fdidx_ready = eventp->ready_cnt; eventp->ready[eventp->ready_cnt++] = fdp; } } } TAG_DONE: event_timer_trigger(eventp); /* 处理准备好的描述字事件 */ if (eventp->ready_cnt > 0) event_fire(eventp); eventp->nested--; }