int srs_st_init() { int ret = ERROR_SUCCESS; #ifdef __linux__ // check epoll, some old linux donot support epoll. // @see https://github.com/simple-rtmp-server/srs/issues/162 if (!srs_st_epoll_is_supported()) { ret = ERROR_ST_SET_EPOLL; srs_error("epoll required on Linux. ret=%d", ret); return ret; } #endif // Select the best event system available on the OS. In Linux this is // epoll(). On BSD it will be kqueue. if (st_set_eventsys(ST_EVENTSYS_ALT) == -1) { ret = ERROR_ST_SET_EPOLL; srs_error("st_set_eventsys use %s failed. ret=%d", st_get_eventsys_name(), ret); return ret; } srs_trace("st_set_eventsys to %s", st_get_eventsys_name()); if(st_init() != 0) { ret = ERROR_ST_INITIALIZE; srs_error("st_init failed. ret=%d", ret); return ret; } srs_trace("st_init success, use %s", st_get_eventsys_name()); return ret; }
int _peer_listen(const peer_index_t index) { // 现在开始创建 rpc_fd int listen_fd; struct addrinfo hints, *ai, *p; int reuseaddr = 1; int rv; struct peer_info *peer_info; memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; peer_info = &peer_list[index]; LOG("[%d] 准备从以下地址获取 IP 信息:%s:%s\n", self_index, peer_info->host, peer_info->port); if ((rv = getaddrinfo(peer_info->host, peer_info->port, &hints, &ai)) != 0) { ERR("[%d] getaddrinfo 时出现错误:%s\n", self_index, strerror(errno)); return -1; } for (p = ai; p != NULL; p = p->ai_next) { if ((listen_fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0) { ERR("[%d] socket: %s\n", self_index, strerror(errno)); continue; } setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(int)); if (bind(listen_fd, p->ai_addr, p->ai_addrlen) < 0) { close(listen_fd); ERR("[%d] bind: %s\n", self_index, strerror(errno)); continue; } LOG("[%d] success to bind.\n", self_index); break; } if (p == NULL) { ERR("[%d] failed to bind at %s.\n", self_index, peer_info->host); return -1; } freeaddrinfo(ai); ai = NULL; p = NULL; if (listen(listen_fd, 10) == -1) { ERR("[%d] failed to listen in %d\n", self_index, peer_info->port); goto close_fd_and_quit; } // 初始化 state-threads 系统 if (st_set_eventsys(ST_EVENTSYS_ALT) == -1) ERR("[%d] Can't set event system to alt: %s\n", self_index, strerror(errno)); if (st_init() < 0) { ERR("[%d] st_init \n", self_index); goto close_fd_and_quit; } LOG("[%d] The event system of state-threads is: %s\n", self_index, st_get_eventsys_name()); // 转换 fd if ((peer_list[self_index].rpc_fd = st_netfd_open_socket(listen_fd)) == NULL) { ERR("[%d] st_netfd_open: %s\n", self_index, strerror(errno)); goto close_fd_and_quit; } return 0; close_fd_and_quit: close(listen_fd); return -1; }
/** * 创建用于 rpc 通讯的 TCP/IP 内容 */ void create_rpc_listeners(void) { int fd; struct addrinfo hints, *ai, *p; int reuseaddr = 1; // for SO_REUSEADDR int rv; memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; int rpc_port = RPC_PORT + my_index; char port[16]; sprintf(port, "%d", rpc_port); fprintf(stdout, "[%d] want to getaddrinfo to: 0.0.0.0:%d\n", my_index, rpc_port); if ((rv = getaddrinfo("0.0.0.0", port, &hints, &ai)) != 0) { err_sys_quit(1, "[%d] getaddrinfo: %s\n", my_index, gai_strerror(rv)); } for (p = ai; p != NULL; p = p->ai_next) { fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol); if (fd < 0) { fprintf(stderr, "[%d] socket: %s\n", my_index, strerror(errno)); continue; } setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(int)); if (bind(fd, p->ai_addr, p->ai_addrlen) < 0) { close(fd); fprintf(stderr, "[%d] bind: %s\n", my_index, strerror(errno)); continue; } fprintf(stdout, "[%d] success to bind.\n", my_index); break; } if (p == NULL) { err_sys_quit(1, "[%d] failed to bind at 0.0.0.0\n", my_index); } freeaddrinfo(ai); // all done with this // 防止野指针 ai = NULL; p = NULL; if (listen(fd, 10) == -1) { err_sys_quit(1, "[%d] failed to listen in %d\n", my_index, rpc_port); } // 初始化 st 线程 if (st_set_eventsys(ST_EVENTSYS_ALT) == -1) fprintf(stderr, "[%d] Can't set event system to alt: %s\n", my_index, strerror(errno)); if (st_init() < 0) { err_sys_quit(1, "[%d] failed to init st\n", my_index); } fprintf(stdout, "[%d] the event system is: %s\n", my_index, st_get_eventsys_name()); // 转换 fd if ((rpc_fd = st_netfd_open(fd)) == NULL) err_sys_quit(1, "[%d] failed to convert fd into st_fd: %s\n", my_index, strerror(errno)); fprintf(stdout, "[%d] vp_count is %d.\n", my_index, vp_count); fd_list = (st_netfd_t*)calloc(vp_count, sizeof(st_netfd_t)); fd_list[my_index] = rpc_fd; }