int get_epollevent(int fd_listener, struct epoll_event *ep_events, int ret_poll) { int i, ret, ret_recv, fd; char buf[1024], buf_time[32]; for (i = 0; i < ret_poll; i++) { if (ep_events[i].events & EPOLLIN) { if (ep_events[i].data.fd == fd_listener) { while (1) { if ((fd = accept(fd_listener, NULL, NULL)) == -1) { if (errno == EAGAIN) break; pr_err("accept()"); break; } fcntl_setnb(fd); ADD_EV(epollfd, fd, FDSESSION_DEFAULT_TIMEOUT); pr_out("accept : add socket = %d", fd); } /* while */ } else { FDSESSION *ret_fds; if (fds_findbytimerfd(&ret_fds, ep_events[i].data.fd) == 0) { pr_out("timeout[%s] expired/closed (sfd/tfd=%d/%d)", GET_TIME0(buf_time), ret_fds->socketfd, ret_fds->timerfd); setsockopt_linger(ret_fds->socketfd); DEL_EV(epollfd, ret_fds->socketfd); } else { if ((ret_recv = recv(ep_events[i].data.fd, buf, sizeof(buf), 0)) == -1) { pr_err("recv()"); } else { if (ret_recv == 0) { pr_out("closed by foreign host (sfd=%d)", ep_events[i].data.fd); DEL_EV(epollfd, ep_events[i].data.fd); } else { pr_out("recv[%s] (fd=%d,n=%d)=%.*s", GET_TIME0(buf_time), ep_events[i].data.fd, ret_recv, ret_recv, buf); if ((ret = fds_findbysocketfd(&ret_fds, ep_events[i].data.fd)) != 0) { return ret; } if ((ret = fds_set_timerfd(ret_fds)) != 0) { return ret; } } } /* end : recv() */ } /* end : if-else timerfd */ } /* end : if-else fd_listener */ } else if (ep_events[i].events & EPOLLERR) { /* error */ } else { pr_out("fd(%d) epoll event(%d) err(%s)", ep_events[i].data.fd, ep_events[i].events, strerror(errno)); } } return 0; }
/* Name : start_thread * Desc : thread function with message * Argv : int idx (child index) * Ret : None */ void *start_thread(void *arg) { struct thread_arg *t_arg = (struct thread_arg *)arg; char ts_now[20]; int ret; pr_out("[Thread:%d] [%s] sleep(%d)", t_arg->idx, GET_TIME0(ts_now), t_arg->idx + 2); sleep(t_arg->idx + 2); ret = pthread_barrier_wait(&pt_barrier); if (ret == PTHREAD_BARRIER_SERIAL_THREAD) { pr_out("[Thread:%d] PTHREAD_BARRIER_SERIAL_THREAD", t_arg->idx); } pr_out("\t[Thread:%d] [%s] wake up", t_arg->idx, GET_TIME0(ts_now)); pthread_exit(t_arg); }
int fds_set_timerfd(FDSESSION *fds) { struct itimerspec rt_tspec = { .it_value.tv_sec = fds->timeout }; if (timerfd_settime(fds->timerfd, 0, &rt_tspec, NULL) == -1) { pr_err("timerfd_settime"); return errno; } char buf_time[32]; pr_out("timeout[%s] start (sfd/tfd=%d/%d, timeout=%d)", GET_TIME0(buf_time), fds->socketfd, fds->timerfd, fds->timeout); return 0; } int fds_deletebytimerfd(int timerfd) { int i, flag = 0; FDSESSION *iter_fds; for (i = 0; i < fds_list.n_used; i++) { iter_fds = &fds_list.list[i]; if (iter_fds->timerfd == timerfd) { if (i != (fds_list.n_used - 1)) { fds_list.list[i] = fds_list.list[fds_list.n_used - 1]; } fds_list.list[fds_list.n_used - 1].socketfd = -1; fds_list.list[fds_list.n_used - 1].timerfd = -1; flag = 1; break; } } if (flag == 0) { return ENOENT; } --fds_list.n_used; return 0; }
int main(int argc, char *argv[]) { int ret, ret_poll, fd_listener; char *port; struct epoll_event *ep_events; if (argc > 2) { printf("%s [port number]\n", argv[0]); exit(EXIT_FAILURE); } if (argc == 2) { port = strdup(argv[1]); } else { port = strdup("0"); } struct addrinfo ai, *ai_ret; int rc_gai; memset(&ai, 0, sizeof(ai)); ai.ai_family = AF_INET; ai.ai_socktype = SOCK_STREAM; ai.ai_flags = AI_ADDRCONFIG | AI_PASSIVE; if ((rc_gai = getaddrinfo(NULL, port, &ai, &ai_ret)) != 0) { pr_err("getaddrinfo():%s", gai_strerror(rc_gai)); exit(EXIT_FAILURE); } if ((fd_listener = socket(ai_ret->ai_family, ai_ret->ai_socktype, ai_ret->ai_protocol)) == -1) { pr_err("socket()"); exit(EXIT_FAILURE); } fcntl_setnb(fd_listener); if (bind(fd_listener, ai_ret->ai_addr, ai_ret->ai_addrlen) == -1) { pr_err("bind()"); exit(EXIT_FAILURE); } pr_out("bind : %s", port); listen(fd_listener, LISTEN_BACKLOG); if ((epollfd = epoll_create(1)) == -1) { exit(EXIT_FAILURE); } if ((ep_events = calloc(max_ep_events, sizeof(struct epoll_event))) == NULL) { exit(EXIT_FAILURE); } ADD_EV(epollfd, fd_listener, 0); char buf_time[32]; while (1) { pr_out("[%s] epoll waiting...", GET_TIME0(buf_time)); if ((ret_poll = epoll_wait(epollfd, ep_events, max_ep_events, -1)) == -1) { /* error */ } pr_out("epoll_wait = %d", ret_poll); ret = get_epollevent(fd_listener, ep_events, ret_poll); if (ret != 0) { pr_err("get_epollevent()"); } } return 0; }