您的位置:首页 > 运维架构 > Linux

linux驱动之异步通知

2015-07-05 17:11 621 查看
异步通知

为了启动文件的异步通知机制,用户程序需要执行两个步骤:

1 fcntl(int fd, F_SETOWN, getpid()); //设置接受SIGIO和SIGURG的进程,如果getpid()为负表示以该值绝对值为值的进程组,其实就是对filp->f_owner赋值

signal(SIGIO, button_signal_function);//接收到SIGIO信号时,调用button_signal_function函数

2 flag |= FASYNC;

fcntl(fd, F_SETFL, flag);//设置文件状态标志,只有设置了FASYNC标志,才能启动异步通知,调用内核的fasync函数

驱动程序要使用的函数

int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fapp)

{

if (!on)

return fasync_remove_entry(filp, fapp);

return fasync_add_entry(fd, filp, fapp);

}

fasync_struct结构体如下

struct fasync_struct {

spinlock_t fa_lock;

int magic;

int fa_fd;

struct fasync_struct *fa_next; /* singly linked list */

struct file *fa_file;

struct rcu_head fa_rcu;

};

static int fasync_add_entry(int fd, struct file *filp, struct fasync_struct **fapp)

{

struct fasync_struct *new;

new = fasync_alloc();

if (!new)

return -ENOMEM;

/*

* fasync_insert_entry() returns the old (update) entry if

* it existed.

*

* So free the (unused) new entry and return 0 to let the

* caller know that we didn't add any new fasync entries.

*/

if (fasync_insert_entry(fd, filp, fapp, new)) {

fasync_free(new);

return 0;

}

return 1;

}

主要是调用fasync_insert_entry函数

struct fasync_struct *fasync_insert_entry(int fd, struct file *filp, struct fasync_struct **fapp, struct fasync_struct *new)

{

struct fasync_struct *fa, **fp;

spin_lock(&filp->f_lock);

spin_lock(&fasync_lock);

for (fp = fapp; (fa = *fp) != NULL; fp = &fa->fa_next) {

if (fa->fa_file != filp)

continue;

spin_lock_irq(&fa->fa_lock);

fa->fa_fd = fd;

spin_unlock_irq(&fa->fa_lock);

goto out;

}

spin_lock_init(&new->fa_lock);

new->magic = FASYNC_MAGIC;

new->fa_file = filp;

new->fa_fd = fd;

new->fa_next = *fapp;

rcu_assign_pointer(*fapp, new);

filp->f_flags |= FASYNC;

out:

spin_unlock(&fasync_lock);

spin_unlock(&filp->f_lock);

return fa;

}

该函数在链表中查找是否存在指定的filp,如果存在将该fasync_struct对应的fa_fd替换成新的fd,如果不存在该filp,则添加新的fasync_struct结构体,并以指定的filp,fd等初始化,添加到链表的末尾。

当指定的事件发生时,内核使用kill_fasync函数通知应用程序
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: