summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHsin-Yu Chao <hychao@chromium.org>2020-05-14 06:46:41 +0000
committerCommit Bot <commit-bot@chromium.org>2020-05-21 06:36:02 +0000
commit6802b1ded3ddf553ce43f44dddf9662ac916b2d3 (patch)
tree6d73ddd003de8e26d45e3622d8b2e2950f454e30
parentc7d8b53492e5dbcff7f71f39df65a8d1fffdf6b1 (diff)
downloadadhd-6802b1ded3ddf553ce43f44dddf9662ac916b2d3.tar.gz
CRAS: server - Allow client callback to poll arbitrary events
Bluetooth HFP service level connection runs on rfcomm socket, and there are events when remote side hangs up and we fail to catch that. Fix this by allowing client callback be registerd to main thread with arbitrary poll events. BUG=b:155279795 TEST=Manual test HFP qualification test case HFP/AG/SDP/BV-01-I Change-Id: Ib5e36798d0e39aa5d921bee25e8fb6bf1e5f6a76 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/adhd/+/2198854 Tested-by: Hsinyu Chao <hychao@chromium.org> Reviewed-by: Hsinyu Chao <hychao@chromium.org> Commit-Queue: Hsinyu Chao <hychao@chromium.org>
-rw-r--r--cras/src/server/cras_alsa_card.c4
-rw-r--r--cras/src/server/cras_alsa_jack.c6
-rw-r--r--cras/src/server/cras_dbus.c5
-rw-r--r--cras/src/server/cras_hfp_slc.c7
-rw-r--r--cras/src/server/cras_main_message.c5
-rw-r--r--cras/src/server/cras_server.c20
-rw-r--r--cras/src/server/cras_system_state.c15
-rw-r--r--cras/src/server/cras_system_state.h9
-rw-r--r--cras/src/server/cras_udev.c7
-rw-r--r--cras/src/tests/system_state_unittest.cc17
10 files changed, 55 insertions, 40 deletions
diff --git a/cras/src/server/cras_alsa_card.c b/cras/src/server/cras_alsa_card.c
index a868c372..7c9dd59b 100644
--- a/cras/src/server/cras_alsa_card.c
+++ b/cras/src/server/cras_alsa_card.c
@@ -171,7 +171,7 @@ static struct mixer_name *filter_controls(struct cras_use_case_mgr *ucm,
/* Handles notifications from alsa controls. Called by main thread when a poll
* fd provided by alsa signals there is an event available. */
-static void alsa_control_event_pending(void *arg)
+static void alsa_control_event_pending(void *arg, int revent)
{
struct cras_alsa_card *card;
@@ -573,7 +573,7 @@ struct cras_alsa_card *cras_alsa_card_create(
DL_APPEND(alsa_card->hctl_poll_fds, registered_fd);
rc = cras_system_add_select_fd(
registered_fd->fd, alsa_control_event_pending,
- alsa_card);
+ alsa_card, POLLIN);
if (rc < 0) {
DL_DELETE(alsa_card->hctl_poll_fds,
registered_fd);
diff --git a/cras/src/server/cras_alsa_jack.c b/cras/src/server/cras_alsa_jack.c
index 6a1a1c37..58e5366a 100644
--- a/cras/src/server/cras_alsa_jack.c
+++ b/cras/src/server/cras_alsa_jack.c
@@ -380,7 +380,7 @@ static void display_info_delay_cb(struct cras_timer *timer, void *arg)
* file has data to read. Perform autoswitching to / from the
* associated device when data is available.
*/
-static void gpio_switch_callback(void *arg)
+static void gpio_switch_callback(void *arg, int events)
{
struct cras_alsa_jack *jack = arg;
int i;
@@ -503,8 +503,8 @@ static int cras_complete_gpio_jack(struct gpio_switch_list_data *data,
cras_free_jack(jack, 0);
return -EIO;
}
- r = cras_system_add_select_fd(jack->gpio.fd, gpio_switch_callback,
- jack);
+ r = cras_system_add_select_fd(jack->gpio.fd, gpio_switch_callback, jack,
+ POLLIN);
if (r < 0) {
/* Not yet registered with system select. */
cras_free_jack(jack, 0);
diff --git a/cras/src/server/cras_dbus.c b/cras/src/server/cras_dbus.c
index d127485d..5975f1c6 100644
--- a/cras/src/server/cras_dbus.c
+++ b/cras/src/server/cras_dbus.c
@@ -15,7 +15,7 @@
#include "cras_system_state.h"
#include "cras_tm.h"
-static void dbus_watch_callback(void *arg)
+static void dbus_watch_callback(void *arg, int revents)
{
DBusWatch *watch = (DBusWatch *)arg;
int r, flags;
@@ -48,7 +48,8 @@ static dbus_bool_t dbus_watch_add(DBusWatch *watch, void *data)
*/
if ((flags & DBUS_WATCH_READABLE) && dbus_watch_get_enabled(watch)) {
r = cras_system_add_select_fd(dbus_watch_get_unix_fd(watch),
- dbus_watch_callback, watch);
+ dbus_watch_callback, watch,
+ POLLIN);
if (r != 0)
return FALSE;
}
diff --git a/cras/src/server/cras_hfp_slc.c b/cras/src/server/cras_hfp_slc.c
index 62abb72d..8a8ba048 100644
--- a/cras/src/server/cras_hfp_slc.c
+++ b/cras/src/server/cras_hfp_slc.c
@@ -1021,7 +1021,7 @@ static int process_at_commands(struct hfp_slc_handle *handle)
return bytes_read;
}
-static void slc_watch_callback(void *arg)
+static void slc_watch_callback(void *arg, int revents)
{
struct hfp_slc_handle *handle = (struct hfp_slc_handle *)arg;
int err;
@@ -1030,6 +1030,7 @@ static void slc_watch_callback(void *arg)
if (err < 0) {
syslog(LOG_ERR, "Error reading slc command %s",
strerror(errno));
+ cras_system_rm_select_fd(handle->rfcomm_fd);
handle->disconnect_cb(handle);
}
return;
@@ -1069,8 +1070,8 @@ struct hfp_slc_handle *hfp_slc_create(int fd, int is_hsp,
handle->selected_codec = HFP_CODEC_UNUSED;
handle->hf_supports_battery_indicator = CRAS_HFP_BATTERY_INDICATOR_NONE;
handle->hf_battery = -1;
- cras_system_add_select_fd(handle->rfcomm_fd, slc_watch_callback,
- handle);
+ cras_system_add_select_fd(handle->rfcomm_fd, slc_watch_callback, handle,
+ POLLIN | POLLERR | POLLHUP);
return handle;
}
diff --git a/cras/src/server/cras_main_message.c b/cras/src/server/cras_main_message.c
index 9fe62afb..b88e4000 100644
--- a/cras/src/server/cras_main_message.c
+++ b/cras/src/server/cras_main_message.c
@@ -77,7 +77,7 @@ static int read_main_message(int msg_fd, uint8_t *buf, size_t max_len)
return 0;
}
-static void handle_main_messages(void *arg)
+static void handle_main_messages(void *arg, int revents)
{
uint8_t buf[256];
int rc;
@@ -112,5 +112,6 @@ void cras_main_message_init()
cras_make_fd_nonblocking(main_msg_fds[0]);
cras_make_fd_nonblocking(main_msg_fds[1]);
- cras_system_add_select_fd(main_msg_fds[0], handle_main_messages, NULL);
+ cras_system_add_select_fd(main_msg_fds[0], handle_main_messages, NULL,
+ POLLIN);
}
diff --git a/cras/src/server/cras_server.c b/cras/src/server/cras_server.c
index 6b2f465f..5f2ce632 100644
--- a/cras/src/server/cras_server.c
+++ b/cras/src/server/cras_server.c
@@ -79,16 +79,18 @@ struct attached_client {
* to watch file descriptors. The client can then read or write the fd.
* Members:
* fd - The file descriptor passed to select.
- * callack - The funciton to call when fd is ready.
+ * callback - The funciton to call when fd is ready.
* callback_data - Pointer passed to the callback.
* pollfd - Pointer to struct pollfd for this callback.
+ * events - The events to poll for.
*/
struct client_callback {
int select_fd;
- void (*callback)(void *);
+ void (*callback)(void *data, int revents);
void *callback_data;
struct pollfd *pollfd;
int deleted;
+ int events;
struct client_callback *prev, *next;
};
@@ -277,8 +279,8 @@ error:
/* Add a file descriptor to be passed to select in the main loop. This is
* registered with system state so that it is called when any client asks to
* have a callback triggered based on an fd being readable. */
-static int add_select_fd(int fd, void (*cb)(void *data), void *callback_data,
- void *server_data)
+static int add_select_fd(int fd, void (*cb)(void *data, int events),
+ void *callback_data, int events, void *server_data)
{
struct client_callback *new_cb;
struct client_callback *client_cb;
@@ -301,6 +303,7 @@ static int add_select_fd(int fd, void (*cb)(void *data), void *callback_data,
new_cb->callback = cb;
new_cb->callback_data = callback_data;
new_cb->deleted = 0;
+ new_cb->events = events;
new_cb->pollfd = NULL;
DL_APPEND(serv->client_callbacks, new_cb);
@@ -641,7 +644,7 @@ int cras_server_run(unsigned int profile_disable_mask)
if (client_cb->deleted)
continue;
pollfds[num_pollfds].fd = client_cb->select_fd;
- pollfds[num_pollfds].events = POLLIN;
+ pollfds[num_pollfds].events = client_cb->events;
client_cb->pollfd = &pollfds[num_pollfds];
num_pollfds++;
}
@@ -687,8 +690,9 @@ int cras_server_run(unsigned int profile_disable_mask)
/* Check any client-registered fd/callback pairs. */
DL_FOREACH (server_instance.client_callbacks, client_cb)
if (!client_cb->deleted && client_cb->pollfd &&
- (client_cb->pollfd->revents & POLLIN))
- client_cb->callback(client_cb->callback_data);
+ (client_cb->pollfd->revents & client_cb->events))
+ client_cb->callback(client_cb->callback_data,
+ client_cb->pollfd->revents);
cleanup_select_fds(&server_instance);
@@ -713,4 +717,4 @@ void cras_server_send_to_all_clients(const struct cras_client_message *msg)
DL_FOREACH (server_instance.clients_head, client)
cras_rclient_send_message(client->client, msg, NULL, 0);
-} \ No newline at end of file
+}
diff --git a/cras/src/server/cras_system_state.c b/cras/src/server/cras_system_state.c
index b1403a76..7d478bb2 100644
--- a/cras/src/server/cras_system_state.c
+++ b/cras/src/server/cras_system_state.c
@@ -64,8 +64,8 @@ static struct {
pthread_mutex_t update_lock;
struct cras_tm *tm;
/* Select loop callback registration. */
- int (*fd_add)(int fd, void (*cb)(void *data), void *cb_data,
- void *select_data);
+ int (*fd_add)(int fd, void (*cb)(void *data, int events), void *cb_data,
+ int events, void *select_data);
void (*fd_rm)(int fd, void *select_data);
void *select_data;
int (*add_task)(void (*callback)(void *data), void *callback_data,
@@ -406,8 +406,8 @@ int cras_system_alsa_card_exists(unsigned alsa_card_index)
}
int cras_system_set_select_handler(
- int (*add)(int fd, void (*callback)(void *data), void *callback_data,
- void *select_data),
+ int (*add)(int fd, void (*callback)(void *data, int events),
+ void *callback_data, int events, void *select_data),
void (*rm)(int fd, void *select_data), void *select_data)
{
if (state.fd_add != NULL || state.fd_rm != NULL)
@@ -418,12 +418,13 @@ int cras_system_set_select_handler(
return 0;
}
-int cras_system_add_select_fd(int fd, void (*callback)(void *data),
- void *callback_data)
+int cras_system_add_select_fd(int fd, void (*callback)(void *data, int revents),
+ void *callback_data, int events)
{
if (state.fd_add == NULL)
return -EINVAL;
- return state.fd_add(fd, callback, callback_data, state.select_data);
+ return state.fd_add(fd, callback, callback_data, events,
+ state.select_data);
}
int cras_system_set_add_task_handler(int (*add_task)(void (*cb)(void *data),
diff --git a/cras/src/server/cras_system_state.h b/cras/src/server/cras_system_state.h
index dd53ee3f..16c5093f 100644
--- a/cras/src/server/cras_system_state.h
+++ b/cras/src/server/cras_system_state.h
@@ -171,8 +171,8 @@ int cras_system_alsa_card_exists(unsigned alsa_card_index);
* 0 on success, or -EBUSY if there is already a registered handler.
*/
int cras_system_set_select_handler(
- int (*add)(int fd, void (*callback)(void *data), void *callback_data,
- void *select_data),
+ int (*add)(int fd, void (*callback)(void *data, int revents),
+ void *callback_data, int events, void *select_data),
void (*rm)(int fd, void *select_data), void *select_data);
/* Adds the fd and callback pair. When select indicates that fd is readable,
@@ -181,11 +181,12 @@ int cras_system_set_select_handler(
* fd - The file descriptor to pass to select(2).
* callback - The callback to call when fd is ready.
* callback_data - Value passed back to the callback.
+ * events - The events to poll for.
* Returns:
* 0 on success or a negative error code on failure.
*/
-int cras_system_add_select_fd(int fd, void (*callback)(void *data),
- void *callback_data);
+int cras_system_add_select_fd(int fd, void (*callback)(void *data, int revents),
+ void *callback_data, int events);
/* Removes the fd from the list of fds that are passed to select.
* Args:
diff --git a/cras/src/server/cras_udev.c b/cras/src/server/cras_udev.c
index 4148da35..16f0e3b2 100644
--- a/cras/src/server/cras_udev.c
+++ b/cras/src/server/cras_udev.c
@@ -367,7 +367,7 @@ static void enumerate_devices(struct udev_callback_data *data)
udev_enumerate_unref(enumerate);
}
-static void udev_sound_subsystem_callback(void *arg)
+static void udev_sound_subsystem_callback(void *arg, int revents)
{
struct udev_callback_data *data = (struct udev_callback_data *)arg;
struct udev_device *dev;
@@ -408,8 +408,9 @@ void cras_udev_start_sound_subsystem_monitor()
udev_monitor_enable_receiving(udev_data.mon);
udev_data.fd = udev_monitor_get_fd(udev_data.mon);
- r = cras_system_add_select_fd(
- udev_data.fd, udev_sound_subsystem_callback, &udev_data);
+ r = cras_system_add_select_fd(udev_data.fd,
+ udev_sound_subsystem_callback, &udev_data,
+ POLLIN);
assert(r == 0);
compile_regex(&pcm_regex, pcm_regex_string);
compile_regex(&card_regex, card_regex_string);
diff --git a/cras/src/tests/system_state_unittest.cc b/cras/src/tests/system_state_unittest.cc
index c1db9749..3484d681 100644
--- a/cras/src/tests/system_state_unittest.cc
+++ b/cras/src/tests/system_state_unittest.cc
@@ -58,8 +58,9 @@ static void ResetStubData() {
}
static int add_stub(int fd,
- void (*cb)(void* data),
+ void (*cb)(void* data, int revents),
void* callback_data,
+ int events,
void* select_data) {
add_stub_called++;
select_data_value = select_data;
@@ -79,7 +80,11 @@ static int add_task_stub(void (*cb)(void* data),
return 0;
}
-static void callback_stub(void* data) {
+static void callback_stub(void* data, int revents) {
+ callback_stub_called++;
+}
+
+static void task_stub(void* data) {
callback_stub_called++;
}
@@ -314,7 +319,7 @@ TEST(SystemSettingsRegisterSelectDescriptor, AddSelectFd) {
ResetStubData();
do_sys_init();
- rc = cras_system_add_select_fd(7, callback_stub, stub_data);
+ rc = cras_system_add_select_fd(7, callback_stub, stub_data, POLLIN);
EXPECT_NE(0, rc);
EXPECT_EQ(0, add_stub_called);
EXPECT_EQ(0, rm_stub_called);
@@ -326,7 +331,7 @@ TEST(SystemSettingsRegisterSelectDescriptor, AddSelectFd) {
EXPECT_EQ(-EEXIST, rc);
EXPECT_EQ(0, add_stub_called);
EXPECT_EQ(0, rm_stub_called);
- rc = cras_system_add_select_fd(7, callback_stub, stub_data);
+ rc = cras_system_add_select_fd(7, callback_stub, stub_data, POLLIN);
EXPECT_EQ(0, rc);
EXPECT_EQ(1, add_stub_called);
EXPECT_EQ(select_data, select_data_value);
@@ -343,13 +348,13 @@ TEST(SystemSettingsAddTask, AddTask) {
int rc;
do_sys_init();
- rc = cras_system_add_task(callback_stub, stub_data);
+ rc = cras_system_add_task(task_stub, stub_data);
EXPECT_NE(0, rc);
EXPECT_EQ(0, add_task_stub_called);
rc = cras_system_set_add_task_handler(add_task_stub, task_data);
EXPECT_EQ(0, rc);
EXPECT_EQ(0, add_task_stub_called);
- rc = cras_system_add_task(callback_stub, stub_data);
+ rc = cras_system_add_task(task_stub, stub_data);
EXPECT_EQ(0, rc);
EXPECT_EQ(1, add_task_stub_called);
EXPECT_EQ(task_data, task_data_value);