概述
近期,作为一个新手在研究input子系统的过程中,发现这么一句话list_for_each_entry(handler, &input_handler_list, node),当时也是在听一些课程,在input_register_device()函数中调用了list_for_each_entry(handler, &input_handler_list, node),说此处为遍历handler链表进行匹配,如下所示。
int input_register_device(struct input_dev *dev)
{
struct input_handler *handler;
...
//加入链表尾部
list_add_tail(&dev->node, &input_dev_list);
//遍历handler链表进行匹配
list_for_each_entry(handler, &input_handler_list, node)
input_attach_handler(dev, handler);
...
}
其中卡在了对于下属函数的分析:
list_for_each_entry(handler, &input_handler_list, node)
上述是个函数这句话就是错误的!,所以一开始一直分析不出handler这个局部变量一直没有赋值,那这个传参有什么意义呢?说是对链表进行遍历,然后遍历了一遍赋给handler的是什么呢?最后一个元素?那显然不合理呀!经过层层分析,网上查看blog,在一些小地方恍然大悟!
因为上一句话是一个宏,而且其最后是没有分号的!
那么现在将这个宏具体实例化看一下:
for (handler = container_of((&input_handler_list)->next, typeof(*handler), node);
&handler->node != (&input_handler_list);
handler = container_of(handler->node.next, typeof(*handler), node))
由于自己是个Linux驱动开发的新手,对这个像函数一样的东西愣是看了半天才反应过来这不是一个函数,应该结合下面一句话一起看才是这个注释的完整意义,下面我就把上述的低级错误重新整理一下,变成了下述代码:
for (handler = container_of((&input_handler_list)->next, typeof(*handler), node);
&handler->node != (&input_handler_list);
handler = container_of(handler->node.next, typeof(*handler), node)){
//调用了input_attach_handler()函数进行真正的匹配,上面的宏只是遍历的条件!
// input_attach_handler(dev, handler); 函数的具体实现如下:
const struct input_device_id *id;
int error;
//将当前的handler和dev进行匹配
id = input_match_device(handler, dev);
if (!id)
return -ENODEV;
//匹配成功后调用handler中的connect,实际调用了 evconnect
error = handler->connect(handler, dev, id);
if (error && error != -ENODEV)
pr_err("failed to attach handler %s to device %s, error: %dn",
handler->name, kobject_name(&dev->dev.kobj), error);
return error;
}
至此,对后续的分析才能够得以继续下去。
本文没有对一些细枝末节的知识点进行分析,如container_of宏等,只是从框架整体上,让大家能够分析得下去,而不至于在此产生迷惑,本文一些细节方面可以参考如下博客:
https://blog.csdn.net/xubin341719/article/details/7098611
https://blog.csdn.net/Richard_LiuJH/article/details/46325327
https://blog.csdn.net/qq_22863733/article/details/78175094
最后
以上就是整齐水壶为你收集整理的list_for_each_entry(handler, &input_handler_list, node)的理解的全部内容,希望文章能够帮你解决list_for_each_entry(handler, &input_handler_list, node)的理解所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复