// 部分系统没有实现 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; }
int st_netfd_close(_st_netfd_t *fd) { if ((*_st_eventsys->fd_close)(fd->osfd) < 0) return -1; st_netfd_free(fd); return close(fd->osfd); }
static _st_netfd_t *_st_netfd_new(int osfd, int nonblock, int is_socket) { _st_netfd_t *fd; int flags = 1; #ifndef USE_POLL if (osfd >= FD_SETSIZE) { errno = EMFILE; return NULL; } #endif if (_st_netfd_freelist) { fd = _st_netfd_freelist; _st_netfd_freelist = _st_netfd_freelist->next; } else { fd = calloc(1, sizeof(_st_netfd_t)); if (!fd) return NULL; } fd->osfd = osfd; fd->inuse = 1; fd->next = NULL; if (nonblock) { /* Use just one system call */ if (is_socket && ioctl(osfd, FIONBIO, &flags) != -1) return fd; /* Do it the Posix way */ if ((flags = fcntl(osfd, F_GETFL, 0)) < 0 || fcntl(osfd, F_SETFL, flags | O_NONBLOCK) < 0) { st_netfd_free(fd); return NULL; } } return fd; }
// 将 osfd 转换为 _st_netfd_t 并返回 static _st_netfd_t *_st_netfd_new(int osfd, int nonblock, int is_socket) { _st_netfd_t *fd; int flags = 1; // 先判断下要不要扩容 if ((*_st_eventsys->fd_new)(osfd) < 0) return NULL; // 从空闲 netfd 队列中取出一个 netfd,如果空闲队列为空则创建一个 netfd。 if (_st_netfd_freelist) { fd = _st_netfd_freelist; _st_netfd_freelist = _st_netfd_freelist->next; } else { fd = calloc(1, sizeof(_st_netfd_t)); if (!fd) return NULL; } fd->osfd = osfd; fd->inuse = 1; fd->next = NULL; // 设置非阻塞 if (nonblock) { /* Use just one system call */ if (is_socket && ioctl(osfd, FIONBIO, &flags) != -1) return fd; /* Do it the Posix way */ if ((flags = fcntl(osfd, F_GETFL, 0)) < 0 || fcntl(osfd, F_SETFL, flags | O_NONBLOCK) < 0) { st_netfd_free(fd); return NULL; } } return fd; }
int st_netfd_close(_st_netfd_t *fd) { #if 0 //确认了,fd是非空的 // if(fd==NULL) // LOGE("st_netfd_close fd is NULL "); // else // LOGD("st_netfd_close fd not NULL "); #if 0 //这么写就会有段错误啊,fd不是空,那是神马情况啊 LOGD("st_netfd_close before fd_close, fd->osfd[%d]",fd->osfd); #else LOGD("st_netfd_close before fd_close 1"); #endif LOGD("st_netfd_close before fd_close 2"); #if 1 //执行下面的这句话就挂了 if ((*_st_eventsys->fd_close)(fd->osfd) < 0) { LOGD("(*_st_eventsys->fd_close)(fd->osfd) < 0 "); return -1; } LOGD("st_netfd_close 222 "); st_netfd_free(fd); return close(fd->osfd); #endif #else LOGD("JUST TEST st_netfd_close"); #endif return 0; }
static _st_netfd_t *_st_netfd_new(int osfd, int nonblock, int is_socket) { _st_netfd_t *fd; int flags = 1; if ((*_st_eventsys->fd_new)(osfd) < 0) //跳转到了event.c的416行 return NULL; pthread_mutex_lock(&_st_netfd_freelist_mutex); //加锁 if (_st_netfd_freelist) { fd = _st_netfd_freelist; _st_netfd_freelist = _st_netfd_freelist->next; pthread_mutex_unlock(&_st_netfd_freelist_mutex); } else { //居然走这里? pthread_mutex_unlock(&_st_netfd_freelist_mutex); fd = calloc(1, sizeof(_st_netfd_t)); if (!fd) return NULL; } fd->osfd = osfd; fd->inuse = 1; fd->next = NULL; if (nonblock) { //走这里 /* Use just one system call */ if (is_socket && ioctl(osfd, FIONBIO, &flags) != -1) return fd; /* Do it the Posix way *///走这里? if ((flags = fcntl(osfd, F_GETFL, 0)) < 0 || fcntl(osfd, F_SETFL, flags | O_NONBLOCK) < 0) { st_netfd_free(fd); //走这里? return NULL; } } return fd; }
int st_netfd_close(_st_netfd_t *fd) { st_netfd_free(fd); return close(fd->osfd); }