summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHsin-Yu Chao <hychao@chromium.org>2018-10-01 11:55:39 +0800
committerchrome-bot <chrome-bot@chromium.org>2018-10-10 09:44:56 -0700
commit14327702091ee73622c2d54c70d8135233428465 (patch)
tree445cdbabe609e600ffdade63b15bfb4d8be1f558
parentab9af3b88c1692b5e3a722bde0dbe908f4a473ea (diff)
downloadadhd-14327702091ee73622c2d54c70d8135233428465.tar.gz
CRAS: iodev_list - Check if pinned device is open already
cras_iodev can be opened and accessed by audio_thread in two ways: (1) UI enables an input/output audio node. (2) An application creates a stream that pins to specific audio node. This change adds a function to ask if the given device is already in use by the audio_thread. It can be used to avoid unecessary calls and possible multi thread access to iodev. BUG=chromium:890242, chromium:863823 TEST=unittest Change-Id: I24713e15f1039599abd3387fbc1bbe2c490efff1 Reviewed-on: https://chromium-review.googlesource.com/1257487 Commit-Ready: Hsinyu Chao <hychao@chromium.org> Tested-by: Hsinyu Chao <hychao@chromium.org> Reviewed-by: Dylan Reid <dgreid@chromium.org>
-rw-r--r--cras/src/server/audio_thread.c32
-rw-r--r--cras/src/server/audio_thread.h8
-rw-r--r--cras/src/server/cras_iodev_list.c3
-rw-r--r--cras/src/tests/iodev_list_unittest.cc16
4 files changed, 59 insertions, 0 deletions
diff --git a/cras/src/server/audio_thread.c b/cras/src/server/audio_thread.c
index 8d53f1e3..7d208d88 100644
--- a/cras/src/server/audio_thread.c
+++ b/cras/src/server/audio_thread.c
@@ -38,6 +38,7 @@
enum AUDIO_THREAD_COMMAND {
AUDIO_THREAD_ADD_OPEN_DEV,
AUDIO_THREAD_RM_OPEN_DEV,
+ AUDIO_THREAD_IS_DEV_OPEN,
AUDIO_THREAD_ADD_STREAM,
AUDIO_THREAD_DISCONNECT_STREAM,
AUDIO_THREAD_STOP,
@@ -398,6 +399,18 @@ static int thread_rm_open_dev(struct audio_thread *thread,
return 0;
}
+/*
+ * Handles message from the main thread to check if an iodev is in the
+ * open dev list.
+ */
+static int thread_is_dev_open(struct audio_thread *thread,
+ struct cras_iodev *iodev)
+{
+ struct open_dev *adev = dev_io_find_open_dev(
+ thread->open_devs[iodev->direction], iodev);
+ return !!adev;
+}
+
/* Handles messages from the main thread to start ramping on a device. */
static int thread_dev_start_ramp(struct audio_thread *thread,
struct cras_iodev *iodev,
@@ -638,6 +651,13 @@ static int handle_playback_thread_message(struct audio_thread *thread)
ret = thread_rm_open_dev(thread, rmsg->dev);
break;
}
+ case AUDIO_THREAD_IS_DEV_OPEN: {
+ struct audio_thread_open_device_msg *rmsg;
+
+ rmsg = (struct audio_thread_open_device_msg *)msg;
+ ret = thread_is_dev_open(thread, rmsg->dev);
+ break;
+ }
case AUDIO_THREAD_STOP:
ret = 0;
err = audio_thread_send_response(thread, ret);
@@ -1256,6 +1276,18 @@ int audio_thread_rm_open_dev(struct audio_thread *thread,
return audio_thread_post_message(thread, &msg.header);
}
+int audio_thread_is_dev_open(struct audio_thread *thread,
+ struct cras_iodev *dev)
+{
+ struct audio_thread_open_device_msg msg;
+
+ if (!dev)
+ return 0;
+
+ init_open_device_msg(&msg, AUDIO_THREAD_IS_DEV_OPEN, dev);
+ return audio_thread_post_message(thread, &msg.header);
+}
+
int audio_thread_dev_start_ramp(struct audio_thread *thread,
struct cras_iodev *dev,
enum CRAS_IODEV_RAMP_REQUEST request)
diff --git a/cras/src/server/audio_thread.h b/cras/src/server/audio_thread.h
index adeadd6c..e2c0d725 100644
--- a/cras/src/server/audio_thread.h
+++ b/cras/src/server/audio_thread.h
@@ -74,6 +74,14 @@ int audio_thread_add_open_dev(struct audio_thread *thread,
int audio_thread_rm_open_dev(struct audio_thread *thread,
struct cras_iodev *dev);
+/* Checks if dev is open and used by audio thread.
+ * Args:
+ * thread - The thread accessing open devs.
+ * dev - The device to check if it has already been open.
+ */
+int audio_thread_is_dev_open(struct audio_thread *thread,
+ struct cras_iodev *dev);
+
/* Adds an thread_callback to audio thread.
* Args:
* fd - The file descriptor to be polled for the callback.
diff --git a/cras/src/server/cras_iodev_list.c b/cras/src/server/cras_iodev_list.c
index 02d58e07..2d5d5a50 100644
--- a/cras/src/server/cras_iodev_list.c
+++ b/cras/src/server/cras_iodev_list.c
@@ -683,6 +683,9 @@ static int init_pinned_device(struct cras_iodev *dev,
{
int rc;
+ if (audio_thread_is_dev_open(audio_thread, dev))
+ return 0;
+
/* Make sure the active node is configured properly, it could be
* disabled when last normal stream removed. */
dev->update_active_node(dev, dev->active_node->idx, 1);
diff --git a/cras/src/tests/iodev_list_unittest.cc b/cras/src/tests/iodev_list_unittest.cc
index f1e14649..5fb32aa3 100644
--- a/cras/src/tests/iodev_list_unittest.cc
+++ b/cras/src/tests/iodev_list_unittest.cc
@@ -36,6 +36,7 @@ static int audio_thread_set_active_dev_called;
static cras_iodev *audio_thread_add_open_dev_dev;
static int audio_thread_add_open_dev_called;
static int audio_thread_rm_open_dev_called;
+static int audio_thread_is_dev_open_ret;
static struct audio_thread thread;
static struct cras_iodev loopback_input;
static int cras_iodev_close_called;
@@ -114,6 +115,7 @@ class IoDevTestSuite : public testing::Test {
audio_thread_disconnect_stream_called = 0;
audio_thread_disconnect_stream_stream = NULL;
+ audio_thread_is_dev_open_ret = 0;
cras_iodev_has_pinned_stream_ret.clear();
sample_rates_[0] = 44100;
@@ -1374,6 +1376,14 @@ TEST_F(IoDevTestSuite, AddRemovePinnedStream) {
EXPECT_EQ(5, update_active_node_called);
// close pinned device
EXPECT_EQ(&d1_, update_active_node_iodev_val[4]);
+
+ // Assume dev is already opened, add pin stream should not trigger another
+ // update_active_node call, but will trigger audio_thread_add_stream.
+ audio_thread_is_dev_open_ret = 1;
+ EXPECT_EQ(0, stream_add_cb(&rstream));
+ EXPECT_EQ(5, update_active_node_called);
+ EXPECT_EQ(2, audio_thread_add_stream_called);
+
cras_iodev_list_deinit();
}
@@ -1574,6 +1584,12 @@ int audio_thread_rm_open_dev(struct audio_thread *thread,
return 0;
}
+int audio_thread_is_dev_open(struct audio_thread *thread,
+ struct cras_iodev *dev)
+{
+ return audio_thread_is_dev_open_ret;
+}
+
int audio_thread_add_stream(struct audio_thread *thread,
struct cras_rstream *stream,
struct cras_iodev **devs,