static void set_thread_throttling(void) { /* * Calculate total values across all processes. * All numbers are per listening socket. */ if (max_wait_threads == 0) max_wait_threads = MAX_WAIT_THREADS_DEFAULT * vp_count; /* Assuming that each client session needs FD_PER_THREAD file descriptors */ if (max_threads == 0) max_threads = (st_getfdlimit() * vp_count) / FD_PER_THREAD / sk_count; if (max_wait_threads > max_threads) max_wait_threads = max_threads; /* * Now calculate per-process values. */ if (max_wait_threads % vp_count) max_wait_threads = max_wait_threads / vp_count + 1; else max_wait_threads = max_wait_threads / vp_count; if (max_threads % vp_count) max_threads = max_threads / vp_count + 1; else max_threads = max_threads / vp_count; if (min_wait_threads > max_wait_threads) min_wait_threads = max_wait_threads; }
ST_HIDDEN int _st_epoll_init(void) { int fdlim; int err = 0; int rv = 0; _st_epoll_data = (struct _st_epolldata *) calloc(1, sizeof(*_st_epoll_data)); if (!_st_epoll_data) return -1; fdlim = st_getfdlimit(); _st_epoll_data->fd_hint = (fdlim > 0 && fdlim < ST_EPOLL_EVTLIST_SIZE) ? fdlim : ST_EPOLL_EVTLIST_SIZE; if ((_st_epoll_data->epfd = epoll_create(_st_epoll_data->fd_hint)) < 0) { err = errno; rv = -1; goto cleanup_epoll; } fcntl(_st_epoll_data->epfd, F_SETFD, FD_CLOEXEC); _st_epoll_data->pid = getpid(); /* Allocate file descriptor data array */ _st_epoll_data->fd_data_size = _st_epoll_data->fd_hint; _st_epoll_data->fd_data = (_epoll_fd_data_t *)calloc(_st_epoll_data->fd_data_size, sizeof(_epoll_fd_data_t)); if (!_st_epoll_data->fd_data) { err = errno; rv = -1; goto cleanup_epoll; } /* Allocate event lists */ _st_epoll_data->evtlist_size = _st_epoll_data->fd_hint; _st_epoll_data->evtlist = (struct epoll_event *)malloc(_st_epoll_data->evtlist_size * sizeof(struct epoll_event)); if (!_st_epoll_data->evtlist) { err = errno; rv = -1; } cleanup_epoll: if (rv < 0) { _st_epoll_free(); _st_epoll_data = NULL; errno = err; } return rv; }
// epoll 事件源系统初始化 ST_HIDDEN int _st_epoll_init(void) { int fdlim; int err = 0; int rv = 0; // 申请 _st_epolldata 控件 _st_epoll_data = (struct _st_epolldata *) calloc(1, sizeof(*_st_epoll_data)); if (!_st_epoll_data) return -1; // 设置当前事件系统描述符限制(最大为 ST_EPOLL_EVTLIST_SIZE (4096) ) // Linux 2.6.8 内核以后该参数没有实际意义: epoll_create() creates an epoll(7) instance. Since Linux 2.6.8, the size argument is ignored, but must be greater than zero. fdlim = st_getfdlimit(); _st_epoll_data->fd_hint = (fdlim > 0 && fdlim < ST_EPOLL_EVTLIST_SIZE) ? fdlim : ST_EPOLL_EVTLIST_SIZE; // 创建 epoll 描述符 if ((_st_epoll_data->epfd = epoll_create(_st_epoll_data->fd_hint)) < 0) { err = errno; rv = -1; goto cleanup_epoll; } // 设置 FD_CLOEXEC 标致位,获取当前进程 id fcntl(_st_epoll_data->epfd, F_SETFD, FD_CLOEXEC); _st_epoll_data->pid = getpid(); /* Allocate file descriptor data array */ // 申请文件描述符 bucket 内存 _st_epoll_data->fd_data_size = _st_epoll_data->fd_hint; _st_epoll_data->fd_data = (_epoll_fd_data_t *)calloc(_st_epoll_data->fd_data_size, sizeof(_epoll_fd_data_t)); if (!_st_epoll_data->fd_data) { err = errno; rv = -1; goto cleanup_epoll; } /* Allocate event lists */ // 申请 epoll_event 结构内存 _st_epoll_data->evtlist_size = _st_epoll_data->fd_hint; _st_epoll_data->evtlist = (struct epoll_event *)malloc(_st_epoll_data->evtlist_size * sizeof(struct epoll_event)); if (!_st_epoll_data->evtlist) { err = errno; rv = -1; } cleanup_epoll: if (rv < 0) { if (_st_epoll_data->epfd >= 0) close(_st_epoll_data->epfd); free(_st_epoll_data->fd_data); free(_st_epoll_data->evtlist); free(_st_epoll_data); _st_epoll_data = NULL; errno = err; } return rv; }