/** * 接收 rpc 连接 * 进程的主线程在这里回环 */ void accept_client(void) { st_netfd_t client; struct sockaddr from; int fromlen = sizeof(from); while ((client = st_accept(rpc_fd, &from, &fromlen, ST_UTIME_NO_TIMEOUT)) != NULL) { st_netfd_setspecific(client, get_in_addr(&from), NULL); if (st_thread_create(handle_clientconn, &client, 0, 0) == NULL) fprintf(stderr, "[%d] failed to create the client thread: %s\n", my_index, strerror(errno)); } st_netfd_close(rpc_fd); }
static void *handle_connections(void *arg) { st_netfd_t srv_nfd, cli_nfd; struct sockaddr_in from; int fromlen; long i = (long) arg; srv_nfd = srv_socket[i].nfd; fromlen = sizeof(from); while (WAIT_THREADS(i) <= max_wait_threads) { cli_nfd = st_accept(srv_nfd, (struct sockaddr *)&from, &fromlen, ST_UTIME_NO_TIMEOUT); if (cli_nfd == NULL) { err_sys_report(errfd, "ERROR: can't accept connection: st_accept"); continue; } /* Save peer address, so we can retrieve it later */ st_netfd_setspecific(cli_nfd, &from.sin_addr, NULL); WAIT_THREADS(i)--; BUSY_THREADS(i)++; if (WAIT_THREADS(i) < min_wait_threads && TOTAL_THREADS(i) < max_threads) { /* Create another spare thread */ if (st_thread_create(handle_connections, (void *)i, 0, 0) != NULL) WAIT_THREADS(i)++; else err_sys_report(errfd, "ERROR: process %d (pid %d): can't create" " thread", my_index, my_pid); } handle_session(i, cli_nfd); st_netfd_close(cli_nfd); WAIT_THREADS(i)++; BUSY_THREADS(i)--; } WAIT_THREADS(i)--; return NULL; }
void _peer_accept(void) { st_netfd_t client; struct sockaddr from; int fromlen = sizeof(from); struct peer_info *peer_info; peer_info = &peer_list[self_index]; // 每个 Peer 的主回环 while ((client = st_accept(peer_info->rpc_fd, &from, &fromlen, ST_UTIME_NO_TIMEOUT)) != NULL) { LOG("[%d] 收到一个 RPC 互联请求\n", self_index); st_netfd_setspecific(client, get_in_addr(&from), NULL); if (st_thread_create(_handle_peer_interconnect, client, 0, 0) == NULL) ERR("[%d] failed to create the client thread: %s\n", self_index, strerror(errno)); } LOG("[%d] 完成了当前 Peer 的主循环: %s\n", self_index, strerror(errno)); st_netfd_close(peer_info->rpc_fd); }