int handle_back_event(struct author *author) { int infinite = 1, ret, i, epfd = author->bdepfd; struct sockinfo si = {{0}}; int bf = 0, rx; struct epoll_event ev = {0}, *e = author->e; uchar *buf = author->tmpbuffer; while (1 && infinite) { bf = author->audp; ret = epoll_wait(epfd, e, BACK_EVENT, 500); // 1000 is 1s if (ret <= 0) break; for (i = 0; i < ret; i++) { memset(&si, 0, sizeof(struct sockinfo)); si.buf = buf; if (e[i].data.fd == bf) { si.socktype = UDP; while (cb_read_auth(e + i, &si) > 0) { rx = passer_auth_data(author, buf, &si); after_pass_data(rx, author, si.mbuf); } } else if (e[i].data.fd > 0) // fd 0 will be ignored { if (e[i].events == EPOLLOUT) //ready to write { rx = send_msg_tcp(author, e[i].data.fd); if (rx < 0) printf("send msg tcp error\n"); ev.data.fd = e[i].data.fd; ev.events = EPOLLIN; epoll_ctl(epfd, EPOLL_CTL_MOD, e[i].data.fd, &ev); } else if (e[i].events == EPOLLIN) { si.socktype = TCP; rx = cb_read_auth(e + i, &si); if (rx < 0) { author->eptcpfds[e[i].data.fd].ret = 0; close(e[i].data.fd); ev.data.fd = e[i].data.fd; // mbuf_free(si.mbuf); epoll_ctl(epfd, EPOLL_CTL_DEL, ev.data.fd, &ev); } else { rx = passer_auth_data(author, buf, &si); after_pass_data(rx, author, si.mbuf); } } else //error { //we do not handle the fail condition //just delete it from epoll and close it //EPOLLIN = 0x001, //EPOLLPRI = 0x002, //EPOLLOUT = 0x004, //EPOLLERR = 0x008, //EPOLLHUP = 0x010, ev.data.fd = e[i].data.fd; rx = epoll_ctl(epfd, EPOLL_CTL_DEL, e[i].data.fd, &ev); author->eptcpfds[e[i].data.fd].ret = 0; close(e[i].data.fd); //printf("epoll fd=%d,events=0x%x,rx=%d\n",e[i].data.fd,e[i].events,rx); } } } } return 0; }
int silly_socket_poll() { int err; sp_event_t *e; struct socket *s; struct silly_socket *ss = SSOCKET; eventwait(ss); err = cmd_process(ss); if (err < 0) return -1; if (err >= 1) clear_socket_event(ss); while (ss->eventindex < ss->eventcount) { int ei = ss->eventindex++; e = &ss->eventbuff[ei]; s = (struct socket *)SP_UD(e); if (s == NULL) //the socket event has be cleared continue; switch (s->type) { case STYPE_LISTEN: assert(SP_READ(e)); report_accept(ss, s); continue; case STYPE_CONNECTING: s->type = STYPE_SOCKET; report_connected(ss, s); continue; case STYPE_RESERVE: fprintf(stderr, "[socket] poll reserve socket\n"); continue; case STYPE_HALFCLOSE: case STYPE_SOCKET: case STYPE_UDPBIND: break; case STYPE_CTRL: continue; default: fprintf(stderr, "[socket] poll: unkonw socket type:%d\n", s->type); continue; } if (SP_ERR(e)) { report_close(ss, s, 0); delsocket(ss, s); continue; } if (SP_READ(e)) { switch (s->protocol) { case PROTOCOL_TCP: err = forward_msg_tcp(ss, s); break; case PROTOCOL_UDP: err = forward_msg_udp(ss, s); break; default: fprintf(stderr, "[socket] poll: unsupport protocol:%d\n", s->protocol); continue; } //this socket have already occurs error, so ignore the write event if (err < 0) continue; } if (SP_WRITE(e)) { if (s->protocol == PROTOCOL_TCP) send_msg_tcp(ss, s); else send_msg_udp(ss, s); } } return 0; }