mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
bluez5: refcount transport acquire and release, let it manage fd
Backends don't necessarily allow for opening the same device multiple times, and it shouldn't be necessary. Since source and sink are not necessarily both running at the same time, refcount the transport acquire/release so that it knows to close the fd only when no source/sink is running. Let the transport manage the fd lifecycle, also closing it once it is not needed. Don't return the fd from acquire(), since each transport is associated with a single socket fd.
This commit is contained in:
parent
8942f6b402
commit
036c10717d
7 changed files with 85 additions and 51 deletions
|
|
@ -686,6 +686,7 @@ struct spa_bt_transport *spa_bt_transport_create(struct spa_bt_monitor *monitor,
|
|||
if (t == NULL)
|
||||
return NULL;
|
||||
|
||||
t->acquire_refcount = 0;
|
||||
t->monitor = monitor;
|
||||
t->path = path;
|
||||
t->fd = -1;
|
||||
|
|
@ -721,6 +722,12 @@ void spa_bt_transport_free(struct spa_bt_transport *transport)
|
|||
|
||||
spa_bt_transport_destroy(transport);
|
||||
|
||||
if (transport->fd >= 0) {
|
||||
shutdown(transport->fd, SHUT_RDWR);
|
||||
close(transport->fd);
|
||||
transport->fd = -1;
|
||||
}
|
||||
|
||||
spa_list_remove(&transport->link);
|
||||
if (transport->device) {
|
||||
transport->device->connected_profiles &= ~transport->profile;
|
||||
|
|
@ -730,6 +737,50 @@ void spa_bt_transport_free(struct spa_bt_transport *transport)
|
|||
free(transport);
|
||||
}
|
||||
|
||||
int spa_bt_transport_acquire(struct spa_bt_transport *transport, bool optional)
|
||||
{
|
||||
struct spa_bt_monitor *monitor = transport->monitor;
|
||||
int res;
|
||||
|
||||
if (transport->acquire_refcount > 0) {
|
||||
spa_log_debug(monitor->log, "transport %p: incref %s", transport, transport->path);
|
||||
transport->acquire_refcount += 1;
|
||||
return 0;
|
||||
}
|
||||
spa_assert(transport->acquire_refcount == 0);
|
||||
|
||||
res = spa_bt_transport_impl(transport, acquire, 0, optional);
|
||||
|
||||
if (res >= 0)
|
||||
transport->acquire_refcount = 1;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int spa_bt_transport_release(struct spa_bt_transport *transport)
|
||||
{
|
||||
struct spa_bt_monitor *monitor = transport->monitor;
|
||||
int res;
|
||||
|
||||
if (transport->acquire_refcount > 1) {
|
||||
spa_log_debug(monitor->log, "transport %p: decref %s", transport, transport->path);
|
||||
transport->acquire_refcount -= 1;
|
||||
return 0;
|
||||
}
|
||||
else if (transport->acquire_refcount == 0) {
|
||||
spa_log_info(monitor->log, "transport %s already released", transport->path);
|
||||
return 0;
|
||||
}
|
||||
spa_assert(transport->acquire_refcount == 1);
|
||||
|
||||
res = spa_bt_transport_impl(transport, release, 0);
|
||||
|
||||
if (res >= 0)
|
||||
transport->acquire_refcount = 0;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int transport_update_props(struct spa_bt_transport *transport,
|
||||
DBusMessageIter *props_iter,
|
||||
DBusMessageIter *invalidated_iter)
|
||||
|
|
@ -840,9 +891,6 @@ static int transport_acquire(void *data, bool optional)
|
|||
int ret = 0;
|
||||
const char *method = optional ? "TryAcquire" : "Acquire";
|
||||
|
||||
if (transport->fd >= 0)
|
||||
return 0;
|
||||
|
||||
m = dbus_message_new_method_call(BLUEZ_SERVICE,
|
||||
transport->path,
|
||||
BLUEZ_MEDIA_TRANSPORT_INTERFACE,
|
||||
|
|
@ -900,10 +948,7 @@ static int transport_release(void *data)
|
|||
DBusMessage *m, *r;
|
||||
DBusError err;
|
||||
|
||||
if (transport->fd < 0)
|
||||
return 0;
|
||||
|
||||
spa_log_debug(monitor->log, "transport %p: Release %s",
|
||||
spa_log_debug(monitor->log, NAME": transport %p: Release %s",
|
||||
transport, transport->path);
|
||||
|
||||
close(transport->fd);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue