diff options
author | Hsin-Yu Chao <hychao@chromium.org> | 2018-10-01 11:55:39 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-10-10 09:44:56 -0700 |
commit | 14327702091ee73622c2d54c70d8135233428465 (patch) | |
tree | 445cdbabe609e600ffdade63b15bfb4d8be1f558 | |
parent | ab9af3b88c1692b5e3a722bde0dbe908f4a473ea (diff) | |
download | adhd-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.c | 32 | ||||
-rw-r--r-- | cras/src/server/audio_thread.h | 8 | ||||
-rw-r--r-- | cras/src/server/cras_iodev_list.c | 3 | ||||
-rw-r--r-- | cras/src/tests/iodev_list_unittest.cc | 16 |
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, |