static inline coro_t _sche_next(sche_t s,coro_t co) { coro_t next = NULL; coro_t coro_goback = co->_goback; if(NULL == coro_goback) { next = LINK_LIST_POP(coro_t,s->active_list_1); if(!next) next = LINK_LIST_POP(coro_t,s->active_list_2); if(!next) next = s->co; } else { next = coro_goback; co->_goback = NULL; } if(co->status == CORO_YIELD) { co->status = CORO_ACTIVE; LINK_LIST_PUSH_BACK(s->active_list_2,co); } assert(co != next); set_current_coro(next); return (coro_t)uthread_switch(co->ut,next->ut,co); }
static inline void on_write_finish(log_t l,int32_t bytestransfer) { wpacket_t w; uint32_t size; while(bytestransfer) { w = LINK_LIST_POP(wpacket_t,l->pending_log); assert(w); if((uint32_t)bytestransfer >= w->data_size) { //一个wpacket写完了 bytestransfer -= w->data_size; ++log_count; wpacket_destroy(&w); } else { while(bytestransfer) { size = w->buf->size - w->begin_pos; size = size > (uint32_t)bytestransfer ? (uint32_t)bytestransfer:size; bytestransfer -= size; w->begin_pos += size; w->data_size -= size; if(w->begin_pos >= w->buf->size) { w->begin_pos = 0; w->buf = buffer_acquire(w->buf,w->buf->next); } } LINK_LIST_PUSH_FRONT(l->pending_log,w); } } }
static void destroy_log(log_t *l) { mutex_lock((*l)->mtx); while(!link_list_is_empty((*l)->log_queue)) { wpacket_t w = LINK_LIST_POP(wpacket_t,(*l)->log_queue); wpacket_destroy(&w); } mutex_unlock((*l)->mtx); close((*l)->file_descriptor); mutex_destroy(&(*l)->mtx); destroy_link_list(&(*l)->log_queue); destroy_link_list(&(*l)->pending_log); free(*l); *l = 0; }
int connection_destroy(struct connection** c) { if(!(*c)->recv_overlap.isUsed && !(*c)->send_overlap.isUsed) { wpacket_t w; while(w = LINK_LIST_POP(wpacket_t,(*c)->send_list)) wpacket_destroy(&w); LINK_LIST_DESTROY(&(*c)->send_list); buffer_release(&(*c)->unpack_buf); buffer_release(&(*c)->next_recv_buf); free(*c); *c = 0; return 0; } return -1; }
int32_t epoll_loop(engine_t n,int32_t timeout) { assert(n); uint32_t ms; uint32_t tick = GetSystemMs(); uint32_t _timeout = tick + timeout; do{ while(!LINK_LIST_IS_EMPTY(n->actived)) { socket_t s = LINK_LIST_POP(socket_t,n->actived); s->isactived = 0; if(Process(s) && s->isactived == 0) { s->isactived = 1; LINK_LIST_PUSH_BACK(n->actived,s); } } ms = _timeout - tick; int32_t nfds = TEMP_FAILURE_RETRY(epoll_wait(n->poller_fd,n->events,MAX_SOCKET,ms)); if(nfds < 0) return -1; int32_t i; for(i = 0 ; i < nfds ; ++i) { socket_t sock = (socket_t)n->events[i].data.ptr; if(sock) { //套接口可读 if(n->events[i].events & EPOLLIN) { on_read_active(sock); } //套接口可写 if(n->events[i].events & EPOLLOUT) on_write_active(sock); if(n->events[i].events & EPOLLERR) { //套接口异常 } } } tick = GetSystemMs(); }while(tick < _timeout); return 0; }
int connection_destroy(struct connection** c) { if(!(*c)->recv_overlap.isUsed && !(*c)->send_overlap.isUsed) { wpacket_t w; while((w = LINK_LIST_POP(wpacket_t,(*c)->send_list))!=NULL) wpacket_destroy(&w); LINK_LIST_DESTROY(&(*c)->send_list); buffer_release(&(*c)->unpack_buf); buffer_release(&(*c)->next_recv_buf); if((*c)->wheelitem) DestroyWheelItem(&((*c)->wheelitem)); free(*c); *c = NULL; printf("connection_destroy\n"); return 0; } return -1; }
void close_log_system() { COMPARE_AND_SWAP(&(g_log_system->is_close),0,1); //停止写日志线程,并等待结束 //g_log_system->is_close = 1; thread_join(g_log_system->worker_thread); mutex_lock(g_log_system->mtx); while(!link_list_is_empty(g_log_system->log_files)) { log_t l = LINK_LIST_POP(log_t,g_log_system->log_files); destroy_log(&l); } mutex_unlock(g_log_system->mtx); mutex_destroy(&g_log_system->mtx); destroy_link_list(&g_log_system->log_files); destroy_thread(&g_log_system->worker_thread); //DESTROY(&(g_log_system->_wpacket_allocator)); free(g_log_system); g_log_system = 0; }
/* * next选择方案,如果有goback优先选择goback作为下一个被运行的coro, * 否则取active_list_1首元素作为下一个被运行的coro,如果active_list_1 * 为空则直接返回. */ coro_t _sche_next_1(sche_t s,coro_t co) { coro_t next = NULL; coro_t coro_goback = co->_goback; if(NULL == coro_goback) { coro_t next = LINK_LIST_POP(coro_t,s->active_list_1); if(!next) return NULL; } else { next = coro_goback; co->_goback = NULL; } LINK_LIST_PUSH_BACK(s->active_list_2,co); assert(co != next); set_current_coro(next); return (coro_t)uthread_switch(co->ut,next->ut,co); }
static inline void update_send_list(struct connection *c,int32_t bytestransfer) { wpacket_t w; uint32_t size; while(bytestransfer) { w = LINK_LIST_POP(wpacket_t,c->send_list); assert(w); if((uint32_t)bytestransfer >= w->data_size) { //一个包发完 bytestransfer -= w->data_size; if(w->_packet_send_finish) w->_packet_send_finish(c,w); else wpacket_destroy(&w); ++packet_send; } else { while(bytestransfer) { size = w->buf->size - w->begin_pos; size = size > (uint32_t)bytestransfer ? (uint32_t)bytestransfer:size; bytestransfer -= size; w->begin_pos += size; w->data_size -= size; if(w->begin_pos >= w->buf->size) { w->begin_pos = 0; w->buf = buffer_acquire(w->buf,w->buf->next); } } LINK_LIST_PUSH_FRONT(c->send_list,w); } } }