struct timer_list,计时器不会停止

时间:2013-11-15 13:08:29

标签: timer linux-kernel linux-device-driver

我遇到以下代码问题。 每当我调用ioctl REGISTER时,计时器就会启动,当它到期时,它调用“update”来调度使用工作队列的任务,doJob方法只是用新的到期时间更新计时器。

当我调用ioctl UNREGISTER时,计时器被终止...但它继续调用更新(从而更新其到期时间)。为什么定时器在调用ioctl UNREGISTER后没有停止?

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);

1 个答案:

答案 0 :(得分:2)

del_timer_sync()的{​​{3}}说:

Callers must prevent restarting of the timer, otherwise this function is meaningless.

换句话说,del_timer_sync()等待处理程序退出,但如果该处理程序重新安排计时器,那么下次它将很高兴再次运行。

您需要做的就是维护另一个变量timer_active。在启动计时器之前将其设置为true,在删除计时器之前将其设置为false。然后仅在timer_active为真时重新安排计时器。通过该订单,您可以确保在del_timer_sync()返回后不再运行计时器。

相关问题