dbus: add events to the dbus connection

Add events to the dbus connection and notify about destroy and
disconnect.
This commit is contained in:
Wim Taymans 2021-05-17 11:54:43 +02:00
parent b6d803daa4
commit 2dcdabd2af
2 changed files with 67 additions and 4 deletions

View file

@ -42,8 +42,23 @@ enum spa_dbus_type {
SPA_DBUS_TYPE_STARTER /**< The bus that started us, if any */
};
#define SPA_DBUS_CONNECTION_EVENT_DESTROY 0
#define SPA_DBUS_CONNECTION_EVENT_DISCONNECTED 1
#define SPA_DBUS_CONNECTION_EVENT_NUM 2
struct spa_dbus_connection_events {
#define SPA_VERSION_DBUS_CONNECTION_EVENTS 0
uint32_t version;
/* a connection is destroyed */
void (*destroy) (void *data);
/* a connection disconnected */
void (*disconnected) (void *data);
};
struct spa_dbus_connection {
#define SPA_VERSION_DBUS_CONNECTION 0
#define SPA_VERSION_DBUS_CONNECTION 1
uint32_t version;
/**
* Get the DBusConnection from a wrapper
@ -58,10 +73,35 @@ struct spa_dbus_connection {
* \param conn the wrapper to destroy
*/
void (*destroy) (struct spa_dbus_connection *conn);
/**
* Add a listener for events
*
* Since version 1
*/
void (*add_listener) (struct spa_dbus_connection *conn,
struct spa_hook *listener,
const struct spa_dbus_connection_events *events,
void *data);
};
#define spa_dbus_connection_get(c) (c)->get((c))
#define spa_dbus_connection_destroy(c) (c)->destroy((c))
#define spa_dbus_connection_call(c,method,vers,...) \
({ \
if (SPA_LIKELY(SPA_CALLBACK_CHECK(c,method,vers))) \
c->method((c), ## __VA_ARGS__); \
})
#define spa_dbus_connection_call_vp(c,method,vers,...) \
({ \
void *_res = NULL; \
if (SPA_LIKELY(SPA_CALLBACK_CHECK(c,method,vers))) \
_res = c->method((c), ## __VA_ARGS__); \
_res; \
})
#define spa_dbus_connection_get(c) spa_dbus_connection_call_vp(c,get,0)
#define spa_dbus_connection_destroy(c) spa_dbus_connection_call(c,destroy,0)
#define spa_dbus_connection_add_listener(c,...) spa_dbus_connection_call(c,add_listener,1,__VA_ARGS__)
struct spa_dbus_methods {
#define SPA_VERSION_DBUS_METHODS 0

View file

@ -57,6 +57,10 @@ struct source_data {
struct connection *conn;
};
#define connection_emit(c,m,v,...) spa_hook_list_call(&c->listener_list, struct spa_dbus_connection_events, m, v, ##__VA_ARGS__)
#define connection_emit_destroy(c) connection_emit(c, destroy, 0)
#define connection_emit_disconnected(c) connection_emit(c, disconnected, 0)
struct connection {
struct spa_list link;
@ -65,6 +69,8 @@ struct connection {
DBusConnection *conn;
struct spa_source *dispatch_event;
struct spa_list source_list;
struct spa_hook_list listener_list;
};
static void source_data_free(void *data)
@ -279,7 +285,8 @@ static DBusHandlerResult filter_message (DBusConnection *connection,
struct impl *impl = this->impl;
if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) {
spa_log_warn(impl->log, "dbus connection %p disconnected", this);
spa_log_debug(impl->log, "dbus connection %p disconnected", this);
connection_emit_disconnected(this);
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
@ -308,6 +315,8 @@ static void connection_free(struct connection *conn)
spa_loop_utils_destroy_source(impl->utils, conn->dispatch_event);
spa_hook_list_clean(&conn->listener_list);
free(conn);
}
@ -317,14 +326,27 @@ impl_connection_destroy(struct spa_dbus_connection *conn)
struct connection *this = SPA_CONTAINER_OF(conn, struct connection, this);
struct impl *impl = this->impl;
connection_emit_destroy(this);
spa_log_debug(impl->log, "destroy conn %p", this);
connection_free(this);
}
static void
impl_connection_add_listener(struct spa_dbus_connection *conn,
struct spa_hook *listener,
const struct spa_dbus_connection_events *events,
void *data)
{
struct connection *this = SPA_CONTAINER_OF(conn, struct connection, this);
spa_hook_list_append(&this->listener_list, listener, events, data);
}
static const struct spa_dbus_connection impl_connection = {
SPA_VERSION_DBUS_CONNECTION,
impl_connection_get,
impl_connection_destroy,
impl_connection_add_listener,
};
static struct spa_dbus_connection *
@ -351,6 +373,7 @@ impl_get_connection(void *object,
goto no_event;
spa_list_init(&conn->source_list);
spa_hook_list_init(&conn->listener_list);
dbus_connection_set_exit_on_disconnect(conn->conn, false);
if (!dbus_connection_add_filter(conn->conn, filter_message, conn, NULL))