You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
都会过期,我开始怀疑,在这个世界上,还有什么东西是不会过期的?<br />
有时候我也被这个问题所困扰,我不知道是我不明白还是这世界变化太快.连Linux 中都引入了过期这么<br />
一个概念.说文雅一点就是超时.设置一个时间,如果时间到了该做的事情还没有做完,那么某些事情就会发<br />
生.<br />
83<br />
比如,咱们需要做这样一些事情,定个闹钟,比如咱们需要烤蛋糕,现在是8点30,而咱们要烤45分钟,所以<br />
咱们希望闹钟9 点一刻响,然后当时间到了,闹钟就如咱们期待的一样,响个不停.在计算机中,咱们也需要做<br />
这样的事情,有些事情,咱们需要时间控制,特别是网络,通信,等等,凡是涉及数据传输的事儿,就得考虑超时,<br />
换句话说,定个闹钟,你要是在这个给定的时间里还没做好你该做的事情,那么停下来,别做了,肯定有问题,<br />
比如,咱们如果烤蛋糕45 分钟,发现蛋糕一点香味都没有,颜色也没变,那肯定有问题,别烤了,先检查一下烤<br />
箱是不是坏了,是不是停电了,等等.而具体到咱们这里,需要用一个闹钟,或者叫专业一点,定时器,如果时间<br />
到了,就执行某个函数,这个功能Linux 内核的时间机制已经实现了,咱们只需要按"说明书"调用相应的接<br />
口<br />
函数即可.看代码,190 行,如果timeout>0,也就是说需要设置闹钟,那么首先需要定义一个struct<br />
timer_list 结构体的变量,咱们这里定义的变量叫做to_timer(在usb_stor_msg_common 一开始就定<br />
义了的),然后用init_timer()函数和add_timer()函数来真正实现设置闹钟,init_timer()是初始化,然后<br />
设置好之后调用add_timer 才能让闹钟生效.具体怎么设置的呢?在add_timer()之前,为<br />
to_timer.expires 赋值为jiffies+timeout,to_timer.function 赋值为<br />
timeout_handler,to_timer.data 赋值为us.这表示,超时时间点为当前时间加上一个<br />
timeout,(jiffies,Linux 内核中赫赫有名的全局变量,表示当前时间),timeout 咱们前面调用<br />
usb_stor_msg_common 的时候给设置成了HZ,也就是1 秒.当时间到了之后,timeout_handler 函数<br />
会被执行,而us 作为参数传递给她.不妨来看一下timeout_handler 函数吧,她定义于<br />
drivers/usb/storage/transport.c 中:<br />
119 /* This is the timeout handler which will cancel an URB when its timeout<br />
120 * expires.<br />
121 */<br />
122 static void timeout_handler(unsigned long us_)<br />
123 {<br />
124 struct us_data *us = (struct us_data *) us_;<br />
125<br />
126 if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->flags)) {<br />
127 US_DEBUGP("Timeout -- cancelling URB\n");<br />
128 usb_unlink_urb(us->current_urb);<br />
129 }<br />
130 }<br />
看得出,其实也没做什么,就是清除US_FLIDX_URB_ACTIVE flag,然后调用usb_unlink_urb()函数<br />
撤销当前这个urb.还记得刚才说的那个同步异步了吗?这正是刚才说的那个异步的情形,显然此刻这个函数<br />
不能睡眠,否则整个driver 就挂了...<br />
紧接着,199 行,非常重要的一句wait_for_completion(&urb_done),这句话会使本进程进入睡眠.别<br />
忘了刚才我们那句init_completion(&urb_done),urb_done 是一个struct completion 结构体变量,<br />
这个定义在usb_stor_msg_common()函数的第一行就出现了.显然completion 是Linux 中同步机制<br />
的一个很重要的结构体.与wait_for_completion 对应的一个函数是complete().其用法和作用是这样<br />
的:<br />
首先我们要用init_completion 初始化一个struct completion 的结构体变量,然后调用