mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2026-07-03 00:06:38 -04:00
bluez5: backend-native: fix multiple profile registration
Handling pending RegisterProfile callbacks was wrong as it forgot that there can be multiple profiles to be registered. Fix the handling by allowing several concurrent register callbacks.
This commit is contained in:
parent
422765c91d
commit
393da55797
1 changed files with 41 additions and 10 deletions
|
|
@ -106,7 +106,7 @@ struct impl {
|
||||||
struct spa_dbus *dbus;
|
struct spa_dbus *dbus;
|
||||||
DBusConnection *conn;
|
DBusConnection *conn;
|
||||||
|
|
||||||
DBusPendingCall *pending_register_profile;
|
DBusPendingCall *pending_register_profile[4];
|
||||||
|
|
||||||
const struct media_codec * const * codecs;
|
const struct media_codec * const * codecs;
|
||||||
|
|
||||||
|
|
@ -3683,12 +3683,40 @@ static DBusHandlerResult profile_handler(DBusConnection *c, DBusMessage *m, void
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool pending_register_profile_push(struct impl *backend, DBusPendingCall *pending)
|
||||||
|
{
|
||||||
|
SPA_FOR_EACH_ELEMENT_VAR(backend->pending_register_profile, p) {
|
||||||
|
if (!*p) {
|
||||||
|
*p = pending;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DBusMessage *pending_register_profile_pop(struct impl *backend, DBusPendingCall *pending)
|
||||||
|
{
|
||||||
|
SPA_FOR_EACH_ELEMENT_VAR(backend->pending_register_profile, p) {
|
||||||
|
if (*p == pending)
|
||||||
|
return steal_reply_and_unref(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
spa_assert_not_reached();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pending_register_profile_clear(struct impl *backend)
|
||||||
|
{
|
||||||
|
SPA_FOR_EACH_ELEMENT_VAR(backend->pending_register_profile, p)
|
||||||
|
cancel_and_unref(p);
|
||||||
|
}
|
||||||
|
|
||||||
static void register_profile_reply(DBusPendingCall *pending, void *user_data)
|
static void register_profile_reply(DBusPendingCall *pending, void *user_data)
|
||||||
{
|
{
|
||||||
struct impl *backend = user_data;
|
struct impl *backend = user_data;
|
||||||
|
|
||||||
spa_assert(backend->pending_register_profile == pending);
|
spa_autoptr(DBusMessage) r = pending_register_profile_pop(backend, pending);
|
||||||
spa_autoptr(DBusMessage) r = steal_reply_and_unref(&backend->pending_register_profile);
|
|
||||||
if (r == NULL)
|
if (r == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -3705,6 +3733,8 @@ static void register_profile_reply(DBusPendingCall *pending, void *user_data)
|
||||||
dbus_message_get_error_name(r));
|
dbus_message_get_error_name(r));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spa_log_debug(backend->log, "RegisterProfile() complete");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int register_profile(struct impl *backend, const char *profile, const char *uuid)
|
static int register_profile(struct impl *backend, const char *profile, const char *uuid)
|
||||||
|
|
@ -3713,14 +3743,12 @@ static int register_profile(struct impl *backend, const char *profile, const cha
|
||||||
DBusMessageIter it[4];
|
DBusMessageIter it[4];
|
||||||
dbus_bool_t autoconnect;
|
dbus_bool_t autoconnect;
|
||||||
dbus_uint16_t version, chan, features;
|
dbus_uint16_t version, chan, features;
|
||||||
|
DBusPendingCall *pending;
|
||||||
const char *str;
|
const char *str;
|
||||||
|
|
||||||
if (!(backend->enabled_profiles & spa_bt_profile_from_uuid(uuid)))
|
if (!(backend->enabled_profiles & spa_bt_profile_from_uuid(uuid)))
|
||||||
return -ECANCELED;
|
return -ECANCELED;
|
||||||
|
|
||||||
if (backend->pending_register_profile)
|
|
||||||
return -EBUSY;
|
|
||||||
|
|
||||||
spa_log_debug(backend->log, "Registering Profile %s %s", profile, uuid);
|
spa_log_debug(backend->log, "Registering Profile %s %s", profile, uuid);
|
||||||
|
|
||||||
m = dbus_message_new_method_call(BLUEZ_SERVICE, "/org/bluez",
|
m = dbus_message_new_method_call(BLUEZ_SERVICE, "/org/bluez",
|
||||||
|
|
@ -3819,9 +3847,12 @@ static int register_profile(struct impl *backend, const char *profile, const cha
|
||||||
}
|
}
|
||||||
dbus_message_iter_close_container(&it[0], &it[1]);
|
dbus_message_iter_close_container(&it[0], &it[1]);
|
||||||
|
|
||||||
backend->pending_register_profile = send_with_reply(backend->conn, m, register_profile_reply, backend);
|
pending = send_with_reply(backend->conn, m, register_profile_reply, backend);
|
||||||
if (!backend->pending_register_profile)
|
if (!pending || !pending_register_profile_push(backend, pending)) {
|
||||||
|
spa_log_error(backend->log, "Failed to start RegisterProfile() %s", profile);
|
||||||
|
cancel_and_unref(&pending);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -3887,7 +3918,7 @@ static int backend_native_unregister_profiles(void *data)
|
||||||
{
|
{
|
||||||
struct impl *backend = data;
|
struct impl *backend = data;
|
||||||
|
|
||||||
cancel_and_unref(&backend->pending_register_profile);
|
pending_register_profile_clear(backend);
|
||||||
|
|
||||||
sco_close(backend);
|
sco_close(backend);
|
||||||
|
|
||||||
|
|
@ -4069,7 +4100,7 @@ static int backend_native_free(void *data)
|
||||||
|
|
||||||
struct rfcomm *rfcomm;
|
struct rfcomm *rfcomm;
|
||||||
|
|
||||||
cancel_and_unref(&backend->pending_register_profile);
|
pending_register_profile_clear(backend);
|
||||||
|
|
||||||
sco_close(backend);
|
sco_close(backend);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue