V4L/DVB (6279): en_50221: convert to kthread API
authorChristoph Hellwig <hch@infradead.org>
Wed, 3 Oct 2007 14:23:01 +0000 (11:23 -0300)
committerMauro Carvalho Chehab <mchehab@infradead.org>
Wed, 10 Oct 2007 03:03:08 +0000 (00:03 -0300)
Here's an attempted update to the full kthread API + wake_up_process:

Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
CC: Andrew de Quincey <adq_dvb@lidskialf.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
drivers/media/dvb/dvb-core/dvb_ca_en50221.c

index 5c7bcb8393d20d6dd618549cb2fc400930ea32e9..084a508a03da8e1202b01fd77ee6a8209fc2f729 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/delay.h>
 #include <linux/spinlock.h>
 #include <linux/sched.h>
+#include <linux/kthread.h>
 
 #include "dvb_ca_en50221.h"
 #include "dvb_ringbuffer.h"
@@ -139,13 +140,7 @@ struct dvb_ca_private {
        wait_queue_head_t wait_queue;
 
        /* PID of the monitoring thread */
-       pid_t thread_pid;
-
-       /* Wait queue used when shutting thread down */
-       wait_queue_head_t thread_queue;
-
-       /* Flag indicating when thread should exit */
-       unsigned int exit:1;
+       struct task_struct *thread;
 
        /* Flag indicating if the CA device is open */
        unsigned int open:1;
@@ -901,27 +896,9 @@ static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca)
 
        ca->wakeup = 1;
        mb();
-       wake_up_interruptible(&ca->thread_queue);
+       wake_up_process(ca->thread);
 }
 
-/**
- * Used by the CA thread to determine if an early wakeup is necessary
- *
- * @param ca CA instance.
- */
-static int dvb_ca_en50221_thread_should_wakeup(struct dvb_ca_private *ca)
-{
-       if (ca->wakeup) {
-               ca->wakeup = 0;
-               return 1;
-       }
-       if (ca->exit)
-               return 1;
-
-       return 0;
-}
-
-
 /**
  * Update the delay used by the thread.
  *
@@ -981,7 +958,6 @@ static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca)
 static int dvb_ca_en50221_thread(void *data)
 {
        struct dvb_ca_private *ca = data;
-       char name[15];
        int slot;
        int flags;
        int status;
@@ -990,28 +966,17 @@ static int dvb_ca_en50221_thread(void *data)
 
        dprintk("%s\n", __FUNCTION__);
 
-       /* setup kernel thread */
-       snprintf(name, sizeof(name), "kdvb-ca-%i:%i", ca->dvbdev->adapter->num, ca->dvbdev->id);
-
-       lock_kernel();
-       daemonize(name);
-       sigfillset(&current->blocked);
-       unlock_kernel();
-
        /* choose the correct initial delay */
        dvb_ca_en50221_thread_update_delay(ca);
 
        /* main loop */
-       while (!ca->exit) {
+       while (!kthread_should_stop()) {
                /* sleep for a bit */
-               if (!ca->wakeup) {
-                       flags = wait_event_interruptible_timeout(ca->thread_queue,
-                                                                dvb_ca_en50221_thread_should_wakeup(ca),
-                                                                ca->delay);
-                       if ((flags == -ERESTARTSYS) || ca->exit) {
-                               /* got signal or quitting */
-                               break;
-                       }
+               while (!ca->wakeup) {
+                       set_current_state(TASK_INTERRUPTIBLE);
+                       schedule_timeout(ca->delay);
+                       if (kthread_should_stop())
+                               return 0;
                }
                ca->wakeup = 0;
 
@@ -1180,10 +1145,6 @@ static int dvb_ca_en50221_thread(void *data)
                }
        }
 
-       /* completed */
-       ca->thread_pid = 0;
-       mb();
-       wake_up_interruptible(&ca->thread_queue);
        return 0;
 }
 
@@ -1683,9 +1644,6 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
                goto error;
        }
        init_waitqueue_head(&ca->wait_queue);
-       ca->thread_pid = 0;
-       init_waitqueue_head(&ca->thread_queue);
-       ca->exit = 0;
        ca->open = 0;
        ca->wakeup = 0;
        ca->next_read_slot = 0;
@@ -1711,14 +1669,14 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
        mb();
 
        /* create a kthread for monitoring this CA device */
-
-       ret = kernel_thread(dvb_ca_en50221_thread, ca, 0);
-
-       if (ret < 0) {
-               printk("dvb_ca_init: failed to start kernel_thread (%d)\n", ret);
+       ca->thread = kthread_run(dvb_ca_en50221_thread, ca, "kdvb-ca-%i:%i",
+                                ca->dvbdev->adapter->num, ca->dvbdev->id);
+       if (IS_ERR(ca->thread)) {
+               ret = PTR_ERR(ca->thread);
+               printk("dvb_ca_init: failed to start kernel_thread (%d)\n",
+                       ret);
                goto error;
        }
-       ca->thread_pid = ret;
        return 0;
 
 error:
@@ -1749,17 +1707,7 @@ void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca)
        dprintk("%s\n", __FUNCTION__);
 
        /* shutdown the thread if there was one */
-       if (ca->thread_pid) {
-               if (kill_proc(ca->thread_pid, 0, 1) == -ESRCH) {
-                       printk("dvb_ca_release adapter %d: thread PID %d already died\n",
-                              ca->dvbdev->adapter->num, ca->thread_pid);
-               } else {
-                       ca->exit = 1;
-                       mb();
-                       dvb_ca_en50221_thread_wakeup(ca);
-                       wait_event_interruptible(ca->thread_queue, ca->thread_pid == 0);
-               }
-       }
+       kthread_stop(ca->thread);
 
        for (i = 0; i < ca->slot_count; i++) {
                dvb_ca_en50221_slot_shutdown(ca, i);