From 992bfc2f6af0da82d6a311b6f3970035b886ee3c Mon Sep 17 00:00:00 2001 From: Alban Crequy Date: Fri, 18 Jul 2014 17:28:32 +0100 Subject: [PATCH 07/11] DBusConnection: implements _dbus_connection_set_pending_fds_function This will allow the bus to be notified whenever a file descriptor is added or removed from a DBusConnection's DBusMessageLoader. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=80559 Reviewed-by: Simon McVittie --- dbus/dbus-connection-internal.h | 5 +++++ dbus/dbus-connection.c | 16 ++++++++++++++++ dbus/dbus-message-internal.h | 3 +++ dbus/dbus-message-private.h | 2 ++ dbus/dbus-message.c | 25 +++++++++++++++++++++++++ dbus/dbus-transport.c | 16 ++++++++++++++++ dbus/dbus-transport.h | 3 +++ 7 files changed, 70 insertions(+) diff --git a/dbus/dbus-connection-internal.h b/dbus/dbus-connection-internal.h index f5edf3c..badeabf 100644 --- a/dbus/dbus-connection-internal.h +++ b/dbus/dbus-connection-internal.h @@ -44,6 +44,8 @@ typedef enum /** default timeout value when waiting for a message reply, 25 seconds */ #define _DBUS_DEFAULT_TIMEOUT_VALUE (25 * 1000) +typedef void (* DBusPendingFdsChangeFunction) (void *data); + void _dbus_connection_lock (DBusConnection *connection); void _dbus_connection_unlock (DBusConnection *connection); DBusConnection * _dbus_connection_ref_unlocked (DBusConnection *connection); @@ -101,6 +103,9 @@ void _dbus_connection_test_get_locks (DBusConnectio DBusCondVar **dispatch_cond_loc, DBusCondVar **io_path_cond_loc); int _dbus_connection_get_pending_fds_count (DBusConnection *connection); +void _dbus_connection_set_pending_fds_function (DBusConnection *connection, + DBusPendingFdsChangeFunction callback, + void *data); /* if DBUS_ENABLE_STATS */ void _dbus_connection_get_stats (DBusConnection *connection, diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index 07a9ebf..e1068e3 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -2543,6 +2543,22 @@ _dbus_connection_get_pending_fds_count (DBusConnection *connection) return _dbus_transport_get_pending_fds_count (connection->transport); } +/** + * Register a function to be called whenever the number of pending file + * descriptors in the loader change. + * + * @param connection the connection + * @param callback the callback + */ +void +_dbus_connection_set_pending_fds_function (DBusConnection *connection, + DBusPendingFdsChangeFunction callback, + void *data) +{ + _dbus_transport_set_pending_fds_function (connection->transport, + callback, data); +} + /** @} */ /** diff --git a/dbus/dbus-message-internal.h b/dbus/dbus-message-internal.h index de03edd..76540f4 100644 --- a/dbus/dbus-message-internal.h +++ b/dbus/dbus-message-internal.h @@ -98,6 +98,9 @@ void _dbus_message_loader_set_max_message_unix_fds(DBusMessageLoad long n); long _dbus_message_loader_get_max_message_unix_fds(DBusMessageLoader *loader); int _dbus_message_loader_get_pending_fds_count (DBusMessageLoader *loader); +void _dbus_message_loader_set_pending_fds_function (DBusMessageLoader *loader, + void (* callback) (void *), + void *data); typedef struct DBusInitialFDs DBusInitialFDs; DBusInitialFDs *_dbus_check_fdleaks_enter (void); diff --git a/dbus/dbus-message-private.h b/dbus/dbus-message-private.h index e1578ab..a611b09 100644 --- a/dbus/dbus-message-private.h +++ b/dbus/dbus-message-private.h @@ -80,6 +80,8 @@ struct DBusMessageLoader int *unix_fds; /**< File descriptors that have been read from the transport but not yet been handed to any message. Array will be allocated at first use. */ unsigned n_unix_fds_allocated; /**< Number of file descriptors this array has space for */ unsigned n_unix_fds; /**< Number of valid file descriptors in array */ + void (* unix_fds_change) (void *); /**< Notify when the pending fds change */ + void *unix_fds_change_data; #endif }; diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c index 30adaf0..48564db 100644 --- a/dbus/dbus-message.c +++ b/dbus/dbus-message.c @@ -3984,6 +3984,9 @@ _dbus_message_loader_return_unix_fds(DBusMessageLoader *loader, loader->n_unix_fds += n_fds; loader->unix_fds_outstanding = FALSE; + + if (n_fds && loader->unix_fds_change) + loader->unix_fds_change (loader->unix_fds_change_data); #else _dbus_assert_not_reached("Platform doesn't support unix fd passing"); #endif @@ -4131,6 +4134,9 @@ load_message (DBusMessageLoader *loader, message->n_unix_fds_allocated = message->n_unix_fds = n_unix_fds; loader->n_unix_fds -= n_unix_fds; memmove (loader->unix_fds, loader->unix_fds + n_unix_fds, loader->n_unix_fds * sizeof (loader->unix_fds[0])); + + if (loader->unix_fds_change) + loader->unix_fds_change (loader->unix_fds_change_data); } else message->unix_fds = NULL; @@ -4439,6 +4445,25 @@ _dbus_message_loader_get_pending_fds_count (DBusMessageLoader *loader) #endif } +/** + * Register a function to be called whenever the number of pending file + * descriptors in the loader change. + * + * @param loader the loader + * @param callback the callback + * @param data the data for the callback + */ +void +_dbus_message_loader_set_pending_fds_function (DBusMessageLoader *loader, + void (* callback) (void *), + void *data) +{ +#ifdef HAVE_UNIX_FD_PASSING + loader->unix_fds_change = callback; + loader->unix_fds_change_data = data; +#endif +} + static DBusDataSlotAllocator slot_allocator; _DBUS_DEFINE_GLOBAL_LOCK (message_slots); diff --git a/dbus/dbus-transport.c b/dbus/dbus-transport.c index e4d03c1..9846cc6 100644 --- a/dbus/dbus-transport.c +++ b/dbus/dbus-transport.c @@ -1502,6 +1502,22 @@ _dbus_transport_get_pending_fds_count (DBusTransport *transport) return _dbus_message_loader_get_pending_fds_count (transport->loader); } +/** + * Register a function to be called whenever the number of pending file + * descriptors in the loader change. + * + * @param transport the transport + * @param callback the callback + */ +void +_dbus_transport_set_pending_fds_function (DBusTransport *transport, + void (* callback) (void *), + void *data) +{ + _dbus_message_loader_set_pending_fds_function (transport->loader, + callback, data); +} + #ifdef DBUS_ENABLE_STATS void _dbus_transport_get_stats (DBusTransport *transport, diff --git a/dbus/dbus-transport.h b/dbus/dbus-transport.h index 6a3a8b3..0d5a6e5 100644 --- a/dbus/dbus-transport.h +++ b/dbus/dbus-transport.h @@ -97,6 +97,9 @@ dbus_bool_t _dbus_transport_set_auth_mechanisms (DBusTransport void _dbus_transport_set_allow_anonymous (DBusTransport *transport, dbus_bool_t value); int _dbus_transport_get_pending_fds_count (DBusTransport *transport); +void _dbus_transport_set_pending_fds_function (DBusTransport *transport, + void (* callback) (void *), + void *data); /* if DBUS_ENABLE_STATS */ void _dbus_transport_get_stats (DBusTransport *transport, -- 2.1.0