summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <smcv@collabora.com>2017-07-21 19:12:30 +0100
committerSimon McVittie <smcv@debian.org>2017-07-30 08:48:43 +0100
commite13f29cae788ee0d0d16352c9be2d9e14a5a0b3d (patch)
treee3bf2e0d7e270c8145f85f74e0f1f5cf8ee6b3f7
parente9974f76a938e155c7d16c913b8cae41ef9cb9fe (diff)
downloaddbus-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.h19
-rw-r--r--dbus/dbus-connection.h30
-rw-r--r--dbus/dbus-hash.h6
-rw-r--r--dbus/dbus-macros.h20
-rw-r--r--dbus/dbus-message-internal.h6
-rw-r--r--dbus/dbus-message.h19
-rw-r--r--dbus/dbus-pending-call.h19
-rw-r--r--dbus/dbus-server.h19
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