linux notify 通知在TP中的应用

xiaoxiao2021-02-28  117

通过对tp中代码的分析来解读一下notifier如何应用。 Mtk_tpd.c中代码:

static struct notifier_block tpd_fb_notifier;//定义一个notifier_block static int tpd_fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data) {}//定义填充回调函数 tpd_fb_notifier.notifier_call = tpd_fb_notifier_callback;//将定义的notifier_block中的结构体成员指向回调函数 if (fb_register_client(&tpd_fb_notifier))//注册自定义的notifier_block

这也就是使用 notify 系统所需要的四个步骤 定义一个 notifier_block:tpd_fb_notifier,这是一个结构体,结构体成员为:

struct notifier_block { int (*notifier_call)(struct notifier_block *, unsigned long, void *); struct notifier_block __rcu *next; int priority; };

第一个成员变量是一个回调函数; 上述步骤中可以看到在第二步中定义了一个函数,并在第三步中赋给了 tpd_fb_notifier. notifier_call 这一结构体成员; 第二个成员是指向下一个 notifier_block,第三个是这个 notifier_block 的优先级,数值越大,优先级越高 然后将 notifier_block:tpd_fb_notifier 注册起来,注册到哪里?我们分析代码: fb_notify.c 中:

int fb_register_client(struct notifier_block *nb) { return blocking_notifier_chain_register(&fb_notifier_list, nb); }

将参数中的 notify_block 注册到 fb_notifier_list 链表中 fb_notifier_list 又是什么?

static BLOCKING_NOTIFIER_HEAD(fb_notifier_list);

是一个通知链的头部节点(这个通知链的类型是 blocking_notifier_chain,还有其他的三种通知链类型,可以百度),通过这个头部节点可以遍历到注册在这个通知链中的其他所有 notify_block

那么定义注册完这些个东西有什么用呢? 在 fb_notify.c 中还定义了一个函数:

int fb_notifier_call_chain(unsigned long val, void *v) { return blocking_notifier_call_chain(&fb_notifier_list, val, v); }

当调用这个函数的时候,通知 fb_notifier_list 链表中所注册的所有 notify_block 执行相应的结构体成员notifier_call,即执行链表上的所有 notify_block 的 callback 函数;这样就达到一个目的:调用这个函数之后就可以执行到我们自定义的函数,执行我们想要的功能; 我们再看这个函数的实现: Notifier.c

int blocking_notifier_call_chain(struct blocking_notifier_head *nh, unsigned long val, void *v) { return __blocking_notifier_call_chain(nh, val, v, -1, NULL); } static int notifier_call_chain(struct notifier_block **nl, unsigned long val, void *v, int nr_to_call, int *nr_calls) { …… ret = nb->notifier_call(nb, val, v); //这句话就是执行这个notify_block的 call 函数,这个函数有三个参数,第一个是 notify_block 自身,val和 v 是要传送的数据,val 是一个无符号 long 型,v 是一个空指针,可以指向任何数据类型(指针真是个好东西) …… }

上述 notifier_call(nb, val, v) ;对应一个实际的函数例子是

tpd_fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data) val = event;v = data

可是这里有一个问题,网上相关博客说:当有事件触发时,通知者调用 notifier_call_chain 函数通知事件的到达,这个函数会遍历 nl 指向的通知链中所有的元素,然后依次调用每一个的回调函数,完成通知动作。 我觉得不是太可能吧,这样的话岂不是执行了多余的函数?!一定是哪里还有判断我没有找到,这个问题后面一定要搞清楚。

流程图:

推荐文章:内核通知链 学习笔记 notifier chain — 内核通知链

转载请注明原文地址: https://www.6miu.com/read-63338.html

最新回复(0)