다음 코드에 문제가 있습니다. ioctl REGISTER를 호출 할 때마다 타이머가 시작되고 만료되면 작업 큐를 사용하여 작업을 예약하는 "update"를 호출합니다. doJob 메서드는 새 만료 타이머를 간단히 업데이트합니다.struct timer_list, 타이머가 중지되지 않습니다
ioctl UNREGISTER를 호출하면 타이머가 종료되지만 ... 업데이트를 계속 호출하므로 만료 날짜가 업데이트됩니다. ioctl UNREGISTER를 호출 한 후 타이머가 멈추지 않는 이유는 무엇입니까?
Callers must prevent restarting of the timer, otherwise this function is meaningless.
즉
, 핸들러가 종료 할 del_timer_sync()
대기,하지만 핸들러가 타이머를 다시 예약하는 경우, 다음 행복하게 다시 다음을 실행합니다 :
int time = 1;
module_param(time, int, 0644);
int delay;
struct workqueue_struct* wq;
struct work_struct task;
struct timer_list timer; /* timer */
long ioctl(struct file *filp, unsigned int cmd, unsigned long args) {
switch (cmd) {
case REGISTER:
add_timer(&timer);
return 0;
case UNREGISTER:
del_timer_sync(&timer);
return 0;
}
}
static void doJob(struct work_struct *work) {
printk(KERN_EMERG "\ndoJob\n");
mod_timer(&timer, jiffies + delay);
}
void update(unsigned long arg) {
queue_work(wq, &task);
}
struct file_operations fop = {
.owner = THIS_MODULE,
.unlocked_ioctl = ioctl
};
static struct miscdevice dev = {
.minor = MISC_DYNAMIC_MINOR,
.name = "timer",
.fops = &fop
};
static int __init init(void)
{
delay = HZ * time/1000;
if (delay < 1) {
printk(KERN_EMERG "time param is too small\n");
return -1;
}
init_timer(&timer);
timer.data = 0;
timer.function = update;
timer.expires = jiffies + delay;
if (misc_register(&dev) < 0) {
printk(KERN_EMERG "error registering misc device\n");
return -1;
}
wq = create_workqueue("timer_task");
INIT_WORK(&task, doJob);
return 0;
}
static void __exit fini(void)
{
misc_deregister(&dev);
printk(KERN_EMERG "deregistered\n");
}
module_init(init);
module_exit(fini);