linux tty core 源码分析(6)

使用非阻塞的IO应用程序常调用select类函数,允许进程决定是否可以对一个或多个打开的文件进行非阻塞的读取或者写入

该功能的实现就要下面tty_poll操作来实现的。该功能的函数实现有一个关键的数据结构poll_table和一个关键的函数poll_wait

对该结构和函数这里不深入解析只知道其功能即可

/**
 * tty_poll - check tty status
 * @filp: file being polled
 * @wait: poll wait structures to update
 *
 * Call the line discipline polling method to obtain the poll
 * status of the device.
 *
 * Locking: locks called line discipline but ldisc poll method
 * may be re-entered freely by other callers.
 */

//tty_poll功能的实现主要在线路规程ldisc->poll中实现即normal_poll函数

static unsigned int tty_poll(struct file *filp, poll_table *wait)
{
 struct tty_struct *tty;
 struct tty_ldisc *ld;
 int ret = 0;

 tty = (struct tty_struct *)filp->private_data;
 if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_poll"))
  return 0;

 ld = tty_ldisc_ref_wait(tty);
 if (ld->ops->poll)
  ret = (ld->ops->poll)(tty, filp, wait); //调用normal_poll函数
 tty_ldisc_deref(ld);
 return ret;
}

 

poll方法的实现主要完成两步操作:

1)在一个或多个指示poll状态变化的等待队列上调用poll_wait.poll_wait增加一个等待队列到poll_table结构

如果没有可执行的文件IO则内核将进程在传递到该系统调用的所有文件描述符对应的等待队列上等待。

2)返回一个用来描述操作的是否可以立即执行的位掩码

/**
 * normal_poll  - poll method for N_TTY
 * @tty: terminal device
 * @file: file accessing it
 * @wait: poll table
 *
 * Called when the line discipline is asked to poll() for data or
 * for special events. This code is not serialized with respect to
 * other events save open/close.
 *
 * This code must be sure never to sleep through a hangup.
 * Called without the kernel lock held - fine
 */

static unsigned int normal_poll(struct tty_struct *tty, struct file *file,
       poll_table *wait)
{
 unsigned int mask = 0;

 poll_wait(file, &tty->read_wait, wait);  //增加一个等待队列到poll_table结构
 poll_wait(file, &tty->write_wait, wait);

 

//POLLIN  设备可不阻塞地读
//POLLRDNORM  可以读"正常"数据. 一个可读的设备返回( POLLIN|POLLRDNORM ).
 if (input_available_p(tty, TIME_CHAR(tty) ? 0 : MIN_CHAR(tty)))
  mask |= POLLIN | POLLRDNORM;

//POLLPRI 可不阻塞地读取高优先级数据(带外). 控制模式数据
 if (tty->packet && tty->link->ctrl_status)
  mask |= POLLPRI | POLLIN | POLLRDNORM;

//POLLHUP 当读这个设备的进程见到文件尾, 驱动必须设置POLLUP(hang-up). 
 if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
  mask |= POLLHUP;
 if (tty_hung_up_p(file))
  mask |= POLLHUP;

//唤醒tty读的最小值设置
 if (!(mask & (POLLHUP | POLLIN | POLLRDNORM))) {
  if (MIN_CHAR(tty) && !TIME_CHAR(tty))
   tty->minimum_to_wake = MIN_CHAR(tty);
  else
   tty->minimum_to_wake = 1;
 }

//POLLOUT 设备可被写入而不阻塞.
//POLLWRNORM 这个位和POLLOUT有相同的含义, 并且有时它确实是相同的数. 一个可写的设备返回( POLLOUT|POLLWRNORM).
 if (tty->ops->write && !tty_is_writelocked(tty) &&
   tty_chars_in_buffer(tty) < WAKEUP_CHARS &&
   tty_write_room(tty) > 0)
  mask |= POLLOUT | POLLWRNORM;
 return mask;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值