summaryrefslogtreecommitdiff
path: root/src/timer
diff options
context:
space:
mode:
authorJaroslav Kysela <perex@perex.cz>2005-05-11 12:18:51 +0000
committerJaroslav Kysela <perex@perex.cz>2005-05-11 12:18:51 +0000
commit8ec3e4ea6cdc57a63bbc91041a73392c0748400c (patch)
treec12f2e679d9227d411d391e2b636fe62cc47b6c1 /src/timer
parenta022bc1fbc6fa287bbdc969cdf969c10c39fe2a1 (diff)
downloadalsa-lib-8ec3e4ea6cdc57a63bbc91041a73392c0748400c.tar.gz
added full async interface to timer API
- added snd_async_add_timer_handler and snd_async_handler_get_timer functions - added async command to test/timer.c
Diffstat (limited to 'src/timer')
-rw-r--r--src/timer/timer.c53
-rw-r--r--src/timer/timer_hw.c1
-rw-r--r--src/timer/timer_local.h1
3 files changed, 55 insertions, 0 deletions
diff --git a/src/timer/timer.c b/src/timer/timer.c
index bb6125a2..7bd5838e 100644
--- a/src/timer/timer.c
+++ b/src/timer/timer.c
@@ -238,6 +238,10 @@ int snd_timer_close(snd_timer_t *timer)
{
int err;
assert(timer);
+ while (!list_empty(&timer->async_handlers)) {
+ snd_async_handler_t *h = list_entry(timer->async_handlers.next, snd_async_handler_t, hlist);
+ snd_async_del_handler(h);
+ }
if ((err = timer->ops->close(timer)) < 0)
return err;
if (timer->name)
@@ -274,6 +278,55 @@ snd_timer_type_t snd_timer_type(snd_timer_t *timer)
}
/**
+ * \brief Add an async handler for a timer
+ * \param handler Returned handler handle
+ * \param timer timer handle
+ * \param callback Callback function
+ * \param private_data Callback private data
+ * \return 0 otherwise a negative error code on failure
+ *
+ * The asynchronous callback is called when new timer event occurs.
+ */
+int snd_async_add_timer_handler(snd_async_handler_t **handler, snd_timer_t *timer,
+ snd_async_callback_t callback, void *private_data)
+{
+ int err;
+ int was_empty;
+ snd_async_handler_t *h;
+ err = snd_async_add_handler(&h, timer->poll_fd,
+ callback, private_data);
+ if (err < 0)
+ return err;
+ h->type = SND_ASYNC_HANDLER_TIMER;
+ h->u.timer = timer;
+ was_empty = list_empty(&timer->async_handlers);
+ list_add_tail(&h->hlist, &timer->async_handlers);
+ if (was_empty) {
+ err = snd_timer_async(timer, snd_async_handler_get_signo(h), getpid());
+ if (err < 0) {
+ snd_async_del_handler(h);
+ return err;
+ }
+ }
+ *handler = h;
+ return 0;
+}
+
+/**
+ * \brief Return timer handle related to an async handler
+ * \param handler Async handler handle
+ * \return timer handle
+ */
+snd_timer_t *snd_async_handler_get_timer(snd_async_handler_t *handler)
+{
+ if (handler->type != SND_ASYNC_HANDLER_TIMER) {
+ SNDMSG("invalid handler type %d", handler->type);
+ return NULL;
+ }
+ return handler->u.timer;
+}
+
+/**
* \brief get count of poll descriptors for timer handle
* \param timer timer handle
* \return count of poll descriptors
diff --git a/src/timer/timer_hw.c b/src/timer/timer_hw.c
index 2d5a92ee..4f64a616 100644
--- a/src/timer/timer_hw.c
+++ b/src/timer/timer_hw.c
@@ -265,6 +265,7 @@ int snd_timer_hw_open(snd_timer_t **handle, const char *name, int dev_class, int
tmr->name = strdup(name);
tmr->poll_fd = fd;
tmr->ops = &snd_timer_hw_ops;
+ INIT_LIST_HEAD(&tmr->async_handlers);
*handle = tmr;
return 0;
}
diff --git a/src/timer/timer_local.h b/src/timer/timer_local.h
index f11bce34..b4f064f3 100644
--- a/src/timer/timer_local.h
+++ b/src/timer/timer_local.h
@@ -45,6 +45,7 @@ struct _snd_timer {
int poll_fd;
snd_timer_ops_t *ops;
void *private_data;
+ struct list_head async_handlers;
};
int snd_timer_hw_open(snd_timer_t **handle, const char *name, int dev_class, int dev_sclass, int card, int device, int subdevice, int mode);