intmain(){ int ret = 0; int server_sockfd, client_sockfd; structsockaddr_inserver_address; structsockaddr_inclient_address; int client_len = 0; structpollfdclients[CLIENT_SIZE]; int conn_count = 0; // 当前客户端连接数
intdo_sys_poll(struct pollfd __user *ufds, unsignedint nfds, struct timespec *end_time) { structpoll_wqueuestable; int err = -EFAULT, fdcount, len, size; /* Allocate small arguments on the stack to save memory and be faster - use long to make sure the buffer is aligned properly on 64 bit archs to avoid unaligned access */ /* 为了加快处理速度和提高系统性能,这里优先定义好一个大小为POLL_STACK_ALLOC的栈空间, 该栈空间转换为poll_list结构体,以存储需要被检测的socket描述符 */ long stack_pps[POLL_STACK_ALLOC/sizeof(long)]; structpoll_list *consthead = (structpoll_list *)stack_pps; structpoll_list *walk = head; unsignedlong todo = nfds;
if (nfds > current->signal->rlim[RLIMIT_NOFILE].rlim_cur) return -EINVAL;
// 通过计算得到前面分配的栈空间能存储多少个pollfd结构 len = min_t(unsignedint, nfds, N_STACK_PPS); for (;;) { walk->next = NULL; walk->len = len; if (!len) break;
/* Optimise the no-wait case */ if (end_time && !end_time->tv_sec && !end_time->tv_nsec) { pt = NULL; timed_out = 1; }
if (end_time && !timed_out) slack = estimate_accuracy(end_time);
for (;;) { structpoll_list *walk;
// 对所有的struct pollfd循环,以调用do_pollfd函数。 for (walk = list; walk != NULL; walk = walk->next) { structpollfd * pfd, * pfd_end;
pfd = walk->entries; pfd_end = pfd + walk->len; for (; pfd != pfd_end; pfd++) { /* * Fish for events. If we found one, record it * and kill the poll_table, so we don't * needlessly register any other waiters after * this. They'll get immediately deregistered * when we break out and return. */ // 调用 do_pollfd() 以检查socket文件描述符的状态变化,如果有变化,则count加1 if (do_pollfd(pfd, pt)) { count++; pt = NULL; } } } /* * All waiters have already been registered, so don't provide * a poll_table to them on the next loop iteration. */ pt = NULL; if (!count) { count = wait->error; /* 检查是否有需要处理的信号,这里的意思是就算是poll调用进入到sys_poll系统调用之后, * 也可以接收外部信号,从而退出当前系统调用(因为我们知道一般的系统调用都不会被中断的, * 所以系统调用一般都尽量很快的返回) */ if (signal_pending(current)) count = -EINTR; }
// for循环退出的条件:如果有文件描述符发生变化,则退出,或者超时退出 if (count || timed_out) break;
/* * If this is the first loop and we have a timeout * given, then we convert to ktime_t and set the to * pointer to the expiry value. */ if (end_time && !to) { expire = timespec_to_ktime(*end_time); to = &expire; }
if (!poll_schedule_timeout(wait, TASK_INTERRUPTIBLE, to, slack)) timed_out = 1; } return count; }
未找到相关的 Issues 进行评论
请联系 @Grizzly1127 初始化创建