static void on_events(handle_t h,int events){ kn_socket *s = (kn_socket*)h; if(h->status == SOCKET_CLOSE) return; do{ h->inloop = 1; if(h->status == SOCKET_LISTENING){ process_accept(s); }else if(h->status == SOCKET_CONNECTING){ process_connect(s,events); }else if(h->status == SOCKET_ESTABLISH){ if(events & EVENT_READ){ process_read(s); if(h->status == SOCKET_CLOSE) break; } if(events & EVENT_WRITE) process_write(s); } h->inloop = 0; }while(0); if(h->status == SOCKET_CLOSE) on_destroy(s); }
int event_run_loop(int wait_ms) { int fd; int i; int event_num = 0; int flags; while(1) { event_num = epoll_wait(epoll_fd, epoll_events, EVENT_NUM,wait_ms); for(i = 0; i < event_num; i++) { fd = epoll_events[i].data.fd; flags = epoll_events[i].events; if(g_state[fd]) { if(flags & EPOLLIN) { if(fd == g_sfd) { process_accept(fd); } else { process_request(fd); } } else { event_free(fd); } } else { close(fd); } } } return event_num; }
int main(int argc, char **argv) { fd_set master_fds; /* master file descriptor list */ fd_set read_fds; /* temp file descriptor list for read events */ fd_set write_fds; /* temp file descriptor list for write events */ int listen_sock, fdmax; int optval; int i; struct sockaddr_in addr; char *reply; /* this should be implemented as a generic map socket:offset, -1 ... not connected, >=0 ... amount of sent bytes */ int sock_to_offset[SOCKET_MAX]; /**********/ for (i = 0; i < SOCKET_MAX; i++) sock_to_offset[i] = NOT_CONNECTED; reply = generate_large_message(); /* clear the master and temp sets */ FD_ZERO(&master_fds); FD_ZERO(&read_fds); FD_ZERO(&write_fds); /* create socket */ listen_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (listen_sock < 0) err("socket()"); /* non-blocking operation */ optval = 1; if (ioctl(listen_sock, FIONBIO, (char *)&optval) < 0) { close(listen_sock); err("ioctl nonblock"); } /* set reusable flag */ optval = 1; setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); /* prepare inet address */ memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(SRV_PORT); addr.sin_addr.s_addr = htonl(INADDR_ANY); /* listen on all interfaces */ if (bind(listen_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) err("bind"); if (listen(listen_sock, 10) < 0) err("listen"); /* add the listener to the master set */ FD_SET(listen_sock, &master_fds); /* keep track of the biggest file descriptor */ fdmax = listen_sock; /* so far, it's this one*/ for(;;) { /* copy it */ memcpy(&read_fds, &master_fds, sizeof(master_fds)); memcpy(&write_fds, &master_fds, sizeof(master_fds)); /* wait for any action */ if (select(fdmax + 1, &read_fds, &write_fds, NULL, NULL) == -1) { close(listen_sock); err("select"); } printf("select is OK\n"); for (i = 0; i <= fdmax; i++) { if (FD_ISSET(i, &read_fds)) { /* the socket is the listening socket */ if (i == listen_sock) process_accept(listen_sock, &master_fds, &fdmax, sock_to_offset); /* otherwise it is a connection socket ready for reading */ else process_recv(i, &master_fds, &fdmax, reply, sock_to_offset); } else if (FD_ISSET(i, &write_fds)) { /* socket is ready to send data */ process_send(i, &master_fds, &fdmax, reply, sock_to_offset); } } } return 0; }
int32_t epoll_loop(poller_t n,int32_t ms) { assert(n); if(ms < 0)ms = 0; uint64_t sleep_ms; uint64_t timeout = GetSystemMs64() + (uint64_t)ms; uint64_t current_tick; uint32_t read_event = EV_IN | EPOLLRDHUP | EPOLLERR | EPOLLHUP; int32_t notify = 0; do{ if(!dlist_empty(&n->connecting)) { //check timeout connecting uint64_t l_now = GetSystemMs64(); dlist_check_remove(&n->connecting,check_connect_timeout,(void*)&l_now); } if(!is_active_empty(n)) { struct dlist *actived = get_active_list(n); n->actived_index = (n->actived_index+1)%2; socket_t s; while((s = (socket_t)dlist_pop(actived)) != NULL) { if(Process(s)) putin_active(n,(struct dnode*)s); } } current_tick = GetSystemMs64(); if(is_active_empty(n)) sleep_ms = timeout > current_tick ? timeout - current_tick:0; else sleep_ms = 0; notify = 0; int32_t nfds = _epoll_wait(n->poller_fd,n->events,MAX_SOCKET,(uint32_t)sleep_ms); if(nfds < 0) return -1; int32_t i; for(i = 0 ; i < nfds ; ++i) { if(n->events[i].data.fd == n->pipe_reader) { char buf[1]; read(n->pipe_reader,buf,1); notify = 1; }else{ socket_t sock = (socket_t)n->events[i].data.ptr; if(sock) { if(sock->socket_type == CONNECT){ process_connect(sock); } else if(sock->socket_type == LISTEN){ process_accept(sock); } else{ if(n->events[i].events & read_event) on_read_active(sock); if(n->events[i].events & EPOLLOUT) on_write_active(sock); } } } } current_tick = GetSystemMs64(); }while(notify == 0 && timeout > current_tick); return 0; }