// 部分系统没有实现 accept 序列化,这里通过管道的方式,在多进程环境下通过竞争读取管道数据实现 accept 序列化 int st_netfd_serialize_accept(_st_netfd_t *fd) { _st_netfd_t **p; int osfd[2], err; if (fd->aux_data) { errno = EINVAL; return -1; } if ((p = (_st_netfd_t **)calloc(2, sizeof(_st_netfd_t *))) == NULL) return -1; if (pipe(osfd) < 0) { free(p); return -1; } if ((p[0] = st_netfd_open(osfd[0])) != NULL && (p[1] = st_netfd_open(osfd[1])) != NULL && write(osfd[1], " ", 1) == 1) { fd->aux_data = p; return 0; } /* Error */ err = errno; if (p[0]) st_netfd_free(p[0]); if (p[1]) st_netfd_free(p[1]); close(osfd[0]); close(osfd[1]); free(p); errno = err; return -1; }
static void install_sighandlers(void) { sigset_t mask; int p[2]; /* Create signal pipe */ if (pipe(p) < 0) err_sys_quit(errfd, "ERROR: process %d (pid %d): can't create" " signal pipe: pipe", my_index, my_pid); if ((sig_pipe[0] = st_netfd_open(p[0])) == NULL || (sig_pipe[1] = st_netfd_open(p[1])) == NULL) err_sys_quit(errfd, "ERROR: process %d (pid %d): can't create" " signal pipe: st_netfd_open", my_index, my_pid); /* Install signal handlers */ Signal(SIGTERM, child_sighandler); /* terminate */ Signal(SIGHUP, child_sighandler); /* restart */ Signal(SIGUSR1, child_sighandler); /* dump info */ /* Unblock signals */ sigemptyset(&mask); sigaddset(&mask, SIGTERM); sigaddset(&mask, SIGHUP); sigaddset(&mask, SIGUSR1); sigprocmask(SIG_UNBLOCK, &mask, NULL); }
void pt_shell() { st_netfd_t fd_shell; char input[1024]; int i; fd_shell = st_netfd_open(fileno(stdin)); if (fd_shell == NULL) { printf("open stdin failed\n"); } while (fd_shell) { printf(">>> "); fflush(stdout); st_read(fd_shell, input, sizeof(input), ST_UTIME_NO_TIMEOUT); if (strstr(input, "show")) pt_cmd_show(); else if (strstr(input, "run")) pt_cmd_run(); else if (strstr(input, "?")) pt_cmd_help(); else printf("invalid cmd %s", input); printf("\n"); } }
static void pt_sig_install(void) { sigset_t mask; int p[2]; /* Create signal pipe */ pipe(p); _sig_pipe[0] = st_netfd_open(p[0]); _sig_pipe[1] = st_netfd_open(p[1]); /* Install signal handlers */ signal(SIGTERM, pt_sig_catcher); /* terminate */ signal(SIGHUP, pt_sig_catcher); /* restart */ signal(SIGUSR1, pt_sig_catcher); /* dump info */ signal(SIGUSR2, pt_sig_catcher); /* dump info */ /* Unblock signals */ sigemptyset(&mask); sigaddset(&mask, SIGTERM); sigaddset(&mask, SIGHUP); sigaddset(&mask, SIGUSR1); sigaddset(&mask, SIGUSR2); sigprocmask(SIG_UNBLOCK, &mask, NULL); }
int SrsSignalManager::cycle() { int ret = ERROR_SUCCESS; if (signal_read_stfd == NULL) { signal_read_stfd = st_netfd_open(sig_pipe[0]); } int signo; /* Read the next signal from the pipe */ st_read(signal_read_stfd, &signo, sizeof(int), ST_UTIME_NO_TIMEOUT); /* Process signal synchronously */ _server->on_signal(signo); return ret; }
void *handle_conn(void *arg) { st_netfd_t client; client = (st_netfd_t)arg; arg = NULL; char buff[1024]; int len = sizeof(buff) / sizeof(buff[0]); int received; received = st_read(client, buff, len, ST_UTIME_NO_TIMEOUT); // fprintf(stdout, "%s\n", buff); st_netfd_t STDOUT; STDOUT = st_netfd_open(STDOUT_FILENO); st_write(STDOUT, buff, sizeof(buff), ST_UTIME_NO_TIMEOUT); received = st_write(client, buff, received, ST_UTIME_NO_TIMEOUT); st_netfd_close(client); return 0; }
/*--------------------------------------------------------------------------- * *--------------------------------------------------------------------------*/ int scsi_init(char *devname) { char *inq_buf; #ifdef DIXTRAC_LINUX_SG #ifdef SG_NONBLOCKING int ictl_val; #endif #ifdef SG_NONBLOCKING int fd = open(devname, O_RDWR | O_NONBLOCK); #else int fd = open(devname, O_RDWR); #endif if (fd < 0) { error_handler("Device %s not defined or no R/W permmissions.\n",devname); } #ifdef SG_NONBLOCKING ictl_val = 1; if ( 0 > ioctl(fd,SG_SET_COMMAND_Q,&ictl_val)) { if (errno == ENOTTY) ictl_val = 0; else error_handler("Problems with ioctl on device %s \n",devname); } /* #ifndef SILENT */ #if 0 printf("Command queueing%s allowed.\n",(ictl_val == 1 ? "" : " not")); #endif ictl_val = 0; /* if ( 0 > ioctl(fd,SG_SET_FORCE_PACK_ID,&ictl_val)) { error_handler("Could not set FORCE_PACK_ID on device %s \n",devname); } */ ictl_val = BIG_BUF_SIZE; if ( 0 > ioctl(fd,SG_SET_RESERVED_SIZE,&ictl_val)) { error_handler("Problems with ioctl on device %s!\n",devname); } ioctl(fd,SG_GET_RESERVED_SIZE,&ictl_val); /* #ifndef SILENT */ #if 0 fprintf(stderr, "*** The size of the RESERVED kernel buffer: %d\n",ictl_val); /* ioctl(fd,SG_GET_SG_TABLESIZE,&ictl_val); */ /* printf("TABLESIZE: %d\n",ictl_val); */ #endif #endif #ifdef STATE_THREADS if (st_init()) { error_handler("Problems with st_init!\n"); } if (!(scsidev_fd = st_netfd_open(fd))) { error_handler("Opening sthread fd failed\n", devname); } #else scsidev_fd = fd; #endif /* DIXTRAC_LINUX_SG */ #endif #ifdef DIXTRAC_FREEBSD_CAM if (cam_open_pass(devname, O_RDWR, &cam_device) == NULL) { error_handler("Opening pass device (%s) failed\n", devname); } #endif inq_buf = scsi_alloc_buffer(); /* get_scsi_version */ send_scsi_command(inq_buf, SCSI_inq_command(),0); recv_scsi_command(inq_buf); scsi_version = ((u_int8_t) inq_buf[2]); /* get the device block size (not all disks use 512-byte sector) */ exec_scsi_command(inq_buf,SCSI_read_capacity(0,0)); /* this is a global that is accessed through te SECT_SIZE macro */ blksize = _4btol((u_int8_t *) &inq_buf[4]); return(0); }
static void *link_to_peers(void *arg) { int client_fd, index, rv; st_netfd_t client; struct addrinfo hints, *ai, *p; const char *host = "0.0.0.0"; fprintf(stderr, "link to perrs\n"); for (int i=0; i<vp_count; i++) { if (i == my_index) continue; char port[16]; //snprintf(port, 16 - 1, "%d", RPC_PORT + i); index = RPC_PORT + i; sprintf(port, "%d", index); memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; if ((rv = getaddrinfo(host, port, &hints, &ai)) != 0) { fprintf(stderr, "[%d] failed to getaddrinfo to peer #%d\n", my_index, i); continue; } for (p = ai; p != NULL; p = p->ai_next) { if ((client_fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { continue; } if ((client = st_netfd_open(client_fd)) == NULL) { close(client_fd); continue; } if ((rv = st_connect(client, p->ai_addr, p->ai_addrlen, ST_UTIME_NO_TIMEOUT)) != 0) { st_netfd_close(client); close(client_fd); continue; } else { fd_list[i] = client; } // 写入 1 字节的 rpc 握手头 if ((rv = st_write(client, (char *)&my_index, 1, ST_UTIME_NO_TIMEOUT)) == -1) { fprintf(stderr, "[%d] handshake failed.\n", my_index); } fd_list[i] = client; break; } if (p == NULL) { fprintf(stderr, "[%d] failed to connect to peer #%d.\n", my_index, i); } freeaddrinfo(ai); ai = NULL; p = NULL; // 模拟:发出第一个 rpc 包 char message[] = "hello rpc."; rpcpkg_len len = strlen(message); rpcpkg_len nlen = HTON(len); // network order of len char *package = (char*)calloc(sizeof(rpcpkg_len) + len, sizeof(char)); memcpy(package, &nlen, sizeof(len)); memcpy(package + sizeof(len), message, len); fprintf(stdout, "[%d] construction an package: << ", my_index); for (int j=0; j<len + sizeof(len); j++) { fprintf(stdout, "%02X ", *((uint8_t*)package + j)); } fprintf(stdout, " >>\n"); if ((rv = st_write(client, package, len + sizeof(rpcpkg_len), ST_UTIME_NO_TIMEOUT)) == -1) { fprintf(stderr, "[%d] failed to write package into client\n", my_index); } free(package); } return NULL; }
/** * 创建用于 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; }