设为首页 加入收藏

TOP

IO多路复用(二)
2023-07-23 13:40:42 】 浏览:69
Tags:路复用
lt;<= 1) { struct fd f; if (i >= n) break; if (!(bit & all_bits)) continue; mask = EPOLLNVAL; f = fdget(i); if (f.file) { wait_key_set(wait, in, out, bit, busy_flag); mask = vfs_poll(f.file, wait); fdput(f); } if ((mask & POLLIN_SET) && (in & bit)) { res_in |= bit; retval++; wait->_qproc = NULL; } if ((mask & POLLOUT_SET) && (out & bit)) { res_out |= bit; retval++; wait->_qproc = NULL; } if ((mask & POLLEX_SET) && (ex & bit)) { res_ex |= bit; retval++; wait->_qproc = NULL; } if (retval) { can_busy_loop = false; busy_flag = 0; } else if (busy_flag & mask) can_busy_loop = true; } if (res_in) *rinp = res_in; if (res_out) *routp = res_out; if (res_ex) *rexp = res_ex; cond_resched(); } wait->_qproc = NULL; if (retval || timed_out || signal_pending(current)) break; if (table.error) { retval = table.error; break; } if (can_busy_loop && !need_resched()) { if (!busy_start) { busy_start = busy_loop_current_time(); continue; } if (!busy_loop_timeout(busy_start)) continue; } busy_flag = 0; if (end_time && !to) { expire = timespec64_to_ktime(*end_time); to = &expire; } if (!poll_schedule_timeout(&table, TASK_INTERRUPTIBLE, to, slack)) timed_out = 1; } poll_freewait(&table); return retval; }
  • poll:do_sys_poll---》do_poll---linux-6.0.2\fs\select.c

    • static int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds,struct timespec64 *end_time)
      {
          ......
      	len = min_t(unsigned int, nfds, N_STACK_PPS);
      	for (;;) {
      	.....
              //copy_from_user从用户空间拷贝fds
      		if (copy_from_user(walk->entries, ufds + nfds-todo,
      					sizeof(struct pollfd) * walk->len))
      			goto out_fds;
      	.....
      	}
      	.....
      out_fds:
      	//没有拷贝成功
          .....
      	return err;
      	.....
      }
      
    • static int do_poll(struct poll_list *list, struct poll_wqueues *wait,struct timespec64 *end_time)
      {
      	......
          //poll底层处理流程
      	for (;;) {
      		struct poll_list *walk;
      		bool can_busy_loop = false;
      		//这个写法,似乎是链表
      		for (walk = list; walk != NULL; walk = walk->next) {
      			struct pollfd * pfd, * pfd_end;
      
      			pfd = walk->entries;
      			pfd_end = pfd + walk->len;
      			for (; pfd != pfd_end; pfd++) {
      				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;
      				}
      			}
      		}
      		pt->_qproc = NULL;
      		if (!count) {
      			count = wait->error;
      			if (signal_pending(current))
      				count = -ERESTARTNOHAND;
      		}
      		if (count || timed_out)
      			break;
      		if (can_busy_loop && !need_resched()) {
      			if (!busy_start) {
      				busy_start = busy_loop_current_time();
      				continue;
      			}
      			if (!busy_loop_timeout(busy_start))
      				continue;
      		}
      		busy_flag = 0;
      
      		if (end_time && !to) {
      			expire = timespec64_to_ktime(*end_time);
      			to = &expire;
      		}
      
      		if (!poll_schedule_timeout(wait, TASK_INTERRUPTIBLE, to, slack))
      			timed_out = 1;
      	}
      	return count;
      }
      
  • epoll:do_epoll_wait---》ep_poll--linux-6.0.2\fs\eventp

  • 首页 上一页 1 2 3 下一页 尾页 2/3/3
    】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
    上一篇Centos7配置webrtc-streamer环境 下一篇SRE:如何提高报警有效性?

    最新文章

    热门文章

    Hot 文章

    Python

    C 语言

    C++基础

    大数据基础

    linux编程基础

    C/C++面试题目