diff options
author | Simon McVittie <smcv@collabora.com> | 2017-07-21 19:12:30 +0100 |
---|---|---|
committer | Simon McVittie <smcv@debian.org> | 2017-07-30 08:48:43 +0100 |
commit | e13f29cae788ee0d0d16352c9be2d9e14a5a0b3d (patch) | |
tree | e3bf2e0d7e270c8145f85f74e0f1f5cf8ee6b3f7 | |
parent | e9974f76a938e155c7d16c913b8cae41ef9cb9fe (diff) | |
download | dbus-e13f29cae788ee0d0d16352c9be2d9e14a5a0b3d.tar.gz |
Implement dbus_clear_connection(), etc.
These are inspired by GLib's g_clear_pointer() and g_clear_object(),
which in turn is descended from CPython's Py_CLEAR_OBJECT. They should
make our code a lot less repetitive.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Reviewed-by: Philip Withnall <withnall@endlessm.com>
Bug: https://bugs.freedesktop.org/show_bug.cgi?id=101895
-rw-r--r-- | dbus/dbus-address.h | 19 | ||||
-rw-r--r-- | dbus/dbus-connection.h | 30 | ||||
-rw-r--r-- | dbus/dbus-hash.h | 6 | ||||
-rw-r--r-- | dbus/dbus-macros.h | 20 | ||||
-rw-r--r-- | dbus/dbus-message-internal.h | 6 | ||||
-rw-r--r-- | dbus/dbus-message.h | 19 | ||||
-rw-r--r-- | dbus/dbus-pending-call.h | 19 | ||||
-rw-r--r-- | dbus/dbus-server.h | 19 |
8 files changed, 138 insertions, 0 deletions
diff --git a/dbus/dbus-address.h b/dbus/dbus-address.h index 4d14fdf7..fefb320e 100644 --- a/dbus/dbus-address.h +++ b/dbus/dbus-address.h @@ -59,6 +59,25 @@ DBUS_EXPORT char* dbus_address_unescape_value (const char *value, DBusError *error); +/** + * Clear a variable or struct member that contains an array of #DBusAddressEntry. + * If it does not contain #NULL, the entries that were previously + * there are freed with dbus_address_entries_free(). + * + * This is similar to dbus_clear_connection(): see that function + * for more details. + * + * @param pointer_to_entries A pointer to a variable or struct member. + * pointer_to_entries must not be #NULL, but *pointer_to_entries + * may be #NULL. + */ +static inline void +dbus_clear_address_entries (DBusAddressEntry ***pointer_to_entries) +{ + _dbus_clear_pointer_impl (DBusAddressEntry *, pointer_to_entries, + dbus_address_entries_free); +} + /** @} */ DBUS_END_DECLS diff --git a/dbus/dbus-connection.h b/dbus/dbus-connection.h index fe4d04ef..bed54242 100644 --- a/dbus/dbus-connection.h +++ b/dbus/dbus-connection.h @@ -28,6 +28,7 @@ #define DBUS_CONNECTION_H #include <dbus/dbus-errors.h> +#include <dbus/dbus-macros.h> #include <dbus/dbus-memory.h> #include <dbus/dbus-message.h> #include <dbus/dbus-shared.h> @@ -438,6 +439,35 @@ DBUS_EXPORT dbus_bool_t dbus_connection_get_socket (DBusConnection *connection, int *fd); +/** + * Clear a variable or struct member that contains a #DBusConnection. + * If it does not contain #NULL, the connection that was previously + * there is unreferenced with dbus_connection_unref(). + * + * For example, this function and the similar functions for + * other reference-counted types can be used in code like this: + * + * @code + * DBusConnection *conn = NULL; + * struct { ...; DBusMessage *m; ... } *larger_structure = ...; + * + * ... code that might set conn or m to be non-NULL ... + * + * dbus_clear_connection (&conn); + * dbus_clear_message (&larger_structure->m); + * @endcode + * + * @param pointer_to_connection A pointer to a variable or struct member. + * pointer_to_connection must not be #NULL, but *pointer_to_connection + * may be #NULL. + */ +static inline void +dbus_clear_connection (DBusConnection **pointer_to_connection) +{ + _dbus_clear_pointer_impl (DBusConnection, pointer_to_connection, + dbus_connection_unref); +} + /** @} */ diff --git a/dbus/dbus-hash.h b/dbus/dbus-hash.h index 93f717a9..fadab91f 100644 --- a/dbus/dbus-hash.h +++ b/dbus/dbus-hash.h @@ -210,6 +210,12 @@ _dbus_hash_table_insert_pollable (DBusHashTable *table, #endif } +static inline void +_dbus_clear_hash_table (DBusHashTable **table_p) +{ + _dbus_clear_pointer_impl (DBusHashTable, table_p, _dbus_hash_table_unref); +} + /** @} */ DBUS_END_DECLS diff --git a/dbus/dbus-macros.h b/dbus/dbus-macros.h index 0e784fe1..2c8956e3 100644 --- a/dbus/dbus-macros.h +++ b/dbus/dbus-macros.h @@ -215,6 +215,26 @@ # define DBUS_PRIVATE_EXPORT /* no decoration */ #endif +/* Implementation for dbus_clear_message() etc. This is not API, + * do not use it directly. + * + * We're using a specific type (T ** and T *) instead of void ** and + * void * partly for type-safety, partly to be strict-aliasing-compliant, + * and partly to keep C++ compilers happy. This code is inlined into + * users of libdbus, so we can't rely on it having dbus' own compiler + * settings. */ +#define _dbus_clear_pointer_impl(T, pointer_to_pointer, destroy) \ + do { \ + T **_pp = (pointer_to_pointer); \ + T *_value = *_pp; \ + \ + *_pp = NULL; \ + \ + if (_value != NULL) \ + destroy (_value); \ + } while (0) +/* Not (destroy) (_value) in case destroy() is a function-like macro */ + /** @} */ #endif /* DBUS_MACROS_H */ diff --git a/dbus/dbus-message-internal.h b/dbus/dbus-message-internal.h index f8fe383f..38c79236 100644 --- a/dbus/dbus-message-internal.h +++ b/dbus/dbus-message-internal.h @@ -135,6 +135,12 @@ const DBusString *_dbus_variant_peek (DBusVariant *s DBUS_PRIVATE_EXPORT const char *_dbus_variant_get_signature (DBusVariant *self); +static inline void +_dbus_clear_variant (DBusVariant **variant_p) +{ + _dbus_clear_pointer_impl (DBusVariant, variant_p, _dbus_variant_free); +} + typedef struct DBusInitialFDs DBusInitialFDs; DBusInitialFDs *_dbus_check_fdleaks_enter (void); void _dbus_check_fdleaks_leave (DBusInitialFDs *fds); diff --git a/dbus/dbus-message.h b/dbus/dbus-message.h index 9e7ae7fe..8a9d57a0 100644 --- a/dbus/dbus-message.h +++ b/dbus/dbus-message.h @@ -351,6 +351,25 @@ DBUS_EXPORT dbus_bool_t dbus_message_get_allow_interactive_authorization ( DBusMessage *message); +/** + * Clear a variable or struct member that contains a #DBusMessage. + * If it does not contain #NULL, the message that was previously + * there is unreferenced with dbus_message_unref(). + * + * This is very similar to dbus_clear_connection(): see that function + * for more details. + * + * @param pointer_to_message A pointer to a variable or struct member. + * pointer_to_message must not be #NULL, but *pointer_to_message + * may be #NULL. + */ +static inline void +dbus_clear_message (DBusMessage **pointer_to_message) +{ + _dbus_clear_pointer_impl (DBusMessage, pointer_to_message, + dbus_message_unref); +} + /** @} */ DBUS_END_DECLS diff --git a/dbus/dbus-pending-call.h b/dbus/dbus-pending-call.h index 8a37ec0a..5593397a 100644 --- a/dbus/dbus-pending-call.h +++ b/dbus/dbus-pending-call.h @@ -72,6 +72,25 @@ DBUS_EXPORT void* dbus_pending_call_get_data (DBusPendingCall *pending, dbus_int32_t slot); +/** + * Clear a variable or struct member that contains a #DBusPendingCall. + * If it does not contain #NULL, the pending call that was previously + * there is unreferenced with dbus_pending_call_unref(). + * + * This is very similar to dbus_clear_connection(): see that function + * for more details. + * + * @param pointer_to_pending_call A pointer to a variable or struct member. + * pointer_to_pending_call must not be #NULL, but *pointer_to_pending_call + * may be #NULL. + */ +static inline void +dbus_clear_pending_call (DBusPendingCall **pointer_to_pending_call) +{ + _dbus_clear_pointer_impl (DBusPendingCall, pointer_to_pending_call, + dbus_pending_call_unref); +} + /** @} */ DBUS_END_DECLS diff --git a/dbus/dbus-server.h b/dbus/dbus-server.h index bdbefa0f..7d8f04e4 100644 --- a/dbus/dbus-server.h +++ b/dbus/dbus-server.h @@ -28,6 +28,7 @@ #define DBUS_SERVER_H #include <dbus/dbus-errors.h> +#include <dbus/dbus-macros.h> #include <dbus/dbus-message.h> #include <dbus/dbus-connection.h> #include <dbus/dbus-protocol.h> @@ -99,6 +100,24 @@ DBUS_EXPORT void* dbus_server_get_data (DBusServer *server, int slot); +/** + * Clear a variable or struct member that contains a #DBusServer. + * If it does not contain #NULL, the server that was previously + * there is unreferenced with dbus_server_unref(). + * + * This is very similar to dbus_clear_connection(): see that function + * for more details. + * + * @param pointer_to_server A pointer to a variable or struct member. + * pointer_to_server must not be #NULL, but *pointer_to_server + * may be #NULL. + */ +static inline void +dbus_clear_server (DBusServer **pointer_to_server) +{ + _dbus_clear_pointer_impl (DBusServer, pointer_to_server, dbus_server_unref); +} + /** @} */ DBUS_END_DECLS |