ALSA: timer: Introduce disconnect op to snd_timer_instance
authorTakashi Iwai <tiwai@suse.de>
Thu, 21 Jan 2016 16:43:08 +0000 (17:43 +0100)
committerTakashi Iwai <tiwai@suse.de>
Thu, 21 Jan 2016 16:51:42 +0000 (17:51 +0100)
Instead of the previous ugly hack, introduce a new op, disconnect, to
snd_timer_instance object for handling the wake up of pending tasks
more cleanly.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=109431
Signed-off-by: Takashi Iwai <tiwai@suse.de>
include/sound/timer.h
sound/core/timer.c

index 7990469a44ce3df7909bdd447cd743019f900f37..c4d76ff056c6efd3431a4ed7aa3c6f6888c69e80 100644 (file)
@@ -104,6 +104,7 @@ struct snd_timer_instance {
                           int event,
                           struct timespec * tstamp,
                           unsigned long resolution);
+       void (*disconnect)(struct snd_timer_instance *timeri);
        void *callback_data;
        unsigned long ticks;            /* auto-load ticks when expired */
        unsigned long cticks;           /* current ticks */
index 681fb051b9ebe3b56aa7cf53e1aff8c2416f1888..af1f68f7e315334202f191e3f049f044de9495f7 100644 (file)
@@ -899,11 +899,6 @@ static int snd_timer_dev_register(struct snd_device *dev)
        return 0;
 }
 
-/* just for reference in snd_timer_dev_disconnect() below */
-static void snd_timer_user_ccallback(struct snd_timer_instance *timeri,
-                                    int event, struct timespec *tstamp,
-                                    unsigned long resolution);
-
 static int snd_timer_dev_disconnect(struct snd_device *device)
 {
        struct snd_timer *timer = device->device_data;
@@ -913,13 +908,8 @@ static int snd_timer_dev_disconnect(struct snd_device *device)
        list_del_init(&timer->device_list);
        /* wake up pending sleepers */
        list_for_each_entry(ti, &timer->open_list_head, open_list) {
-               /* FIXME: better to have a ti.disconnect() op */
-               if (ti->ccallback == snd_timer_user_ccallback) {
-                       struct snd_timer_user *tu = ti->callback_data;
-
-                       tu->disconnected = true;
-                       wake_up(&tu->qchange_sleep);
-               }
+               if (ti->disconnect)
+                       ti->disconnect(ti);
        }
        mutex_unlock(&register_mutex);
        return 0;
@@ -1227,6 +1217,14 @@ static void snd_timer_user_ccallback(struct snd_timer_instance *timeri,
        wake_up(&tu->qchange_sleep);
 }
 
+static void snd_timer_user_disconnect(struct snd_timer_instance *timeri)
+{
+       struct snd_timer_user *tu = timeri->callback_data;
+
+       tu->disconnected = true;
+       wake_up(&tu->qchange_sleep);
+}
+
 static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri,
                                      unsigned long resolution,
                                      unsigned long ticks)
@@ -1600,6 +1598,7 @@ static int snd_timer_user_tselect(struct file *file,
                        ? snd_timer_user_tinterrupt : snd_timer_user_interrupt;
                tu->timeri->ccallback = snd_timer_user_ccallback;
                tu->timeri->callback_data = (void *)tu;
+               tu->timeri->disconnect = snd_timer_user_disconnect;
        }
 
       __err: