mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-03 09:01:54 -05:00
bluez5: add convenience helper for dbus pending calls
This commit is contained in:
parent
42e463f726
commit
a07dfbbdb9
2 changed files with 104 additions and 35 deletions
|
|
@ -292,36 +292,26 @@ static void interfaces_removed(struct impl *impl, DBusMessageIter *arg_iter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_managed_objects_reply(DBusPendingCall *pending, void *user_data)
|
static void get_managed_objects_reply(DBusPendingCall **call_ptr, DBusMessage *r)
|
||||||
{
|
{
|
||||||
struct impl *impl = user_data;
|
struct impl *impl = SPA_CONTAINER_OF(call_ptr, struct impl, get_managed_objects_call);
|
||||||
DBusMessage *r;
|
|
||||||
DBusMessageIter it[6];
|
DBusMessageIter it[6];
|
||||||
|
|
||||||
spa_assert(pending == impl->get_managed_objects_call);
|
|
||||||
impl->get_managed_objects_call = NULL;
|
|
||||||
|
|
||||||
r = dbus_pending_call_steal_reply(pending);
|
|
||||||
dbus_pending_call_unref(pending);
|
|
||||||
|
|
||||||
if (r == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (dbus_message_is_error(r, DBUS_ERROR_UNKNOWN_METHOD)) {
|
if (dbus_message_is_error(r, DBUS_ERROR_UNKNOWN_METHOD)) {
|
||||||
spa_log_warn(impl->log, "BlueZ D-Bus ObjectManager not available");
|
spa_log_warn(impl->log, "BlueZ D-Bus ObjectManager not available");
|
||||||
goto done;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
|
if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
|
||||||
spa_log_error(impl->log, "GetManagedObjects() failed: %s",
|
spa_log_error(impl->log, "GetManagedObjects() failed: %s",
|
||||||
dbus_message_get_error_name(r));
|
dbus_message_get_error_name(r));
|
||||||
goto done;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dbus_message_iter_init(r, &it[0]) ||
|
if (!dbus_message_iter_init(r, &it[0]) ||
|
||||||
!spa_streq(dbus_message_get_signature(r), "a{oa{sa{sv}}}")) {
|
!spa_streq(dbus_message_get_signature(r), "a{oa{sa{sv}}}")) {
|
||||||
spa_log_error(impl->log, "Invalid reply signature for GetManagedObjects()");
|
spa_log_error(impl->log, "Invalid reply signature for GetManagedObjects()");
|
||||||
goto done;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add fake object representing the service itself */
|
/* Add fake object representing the service itself */
|
||||||
|
|
@ -338,17 +328,11 @@ static void get_managed_objects_reply(DBusPendingCall *pending, void *user_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl->objects_listed = true;
|
impl->objects_listed = true;
|
||||||
|
|
||||||
done:
|
|
||||||
dbus_message_unref(r);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_managed_objects(struct impl *impl)
|
static int get_managed_objects(struct impl *impl)
|
||||||
{
|
{
|
||||||
DBusMessage *m = NULL;
|
DBusMessage *m;
|
||||||
DBusPendingCall *call;
|
|
||||||
int res = 0;
|
|
||||||
|
|
||||||
if (impl->objects_listed || impl->get_managed_objects_call)
|
if (impl->objects_listed || impl->get_managed_objects_call)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -362,19 +346,8 @@ static int get_managed_objects(struct impl *impl)
|
||||||
|
|
||||||
dbus_message_set_auto_start(m, false);
|
dbus_message_set_auto_start(m, false);
|
||||||
|
|
||||||
if (!dbus_connection_send_with_reply(impl->conn, m, &call, -1)) {
|
return spa_dbus_async_call(impl->conn, m, &impl->get_managed_objects_call,
|
||||||
res = -EIO;
|
get_managed_objects_reply);
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
dbus_pending_call_set_notify(call, get_managed_objects_reply, impl, NULL);
|
|
||||||
impl->get_managed_objects_call = call;
|
|
||||||
|
|
||||||
done:
|
|
||||||
if (m)
|
|
||||||
dbus_message_unref(m);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -696,3 +669,72 @@ struct spa_list *spa_dbus_monitor_object_list(struct spa_dbus_monitor *this, con
|
||||||
|
|
||||||
return object_list;
|
return object_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef void (*pending_call_reply_t)(DBusPendingCall **, DBusMessage *);
|
||||||
|
|
||||||
|
static dbus_int32_t async_call_reply_id = -1;
|
||||||
|
|
||||||
|
static void async_call_reply(DBusPendingCall *pending, void *user_data)
|
||||||
|
{
|
||||||
|
DBusPendingCall **call_ptr = user_data;
|
||||||
|
DBusMessage *r;
|
||||||
|
pending_call_reply_t reply;
|
||||||
|
|
||||||
|
spa_assert(pending == *call_ptr);
|
||||||
|
*call_ptr = NULL;
|
||||||
|
|
||||||
|
r = dbus_pending_call_steal_reply(pending);
|
||||||
|
reply = dbus_pending_call_get_data(pending, async_call_reply_id);
|
||||||
|
dbus_pending_call_unref(pending);
|
||||||
|
|
||||||
|
spa_assert(reply != NULL);
|
||||||
|
|
||||||
|
if (r == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
reply(call_ptr, r);
|
||||||
|
dbus_message_unref(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
int spa_dbus_async_call(DBusConnection *conn, DBusMessage *msg,
|
||||||
|
DBusPendingCall **call_ptr,
|
||||||
|
pending_call_reply_t reply)
|
||||||
|
{
|
||||||
|
int res = -EIO;
|
||||||
|
DBusPendingCall *pending;
|
||||||
|
|
||||||
|
spa_assert(msg);
|
||||||
|
spa_assert(call_ptr);
|
||||||
|
|
||||||
|
if (async_call_reply_id == -1) {
|
||||||
|
if (!dbus_pending_call_allocate_data_slot(&async_call_reply_id))
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*call_ptr) {
|
||||||
|
res = -EBUSY;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dbus_connection_send_with_reply(conn, msg, &pending, -1))
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
if (!dbus_pending_call_set_data(pending, async_call_reply_id, reply, NULL)) {
|
||||||
|
dbus_pending_call_cancel(pending);
|
||||||
|
dbus_pending_call_unref(pending);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dbus_pending_call_set_notify(pending, async_call_reply, call_ptr, NULL)) {
|
||||||
|
dbus_pending_call_cancel(pending);
|
||||||
|
dbus_pending_call_unref(pending);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
*call_ptr = pending;
|
||||||
|
res = 0;
|
||||||
|
|
||||||
|
done:
|
||||||
|
dbus_message_unref(msg);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ struct spa_dbus_interface {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface at the object path removed.
|
* Interface at the object path removed.
|
||||||
|
* No other hooks will be called after this.
|
||||||
* The object will be deallocated after this, so any associated data,
|
* The object will be deallocated after this, so any associated data,
|
||||||
* for example in a custom object struct, can be freed in this hook.
|
* for example in a custom object struct, can be freed in this hook.
|
||||||
*/
|
*/
|
||||||
|
|
@ -136,4 +137,30 @@ void spa_dbus_monitor_ignore_object(struct spa_dbus_monitor *monitor,
|
||||||
struct spa_list *spa_dbus_monitor_object_list(struct spa_dbus_monitor *monitor,
|
struct spa_list *spa_dbus_monitor_object_list(struct spa_dbus_monitor *monitor,
|
||||||
const char *interface);
|
const char *interface);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make an asynchronous DBus call.
|
||||||
|
*
|
||||||
|
* On successful return, *call_ptr contains the pending call handle.
|
||||||
|
* The same address is passed to the reply function, and can be used
|
||||||
|
* to locate the address container object. The reply function does not
|
||||||
|
* need to unref the reply, or set *call_ptr to NULL itself.
|
||||||
|
*
|
||||||
|
* The msg passed in is stolen, and unref'd also on errors.
|
||||||
|
*
|
||||||
|
* \returns 0 on success, < 0 on error.
|
||||||
|
*/
|
||||||
|
int spa_dbus_async_call(DBusConnection *conn, DBusMessage *msg,
|
||||||
|
DBusPendingCall **call_ptr,
|
||||||
|
void (*reply)(DBusPendingCall **call_ptr, DBusMessage *reply));
|
||||||
|
|
||||||
|
/** Convenience for pending call cancel + unref */
|
||||||
|
static inline void spa_dbus_async_call_cancel(DBusPendingCall **call_ptr)
|
||||||
|
{
|
||||||
|
if (*call_ptr) {
|
||||||
|
dbus_pending_call_cancel(*call_ptr);
|
||||||
|
dbus_pending_call_unref(*call_ptr);
|
||||||
|
*call_ptr = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue