*参照元 [#z3e08e80] #backlinks *説明 [#sed76b7e] -パス: [[linux-4.4.1/fs/select.c]] -FIXME: これは何? --説明 **引数 [#p0970b1d] -unsigned int nfds -- -struct poll_list *list -- --[[linux-4.4.1/poll_list]] -struct poll_wqueues *wait -- --[[linux-4.4.1/poll_wqueues]] -struct timespec *end_time -- --[[linux-4.4.1/timespec]] **返り値 [#r0630027] -int -- **参考 [#e0986963] *実装 [#qe78df94] static int do_poll(unsigned int nfds, struct poll_list *list, struct poll_wqueues *wait, struct timespec *end_time) { poll_table* pt = &wait->pt; ktime_t expire, *to = NULL; int timed_out = 0, count = 0; unsigned long slack = 0; unsigned int busy_flag = net_busy_loop_on() ? POLL_BUSY_LOOP : 0; unsigned long busy_end = 0; - --[[linux-4.4.1/poll_table]] --[[linux-4.4.1/ktime_t]] --[[linux-4.4.1/net_busy_loop_on()]] /* Optimise the no-wait case */ if (end_time && !end_time->tv_sec && !end_time->tv_nsec) { pt->_qproc = NULL; timed_out = 1; } if (end_time && !timed_out) slack = select_estimate_accuracy(end_time); - --[[linux-4.4.1/select_estimate_accuracy()]] for (;;) { struct poll_list *walk; bool can_busy_loop = false; for (walk = list; walk != NULL; walk = walk->next) { struct pollfd * pfd, * pfd_end; - --[[linux-4.4.1/pollfd]] pfd = walk->entries; pfd_end = pfd + walk->len; for (; pfd != pfd_end; pfd++) { /* * Fish for events. If we found one, record it * and kill poll_table->_qproc, so we don't * needlessly register any other waiters after * this. They'll get immediately deregistered * when we break out and return. */ if (do_pollfd(pfd, pt, &can_busy_loop, busy_flag)) { count++; pt->_qproc = NULL; /* found something, stop busy polling */ busy_flag = 0; can_busy_loop = false; } - --[[linux-4.4.1/do_pollfd()]] } } /* * All waiters have already been registered, so don't provide * a poll_table->_qproc to them on the next loop iteration. */ pt->_qproc = NULL; if (!count) { count = wait->error; if (signal_pending(current)) count = -EINTR; } if (count || timed_out) break; - --[[linux-4.4.1/signal_pending()]] /* only if found POLL_BUSY_LOOP sockets && not out of time */ if (can_busy_loop && !need_resched()) { if (!busy_end) { busy_end = busy_loop_end_time(); continue; } if (!busy_loop_timeout(busy_end)) continue; } busy_flag = 0; - --[[linux-4.4.1/need_resched()]] --[[linux-4.4.1/busy_loop_end_time()]] --[[linux-4.4.1/busy_loop_timeout()]] /* * 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; } - --[[linux-4.4.1/timespec_to_ktime()]] if (!poll_schedule_timeout(wait, TASK_INTERRUPTIBLE, to, slack)) timed_out = 1; - --[[linux-4.4.1/poll_schedule_timeout()]] } return count; } *コメント [#i397c65b]