spx_private void ReciveRequest(EV_P_ ev_async *watcher, int revents){/*{{{*/ ev_async_stop(loop, watcher); struct server_context * ctx = (struct server_context *) watcher->data; if(NULL == ctx){ SpxLog1(g_log, SpxLogError, "ReciveRequest ctx is NULL"); return; } if(READ_HEADER == ctx->life_cycle){ char buf[LOG_HEADER_SIZE] = {0}; size_t len = 0; err_t err = ReciveRequest_GetRequest_ReadRequest(ctx->fd, buf, &len, LOG_HEADER_SIZE); if(0 == err){ log_header_unpack(buf, ctx->header); char * request = (char *) calloc(1, sizeof(char)*ctx->header->req_size); if(NULL == request){ SpxLog2(g_log, SpxLogError, err,"calloc log_header failed"); return; } ctx->req_size = ctx->header->req_size; ctx->request = request; ctx->life_cycle = READ_REQUEST; } else{ if(EAGAIN == err || EWOULDBLOCK == err || EINTR == err) { ev_once(loop, ctx->fd, EV_READ, ctx->timeout, ReciveRequest_GetRequest, ctx); return; } else{ SpxLog2(g_log, SpxLogError, err,"Read header failed"); CloseCTX(ctx); return; } } } if(READ_REQUEST == ctx->life_cycle){ printf("---------------ReadRequest-------------\n"); printf("req_size:%d\n", (int)ctx->req_size); err_t err = ReciveRequest_GetRequest_ReadRequest(ctx->fd, ctx->request, &ctx->req_len, ctx->req_size); printf("read request complete\n" ); if(0 == err){ ctx->life_cycle = PARSE_REQUEST; RegisterAayncWatcher(&ctx->async_watcher, ParserRequest, ctx); ev_async_start(loop, &ctx->async_watcher); ev_async_send(loop, &ctx->async_watcher); return; }else{ if(EAGAIN == err || EWOULDBLOCK == err || EINTR == err) { ev_once(loop, ctx->fd, EV_READ, ctx->timeout, ReciveRequest_GetRequest, ctx); return; }else{ SpxLog2(g_log, SpxLogError, err,"ReciveRequest_GetRequest_ReadRequest Failed"); CloseCTX(ctx); return; } } } }/*}}}*/
spx_private void Sender_ReWriteResponse(int revents, void *arg){/*{{{*/ struct server_context *ctx = (struct server_context *) arg; if(NULL == ctx){ SpxLog1(g_log, SpxLogError, "Sender ctx is NULL"); return; } if(EV_ERROR & revents){ SpxLog1(g_log, SpxLogError, "EV_ERROR"); return; } if(EV_TIMEOUT & revents){ if((ctx->resp_retry++) >= RETRY_TIMES){ RequestException(ctx, bad_request); SpxLog1(g_log, SpxLogError, "EV_TIMEOUT"); return; }else{ ev_once(main_socket_loop, ctx->fd, EV_WRITE, ctx->timeout, Sender_ReWriteResponse, ctx); return; } } if(EV_WRITE & revents){ err_t err = Sender_WriteResponse(ctx->fd, ctx->response, &ctx->resp_len, &ctx->split_size); if((0 == err)&&(0 == ctx->split_size)){ if(ctx->resp_size == ctx->resp_len){ RequestFinish(ctx); }else{ int remain_size = ctx->resp_size - ctx->resp_len; if(remain_size >= SPLIT_SIZE){ ctx->split_size = SPLIT_SIZE; }else{ ctx->split_size = remain_size; } RegisterAayncWatcher(&ctx->async_watcher, Sender, ctx); ev_async_start(main_socket_loop, &ctx->async_watcher); ev_async_send(main_socket_loop, &ctx->async_watcher); return; } }else{ if((EAGAIN == err || EWOULDBLOCK == err || EINTR == err)||(ctx->resp_size > 0)) { ev_once(main_socket_loop, ctx->fd, EV_READ, ctx->timeout, Sender_ReWriteResponse, ctx); return; }else{ SpxLog2(g_log, SpxLogError, err,"Sender Failed"); RequestException(ctx, bad_request); } } } }/*}}}*/
spx_private void Sender(EV_P_ ev_async *watcher, int revents){/*{{{*/ ev_async_stop(loop, watcher); struct server_context * ctx = (struct server_context *) watcher->data; if(NULL == ctx){ SpxLog1(g_log, SpxLogError, "Sender ctx is NULL"); return; } err_t err = Sender_WriteResponse(ctx->fd, ctx->response, &ctx->resp_len, &ctx->split_size); if((0 == err)&&(0 == ctx->split_size)){ if(ctx->resp_size == ctx->resp_len){ RequestFinish(ctx); }else{ int remain_size = ctx->resp_size - ctx->resp_len; if(remain_size >= SPLIT_SIZE){ ctx->split_size = SPLIT_SIZE; }else{ ctx->split_size = remain_size; } RegisterAayncWatcher(&ctx->async_watcher, Sender, ctx); ev_async_start(loop, &ctx->async_watcher); ev_async_send(loop, &ctx->async_watcher); return; } }else{ if((EAGAIN == err || EWOULDBLOCK == err || EINTR == err)||(ctx->resp_size > 0)) { ev_once(main_socket_loop, ctx->fd, EV_READ, ctx->timeout, Sender_ReWriteResponse, ctx); return; }else{ SpxLog2(g_log, SpxLogError, err,"Sender Failed"); RequestException(ctx, bad_request); } } }/*}}}*/
spx_private void ReciveRequest(EV_P_ ev_async *watcher, int revents){/*{{{*/ ev_async_stop(loop, watcher); struct server_context * ctx = (struct server_context *) watcher->data; if(NULL == ctx){ SpxLog1(g_log, SpxLogError, "ReciveRequest ctx is NULL"); return; } err_t err = ReciveRequest_GetRequest_ReadRequest(ctx->fd, ctx->request, &ctx->req_len); if(0 == err){ RegisterAayncWatcher(&ctx->async_watcher, ParserRequest, ctx); ev_async_start(loop, &ctx->async_watcher); ev_async_send(loop, &ctx->async_watcher); printf("buf:%s\n",ctx->request); return; }else{ if(EAGAIN == err || EWOULDBLOCK == err || EINTR == err) { ev_once(loop, ctx->fd, EV_READ, ctx->timeout, ReciveRequest_GetRequest, ctx); return; }else{ SpxLog2(g_log, SpxLogError, err,"ReciveRequest_GetRequest_ReadRequest Failed"); if( -1 == err) CloseCTX(ctx); else RequestException(ctx, bad_request); return; } } }/*}}}*/
spx_private void ReciveRequest_GetRequest(int revents, void *arg){/*{{{*/ struct server_context *ctx = (struct server_context *) arg; if(NULL == ctx){ SpxLog1(g_log, SpxLogError, "ReciveRequest_GetRequest ctx is NULL"); return; } if(EV_ERROR & revents){ SpxLog1(g_log, SpxLogError, "EV_ERROR"); return; } if(EV_TIMEOUT & revents){ if((ctx->req_retry++) >= RETRY_TIMES){ RequestException(ctx, bad_request); SpxLog1(g_log, SpxLogError, "EV_TIMEOUT"); return; }else{ ev_once(main_socket_loop, ctx->fd, EV_READ, ctx->timeout, ReciveRequest_GetRequest, ctx); return; } } if(EV_READ & revents){ err_t err = ReciveRequest_GetRequest_ReadRequest(ctx->fd, ctx->request, &ctx->req_len); if(0 == err){ RegisterAayncWatcher(&ctx->async_watcher, ParserRequest, ctx); ev_async_start(main_socket_loop, &ctx->async_watcher); ev_async_send(main_socket_loop, &ctx->async_watcher); }else{ if((EAGAIN == err || EWOULDBLOCK == err || EINTR == err)) { ev_once(main_socket_loop, ctx->fd, EV_READ, ctx->timeout, ReciveRequest_GetRequest, ctx); return; }else{ SpxLog2(g_log, SpxLogError, err,"ReciveRequest_GetRequest_ReadRequest Failed"); if( -1 == err) CloseCTX(ctx); else RequestException(ctx, bad_request); return; } } } }/*}}}*/
int event_base_loopexit (struct event_base *base, struct timeval *tv) { ev_tstamp after = ev_tv_get (tv); dLOOPbase; ev_once (EV_A_ -1, 0, after >= 0. ? after : 0., ev_x_loopexit_cb, (void *)base); return 0; }
int buffered_socket_connect(struct BufferedSocket *buffsock) { struct addrinfo ai, *aitop; char strport[32]; struct sockaddr *sa; int slen; long flags; if ((buffsock->state == BS_CONNECTED) || (buffsock->state == BS_CONNECTING)) { return 0; } memset(&ai, 0, sizeof(struct addrinfo)); ai.ai_family = AF_INET; ai.ai_socktype = SOCK_STREAM; snprintf(strport, sizeof(strport), "%d", buffsock->port); if (getaddrinfo(buffsock->address, strport, &ai, &aitop) != 0) { _DEBUG("%s: getaddrinfo() failed\n", __FUNCTION__); return 0; } sa = aitop->ai_addr; slen = aitop->ai_addrlen; if ((buffsock->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { _DEBUG("%s: socket() failed\n", __FUNCTION__); return 0; } // set non-blocking if ((flags = fcntl(buffsock->fd, F_GETFL, NULL)) < 0) { close(buffsock->fd); _DEBUG("%s: fcntl(%d, F_GETFL) failed\n", __FUNCTION__, buffsock->fd); return 0; } if (fcntl(buffsock->fd, F_SETFL, flags | O_NONBLOCK) == -1) { close(buffsock->fd); _DEBUG("%s: fcntl(%d, F_SETFL) failed\n", __FUNCTION__, buffsock->fd); return 0; } if (connect(buffsock->fd, sa, slen) == -1) { if (errno != EINPROGRESS) { close(buffsock->fd); _DEBUG("%s: connect() failed\n", __FUNCTION__); return 0; } } freeaddrinfo(aitop); ev_once(buffsock->loop, buffsock->fd, EV_WRITE, 2.0, buffered_socket_connect_cb, buffsock); buffsock->state = BS_CONNECTING; return buffsock->fd; }
int event_base_once (struct event_base *base, int fd, short events, void (*cb)(int, short, void *), void *arg, struct timeval *tv) { struct ev_x_once *once = (struct ev_x_once *)malloc (sizeof (struct ev_x_once)); dLOOPbase; if (!once) return -1; once->fd = fd; once->cb = cb; once->arg = arg; ev_once (EV_A_ fd, events & (EV_READ | EV_WRITE), ev_tv_get (tv), ev_x_once_cb, (void *)once); return 0; }
static void closing_socket_cb(int revents, void* arg) { static char trash[1024]; closing_socket *cs = (closing_socket*) arg; ssize_t r; liEventLoop *loop = cs->loop; li_tstamp remaining = cs->close_timeout - li_event_now(loop); if (-1 == cs->fd) { g_slice_free(closing_socket, cs); return; } /* empty the input buffer, wait for EOF or timeout or a socket error to close it */ for (;!loop->end;) { r = read(cs->fd, trash, sizeof(trash)); if (0 == r) break; /* got EOF */ if (0 > r) { /* error */ switch (errno) { case EINTR: /* call read again */ continue; case EAGAIN: #if EWOULDBLOCK != EAGAIN case EWOULDBLOCK: #endif /* check timeout: */ if (remaining > 0 && !(revents & EV_TIMEOUT)) { /* wait again */ ev_once(cs->loop->loop, cs->fd, EV_READ, remaining, closing_socket_cb, cs); return; } /* timeout reached, break switch and loop */ break; default: /* real error (probably ECONNRESET or similar): break switch and loop */ /* no logging: there is no context anymore for the socket */ break; } break; /* end loop */ } } close_socket_now(cs); g_slice_free(closing_socket, cs); }
void li_event_add_closing_socket(liEventLoop *loop, int fd) { closing_socket *cs; if (-1 == fd) return; shutdown(fd, SHUT_WR); if (loop->end) { close(fd); return; } cs = g_slice_new0(closing_socket); cs->loop = loop; cs->fd = fd; g_queue_push_tail_link(&loop->closing_sockets, &cs->sockets_link); cs->close_timeout = li_event_now(loop) + 10.0; ev_once(loop->loop, fd, EV_READ, 10.0, closing_socket_cb, cs); }
spx_private void ReciveRequest_GetRequest(int revents, void *arg){/*{{{*/ struct server_context *ctx = (struct server_context *) arg; if(NULL == ctx){ SpxLog1(g_log, SpxLogError, "ReciveRequest_GetRequest ctx is NULL"); return; } if(READ_HEADER == ctx->life_cycle){ if(EV_ERROR & revents){ SpxLog1(g_log, SpxLogError, "READ_HEADER EV_ERROR"); return; } if(EV_TIMEOUT & revents){ if((ctx->header_retry++) >= RETRY_TIMES){ RequestException(ctx, bad_request); SpxLog1(g_log, SpxLogError, "READ_HEADER EV_TIMEOUT"); return; } else{ ev_once(main_socket_loop, ctx->fd, EV_READ, ctx->timeout, ReciveRequest_GetRequest, ctx); return; } } if(EV_READ & revents){ char buf[LOG_HEADER_SIZE] = {0}; size_t len = 0; err_t err = ReciveRequest_GetRequest_ReadRequest(ctx->fd, buf, &len, LOG_HEADER_SIZE); if(0 == err){ log_header_unpack(buf, ctx->header); char * request = (char *) calloc(1, sizeof(char)*ctx->header->req_size); if(NULL == request){ SpxLog2(g_log, SpxLogError, err,"calloc log_header failed"); return; } ctx->req_size = ctx->header->req_size; ctx->request = request; ctx->life_cycle = READ_REQUEST; } else{ if((EAGAIN == err || EWOULDBLOCK == err || EINTR == err)) { ev_once(main_socket_loop, ctx->fd, EV_READ, ctx->timeout, ReciveRequest_GetRequest, ctx); return; } else{ SpxLog2(g_log, SpxLogError, err,"ReciveRequest_GetRequest_ReadRequest Failed"); CloseCTX(ctx); return; } } } } if(READ_REQUEST == ctx->life_cycle){ if(EV_ERROR & revents){ SpxLog1(g_log, SpxLogError, "READ_REQUEST EV_ERROR"); return; } if(EV_TIMEOUT & revents){ if((ctx->req_retry++) >= RETRY_TIMES){ RequestException(ctx, bad_request); SpxLog1(g_log, SpxLogError, "READ_REQUEST EV_TIMEOUT"); return; } else{ ev_once(main_socket_loop, ctx->fd, EV_READ, ctx->timeout, ReciveRequest_GetRequest, ctx); return; } } if(EV_READ & revents){ err_t err = ReciveRequest_GetRequest_ReadRequest(ctx->fd, ctx->request, &ctx->req_len, ctx->req_size); if(0 == err){ ctx->life_cycle = PARSE_REQUEST; RegisterAayncWatcher(&ctx->async_watcher, ParserRequest, ctx); ev_async_start(main_socket_loop, &ctx->async_watcher); ev_async_send(main_socket_loop, &ctx->async_watcher); } else{ if((EAGAIN == err || EWOULDBLOCK == err || EINTR == err)) { ev_once(main_socket_loop, ctx->fd, EV_READ, ctx->timeout, ReciveRequest_GetRequest, ctx); return; } else{ SpxLog2(g_log, SpxLogError, err,"ReciveRequest_GetRequest_ReadRequest Failed"); CloseCTX(ctx); return; } } } } }/*}}}*/