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; }
/* * Initialize this Virtual Processor */ int st_init(void) { _st_thread_t *thread; if (_st_active_count) { /* Already initialized */ return 0; } /* We can ignore return value here */ //st_set_eventsys(ST_EVENTSYS_DEFAULT); st_set_eventsys(ST_EVENTSYS_ALT); if (_st_io_init() < 0) return -1; memset(&_st_this_vp, 0, sizeof(_st_vp_t)); ST_INIT_CLIST(&_ST_RUNQ); ST_INIT_CLIST(&_ST_IOQ); ST_INIT_CLIST(&_ST_ZOMBIEQ); #ifdef DEBUG ST_INIT_CLIST(&_ST_THREADQ); #endif if ((*_st_eventsys->init)() < 0) return -1; _st_this_vp.pagesize = getpagesize(); _st_this_vp.last_clock = st_utime(); /* * Create idle thread */ _st_this_vp.idle_thread = st_thread_create(_st_idle_thread_start, NULL, 0, 0); if (!_st_this_vp.idle_thread) return -1; _st_this_vp.idle_thread->flags = _ST_FL_IDLE_THREAD; _st_active_count--; _ST_DEL_RUNQ(_st_this_vp.idle_thread); /* * Initialize primordial thread */ thread = (_st_thread_t *) calloc(1, sizeof(_st_thread_t) + (ST_KEYS_MAX * sizeof(void *))); if (!thread) return -1; thread->private_data = (void **) (thread + 1); thread->state = _ST_ST_RUNNING; thread->flags = _ST_FL_PRIMORDIAL; _ST_SET_CURRENT_THREAD(thread); _st_active_count++; #ifdef DEBUG _ST_ADD_THREADQ(thread); #endif return 0; }
int SrsServer::initialize_st() { int ret = ERROR_SUCCESS; // use linux epoll. if (st_set_eventsys(ST_EVENTSYS_ALT) == -1) { ret = ERROR_ST_SET_EPOLL; srs_error("st_set_eventsys use linux epoll failed. ret=%d", ret); return ret; } srs_verbose("st_set_eventsys use linux epoll success"); if(st_init() != 0){ ret = ERROR_ST_INITIALIZE; srs_error("st_init failed. ret=%d", ret); return ret; } srs_verbose("st_init success"); // set current log id. _srs_context->generate_id(); srs_info("log set id success"); return ret; }
int srs_init_st() { int ret = ERROR_SUCCESS; // 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. ret=%d", ret); return ret; } // use linux epoll. if (st_set_eventsys(ST_EVENTSYS_ALT) == -1) { ret = ERROR_ST_SET_EPOLL; srs_error("st_set_eventsys use linux epoll failed. ret=%d", ret); return ret; } srs_verbose("st_set_eventsys use linux epoll success"); if(st_init() != 0){ ret = ERROR_ST_INITIALIZE; srs_error("st_init failed. ret=%d", ret); return ret; } srs_verbose("st_init success"); return ret; }
int main(int argc, char *argv[]) { g_assert(st_set_eventsys(ST_EVENTSYS_ALT) == 0); st_init(); int status = ares_library_init(ARES_LIB_INIT_ALL); if (status != ARES_SUCCESS) { fprintf(stderr, "ares_library_init: %s\n", ares_strerror(status)); return 1; } int sock; int n; struct sockaddr_in serv_addr; if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) { perror("socket"); } n = 1; if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&n, sizeof(n)) < 0) { perror("setsockopt SO_REUSEADDR"); } memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(8080); serv_addr.sin_addr.s_addr = inet_addr("0.0.0.0"); if (bind(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { perror("bind"); } if (listen(sock, 10) < 0) { perror("listen"); } st_netfd_t server_nfd = st_netfd_open_socket(sock); st_netfd_t client_nfd; struct sockaddr_in from; int fromlen = sizeof(from); for (;;) { client_nfd = st_accept(server_nfd, (struct sockaddr *)&from, &fromlen, ST_UTIME_NO_TIMEOUT); printf("accepted\n"); if (st_thread_create(handle_connection, (void *)client_nfd, 0, 1024 * 1024) == NULL) { fprintf(stderr, "st_thread_create error\n"); } } ares_library_cleanup(); return EXIT_SUCCESS; }
void create_listener_and_accept(void) { st_set_eventsys(ST_EVENTSYS_ALT); st_init(); int listener_fd; struct addrinfo hints, *ai, *p; memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; getaddrinfo("0.0.0.0", "9595", &hints, &ai); for (p = ai; p != NULL; p = p->ai_next) { listener_fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol); if (listener_fd < 0) continue; if (bind(listener_fd, p->ai_addr, p->ai_addrlen) < 0) { close(listener_fd); continue; } break; } if (p == NULL) return; listen(listener_fd, 10); context = (struct peer_context*)calloc(5, sizeof(struct peer_context)); context[0].rpc_fd = st_netfd_open_socket(listener_fd); st_netfd_t client; struct sockaddr from; int len = sizeof(from); while ((client = st_accept(context[0].rpc_fd, &from, &len, ST_UTIME_NO_TIMEOUT)) != NULL) { st_thread_create(handle_conn, client, 0, 0); } }
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; }