FASYNC) 函数,下面的函数原型可以根据 class="cnblogs_code">mode
值配置
class="ds-markdown-paragraph">如果
mode
fasync_struct,将其插入链表
class="ds-markdown-paragraph">如果
mode
class="ds-markdown-paragraph">返回
0
fapp。
该函数可以完成fapp变量的初始化
style="color:
class="ds-markdown-paragraph">kill_fasync
用于遍历指定的异步通知链表,向链表中每个条目所代表的进程发送信号。
它会:
class="ds-markdown-paragraph">遍历
*fapp
fasync_struct
class="ds-markdown-paragraph">根据条目中保存的进程信息(fa_file->f_owner)确定目标进程
class="ds-markdown-paragraph">调用
发送信号,并附带
POLL_IN(可读)、POLL_OUT(可写)、POLL_ERR(错误)。
这些值与
poll
<linux/errno.h>style="color:
<linux/sched.h>style="color:
<linux/module.h>style="color:
<linux/ioctl.h>style="color:
<linux/cdev.h>style="color:
<linux/uaccess.h>style="color:
<linux/slab.h>style="color:
<linux/wait.h>style="color:
m_cdev);filp
->private_data
=1.将等待队列加入到等待队列头
add_wait_queue(&dev->r_wait,&2.循环检查等待条件(防止假唤醒,如果唤醒后不满足条件会再次睡眠)
style="color:
1)">EAGAIN;up(
&dev->style="color:
1)">sem);remove_wait_queue(
&dev->w_wait,&1)">wait);set_current_state(TASK_RUNNING);
style="color:
__set_current_state(TASK_INTERRUPTIBLE);up(
&dev->style="color:
6.检查如果有信号到达返回上层处理错误(自己的唤醒只将状态转换为TASK_RUNNING,但信号到来也会做这个处理)
style="color:
1)">ERESTARTSYS;remove_wait_queue(
&dev->w_wait,&1)">wait);set_current_state(TASK_RUNNING);
style="color:
被唤醒后的处理
down(&dev->style="color:
1)">if
(copy_to_user(buf,dev->1)">EFAULT;up(
&dev->style="color:
1)">sem);remove_wait_queue(
&dev->w_wait,&1)">wait);set_current_state(TASK_RUNNING);
style="color:
count);dev
->current_len-=count;wake_up_interruptible(
&dev->w_wait);count;}up(
&dev->style="color:
1)">sem);remove_wait_queue(
&dev->w_wait,&1)">wait);set_current_state(TASK_RUNNING);
style="color:
current);down(
&dev->style="color:
1.将等待队列插入写等待队列头
add_wait_queue(&dev->w_wait,&1)">EAGAIN;remove_wait_queue(
&dev->w_wait,&1)">wait);set_current_state(TASK_RUNNING);
style="color:
__set_current_state(TASK_INTERRUPTIBLE);up(
&dev->style="color:
6.若因为信号唤醒,则返回让上层完成错误处理
style="color:
1)">ERESTARTSYS;remove_wait_queue(
&dev->w_wait,&1)">wait);set_current_state(TASK_RUNNING);
style="color:
ret;}down(
&dev->style="color:
1)">EFAULT;up(
&dev->style="color:
1)">sem);remove_wait_queue(
&dev->w_wait,&1)">wait);set_current_state(TASK_RUNNING);
style="color:
唤醒等待队列
wake_up_interruptible(&dev->style="color:
1)">async_queue)kill_fasync(
&dev->style="color:
1)">sem);remove_wait_queue(
&dev->w_wait,&1)">wait);set_current_state(TASK_RUNNING);
style="color:
globalfifo_unlocked_ioctl(style="color:
MEM_CLEAR:down(
&dev->style="color:
1)">sem);dev
->current_len
1)">;memset(dev
->mem,GLOBALFIFO_SIZE);up(
&dev->style="color:
{globalfifo_fasync(
-style="color:
globalmem_write,.unlocked_ioctl
=内核中注册字符设备编号范围
register_chrdev_region(MKDEV(globalfifo_major,为设备以及共享内存分配内存
globalfifo_devpkmalloc(GFP_KERNEL);memset(globalfifo_devp,
初始化字符设备0的基本字段
cdev_init(&globalfifo_devp->m_cdev,&1)">globalfifo_fops);globalfifo_devp
->m_cdev.owner=将主设备号globalfifo_major次设备号0,与字符设备驱动的关联
cdev_add(&globalfifo_devp->m_cdev,初始化信号量
sema_init(&globalfifo_devp->sem,初始化读写等待队列头
init_waitqueue_head(&globalfifo_devp->style="color:
1)">r_wait);init_waitqueue_head(
&globalfifo_devp->style="color:
注销cdev
cdev_del(&globalfifo_devp->style="color:
1)">);unregister_chrdev_region(devno,
1)">);module_param(globalfifo_major,
module_exit(globalmem_exit);