mirror of
				https://gitlab.gnome.org/GNOME/glib.git
				synced 2025-11-04 01:58:54 +01:00 
			
		
		
		
	Bug 624546 – Modification of GDBusMessage in filter function
Rework filter functions as per https://bugzilla.gnome.org/show_bug.cgi?id=624546#c8 This commit breaks ABI. However, this ABI break affects only applications using filter functions. The only known user of is dconf. Signed-off-by: David Zeuthen <davidz@redhat.com>
This commit is contained in:
		@@ -2428,7 +2428,6 @@ g_dbus_connection_send_message
 | 
			
		||||
g_dbus_connection_send_message_with_reply
 | 
			
		||||
g_dbus_connection_send_message_with_reply_finish
 | 
			
		||||
g_dbus_connection_send_message_with_reply_sync
 | 
			
		||||
GDBusMessageFilterResult
 | 
			
		||||
GDBusMessageFilterFunction
 | 
			
		||||
g_dbus_connection_add_filter
 | 
			
		||||
g_dbus_connection_remove_filter
 | 
			
		||||
 
 | 
			
		||||
@@ -1367,6 +1367,7 @@ g_dbus_connection_send_message_unlocked (GDBusConnection   *connection,
 | 
			
		||||
 | 
			
		||||
  g_dbus_message_set_serial (message, serial_to_use);
 | 
			
		||||
 | 
			
		||||
  g_dbus_message_lock (message);
 | 
			
		||||
  _g_dbus_worker_send_message (connection->worker,
 | 
			
		||||
                               message,
 | 
			
		||||
                               (gchar*) blob,
 | 
			
		||||
@@ -1406,6 +1407,9 @@ g_dbus_connection_send_message_unlocked (GDBusConnection   *connection,
 | 
			
		||||
 * linkend="gdbus-unix-fd-client"/> for an example of how to use this
 | 
			
		||||
 * low-level API to send and receive UNIX file descriptors.
 | 
			
		||||
 *
 | 
			
		||||
 * Note that @message must be unlocked, unless @flags contain the
 | 
			
		||||
 * %G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL flag.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: %TRUE if the message was well-formed and queued for
 | 
			
		||||
 * transmission, %FALSE if @error is set.
 | 
			
		||||
 *
 | 
			
		||||
@@ -1422,6 +1426,7 @@ g_dbus_connection_send_message (GDBusConnection   *connection,
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE);
 | 
			
		||||
  g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), FALSE);
 | 
			
		||||
  g_return_val_if_fail ((flags & G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL) || !g_dbus_message_get_locked (message), FALSE);
 | 
			
		||||
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
  CONNECTION_LOCK (connection);
 | 
			
		||||
@@ -1727,6 +1732,9 @@ g_dbus_connection_send_message_with_reply_unlocked (GDBusConnection     *connect
 | 
			
		||||
 * g_dbus_connection_send_message_with_reply_finish() to get the result of the operation.
 | 
			
		||||
 * See g_dbus_connection_send_message_with_reply_sync() for the synchronous version.
 | 
			
		||||
 *
 | 
			
		||||
 * Note that @message must be unlocked, unless @flags contain the
 | 
			
		||||
 * %G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL flag.
 | 
			
		||||
 *
 | 
			
		||||
 * See <xref linkend="gdbus-server"/> and <xref
 | 
			
		||||
 * linkend="gdbus-unix-fd-client"/> for an example of how to use this
 | 
			
		||||
 * low-level API to send and receive UNIX file descriptors.
 | 
			
		||||
@@ -1745,6 +1753,7 @@ g_dbus_connection_send_message_with_reply (GDBusConnection     *connection,
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (G_IS_DBUS_CONNECTION (connection));
 | 
			
		||||
  g_return_if_fail (G_IS_DBUS_MESSAGE (message));
 | 
			
		||||
  g_return_if_fail ((flags & G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL) || !g_dbus_message_get_locked (message));
 | 
			
		||||
  g_return_if_fail (timeout_msec >= 0 || timeout_msec == -1);
 | 
			
		||||
 | 
			
		||||
  CONNECTION_LOCK (connection);
 | 
			
		||||
@@ -1776,7 +1785,7 @@ g_dbus_connection_send_message_with_reply (GDBusConnection     *connection,
 | 
			
		||||
 * linkend="gdbus-unix-fd-client"/> for an example of how to use this
 | 
			
		||||
 * low-level API to send and receive UNIX file descriptors.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: A #GDBusMessage or %NULL if @error is set.
 | 
			
		||||
 * Returns: A locked #GDBusMessage or %NULL if @error is set.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.26
 | 
			
		||||
 */
 | 
			
		||||
@@ -1869,7 +1878,10 @@ send_message_with_reply_sync_cb (GDBusConnection *connection,
 | 
			
		||||
 * linkend="gdbus-unix-fd-client"/> for an example of how to use this
 | 
			
		||||
 * low-level API to send and receive UNIX file descriptors.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: A #GDBusMessage that is the reply to @message or %NULL if @error is set.
 | 
			
		||||
 * Note that @message must be unlocked, unless @flags contain the
 | 
			
		||||
 * %G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL flag.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: A locked #GDBusMessage that is the reply to @message or %NULL if @error is set.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.26
 | 
			
		||||
 */
 | 
			
		||||
@@ -1887,6 +1899,7 @@ g_dbus_connection_send_message_with_reply_sync (GDBusConnection   *connection,
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
 | 
			
		||||
  g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
 | 
			
		||||
  g_return_val_if_fail ((flags & G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL) || !g_dbus_message_get_locked (message), FALSE);
 | 
			
		||||
  g_return_val_if_fail (timeout_msec >= 0 || timeout_msec == -1, NULL);
 | 
			
		||||
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 | 
			
		||||
 | 
			
		||||
@@ -1950,6 +1963,9 @@ on_worker_message_received (GDBusWorker  *worker,
 | 
			
		||||
 | 
			
		||||
  //g_debug ("in on_worker_message_received");
 | 
			
		||||
 | 
			
		||||
  g_object_ref (message);
 | 
			
		||||
  g_dbus_message_lock (message);
 | 
			
		||||
 | 
			
		||||
  g_object_ref (connection);
 | 
			
		||||
 | 
			
		||||
  /* First collect the set of callback functions */
 | 
			
		||||
@@ -1964,42 +1980,24 @@ on_worker_message_received (GDBusWorker  *worker,
 | 
			
		||||
    }
 | 
			
		||||
  CONNECTION_UNLOCK (connection);
 | 
			
		||||
 | 
			
		||||
  /* the call the filters in order (without holding the lock) */
 | 
			
		||||
  /* then call the filters in order (without holding the lock) */
 | 
			
		||||
  consumed_by_filter = FALSE;
 | 
			
		||||
  altered_by_filter = FALSE;
 | 
			
		||||
  for (n = 0; n < num_filters; n++)
 | 
			
		||||
    {
 | 
			
		||||
      GDBusMessageFilterResult result;
 | 
			
		||||
      result = filters[n].func (connection,
 | 
			
		||||
                                message,
 | 
			
		||||
                                TRUE,
 | 
			
		||||
                                filters[n].user_data);
 | 
			
		||||
      switch (result)
 | 
			
		||||
        {
 | 
			
		||||
        case G_DBUS_MESSAGE_FILTER_RESULT_NO_EFFECT:
 | 
			
		||||
          /* do nothing */
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
          g_warning ("Treating unknown value %d for GDBusMessageFilterResult from filter "
 | 
			
		||||
                     "function on incoming message as MESSAGE_CONSUMED.", result);
 | 
			
		||||
          /* explicit fallthrough */
 | 
			
		||||
        case G_DBUS_MESSAGE_FILTER_RESULT_MESSAGE_CONSUMED:
 | 
			
		||||
          consumed_by_filter = TRUE;
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case G_DBUS_MESSAGE_FILTER_RESULT_MESSAGE_ALTERED:
 | 
			
		||||
          altered_by_filter = TRUE;
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
      if (consumed_by_filter)
 | 
			
		||||
      message = filters[n].func (connection,
 | 
			
		||||
                                 message,
 | 
			
		||||
                                 TRUE,
 | 
			
		||||
                                 filters[n].user_data);
 | 
			
		||||
      if (message == NULL)
 | 
			
		||||
        break;
 | 
			
		||||
      g_dbus_message_lock (message);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* Standard dispatch unless the filter ate the message - no need to
 | 
			
		||||
   * do anything if the message was altered
 | 
			
		||||
   */
 | 
			
		||||
  if (!consumed_by_filter)
 | 
			
		||||
  if (message != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      GDBusMessageType message_type;
 | 
			
		||||
 | 
			
		||||
@@ -2038,12 +2036,14 @@ on_worker_message_received (GDBusWorker  *worker,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (message != NULL)
 | 
			
		||||
    g_object_unref (message);
 | 
			
		||||
  g_object_unref (connection);
 | 
			
		||||
  g_free (filters);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Called in worker's thread */
 | 
			
		||||
static GDBusMessageFilterResult
 | 
			
		||||
static GDBusMessage *
 | 
			
		||||
on_worker_message_about_to_be_sent (GDBusWorker  *worker,
 | 
			
		||||
                                    GDBusMessage *message,
 | 
			
		||||
                                    gpointer      user_data)
 | 
			
		||||
@@ -2052,12 +2052,8 @@ on_worker_message_about_to_be_sent (GDBusWorker  *worker,
 | 
			
		||||
  FilterCallback *filters;
 | 
			
		||||
  guint num_filters;
 | 
			
		||||
  guint n;
 | 
			
		||||
  GDBusMessageFilterResult ret;
 | 
			
		||||
 | 
			
		||||
  //g_debug ("in on_worker_message_about_to_be_sent");
 | 
			
		||||
 | 
			
		||||
  ret = G_DBUS_MESSAGE_FILTER_RESULT_NO_EFFECT;
 | 
			
		||||
 | 
			
		||||
  g_object_ref (connection);
 | 
			
		||||
 | 
			
		||||
  /* First collect the set of callback functions */
 | 
			
		||||
@@ -2075,36 +2071,19 @@ on_worker_message_about_to_be_sent (GDBusWorker  *worker,
 | 
			
		||||
  /* then call the filters in order (without holding the lock) */
 | 
			
		||||
  for (n = 0; n < num_filters; n++)
 | 
			
		||||
    {
 | 
			
		||||
      GDBusMessageFilterResult result;
 | 
			
		||||
      result = filters[n].func (connection,
 | 
			
		||||
                                message,
 | 
			
		||||
                                FALSE,
 | 
			
		||||
                                filters[n].user_data);
 | 
			
		||||
      switch (result)
 | 
			
		||||
        {
 | 
			
		||||
        case G_DBUS_MESSAGE_FILTER_RESULT_NO_EFFECT:
 | 
			
		||||
          /* do nothing, ret might already be _ALTERED */
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
          g_warning ("Treating unknown value %d for GDBusMessageFilterResult from filter "
 | 
			
		||||
                     "function on outgoing message as MESSAGE_CONSUMED.", result);
 | 
			
		||||
          /* explicit fallthrough */
 | 
			
		||||
        case G_DBUS_MESSAGE_FILTER_RESULT_MESSAGE_CONSUMED:
 | 
			
		||||
          ret = G_DBUS_MESSAGE_FILTER_RESULT_MESSAGE_CONSUMED;
 | 
			
		||||
          goto out;
 | 
			
		||||
 | 
			
		||||
        case G_DBUS_MESSAGE_FILTER_RESULT_MESSAGE_ALTERED:
 | 
			
		||||
          ret = G_DBUS_MESSAGE_FILTER_RESULT_MESSAGE_ALTERED;
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
      g_dbus_message_lock (message);
 | 
			
		||||
      message = filters[n].func (connection,
 | 
			
		||||
                                 message,
 | 
			
		||||
                                 FALSE,
 | 
			
		||||
                                 filters[n].user_data);
 | 
			
		||||
      if (message == NULL)
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 out:
 | 
			
		||||
  g_object_unref (connection);
 | 
			
		||||
  g_free (filters);
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
  return message;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Called in worker's thread - we must not block */
 | 
			
		||||
 
 | 
			
		||||
@@ -469,29 +469,82 @@ void             g_dbus_connection_signal_unsubscribe         (GDBusConnection
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * GDBusMessageFilterFunction:
 | 
			
		||||
 * @connection: A #GDBusConnection.
 | 
			
		||||
 * @message: A #GDBusMessage.
 | 
			
		||||
 * @connection: (transfer none): A #GDBusConnection.
 | 
			
		||||
 * @message: (transfer full): A locked #GDBusMessage that the filter function takes ownership of.
 | 
			
		||||
 * @incoming: %TRUE if it is a message received from the other peer, %FALSE if it is
 | 
			
		||||
 * a message to be sent to the other peer.
 | 
			
		||||
 * @user_data: User data passed when adding the filter.
 | 
			
		||||
 *
 | 
			
		||||
 * Signature for function used in g_dbus_connection_add_filter().
 | 
			
		||||
 *
 | 
			
		||||
 * If you modify an outgoing message, make sure to return
 | 
			
		||||
 * %G_DBUS_MESSAGE_FILTER_RESULT_MESSAGE_ALTERED instead of
 | 
			
		||||
 * %G_DBUS_MESSAGE_FILTER_RESULT_NO_EFFECT so the message can be
 | 
			
		||||
 * re-serialized. If an error occurs during re-serialization, a
 | 
			
		||||
 * warning will be printed on standard error.
 | 
			
		||||
 * A filter function is passed a #GDBusMessage and expected to return
 | 
			
		||||
 * a #GDBusMessage too. Passive filter functions that don't modify the
 | 
			
		||||
 * message can simply return the @message object:
 | 
			
		||||
 * |[
 | 
			
		||||
 * static GDBusMessage *
 | 
			
		||||
 * passive_filter (GDBusConnection *connection
 | 
			
		||||
 *                 GDBusMessage    *message,
 | 
			
		||||
 *                 gboolean         incoming,
 | 
			
		||||
 *                 gpointer         user_data)
 | 
			
		||||
 * {
 | 
			
		||||
 *   /<!-- -->* inspect @message *<!-- -->/
 | 
			
		||||
 *   return message;
 | 
			
		||||
 * }
 | 
			
		||||
 * ]|
 | 
			
		||||
 * Filter functions that wants to drop a message can simply return %NULL:
 | 
			
		||||
 * |[
 | 
			
		||||
 * static GDBusMessage *
 | 
			
		||||
 * drop_filter (GDBusConnection *connection
 | 
			
		||||
 *              GDBusMessage    *message,
 | 
			
		||||
 *              gboolean         incoming,
 | 
			
		||||
 *              gpointer         user_data)
 | 
			
		||||
 * {
 | 
			
		||||
 *   if (should_drop_message)
 | 
			
		||||
 *     {
 | 
			
		||||
 *       g_object_unref (message);
 | 
			
		||||
 *       message = NULL;
 | 
			
		||||
 *     }
 | 
			
		||||
 *   return message;
 | 
			
		||||
 * }
 | 
			
		||||
 * ]|
 | 
			
		||||
 * Finally, a filter function may modify a message by copying it:
 | 
			
		||||
 * |[
 | 
			
		||||
 * static GDBusMessage *
 | 
			
		||||
 * modifying_filter (GDBusConnection *connection
 | 
			
		||||
 *                   GDBusMessage    *message,
 | 
			
		||||
 *                   gboolean         incoming,
 | 
			
		||||
 *                   gpointer         user_data)
 | 
			
		||||
 * {
 | 
			
		||||
 *   GDBusMessage *copy;
 | 
			
		||||
 *   GError *error;
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: A value from the #GDBusMessageFilterResult enumeration
 | 
			
		||||
 * describing what to do with @message.
 | 
			
		||||
 *   error = NULL;
 | 
			
		||||
 *   copy = g_dbus_message_copy (message, &error);
 | 
			
		||||
 *   /<!-- -->* handle @error being is set *<!-- -->/
 | 
			
		||||
 *   g_object_unref (message);
 | 
			
		||||
 *
 | 
			
		||||
 *   /<!-- -->* modify @copy *<!-- -->/
 | 
			
		||||
 *
 | 
			
		||||
 *   return copy;
 | 
			
		||||
 * }
 | 
			
		||||
 * ]|
 | 
			
		||||
 * If the returned #GDBusMessage is different from @message and the
 | 
			
		||||
 * serial number is unset (e.g. zero), then @message's serial number
 | 
			
		||||
 * will be used on the returned message (so in this case the returned
 | 
			
		||||
 * message must be unlocked). Additionally, if the returned message
 | 
			
		||||
 * cannot be sent on @connection, then a warning is logged to
 | 
			
		||||
 * <emphasis>standard error</emphasis>.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: (transfer full) (allow-none): A #GDBusMessage that will be freed with
 | 
			
		||||
 * g_object_unref() or %NULL to drop the message. Passive filter
 | 
			
		||||
 * functions can simply return the passed @message object.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.26
 | 
			
		||||
 */
 | 
			
		||||
typedef GDBusMessageFilterResult (*GDBusMessageFilterFunction) (GDBusConnection *connection,
 | 
			
		||||
                                                                GDBusMessage    *message,
 | 
			
		||||
                                                                gboolean         incoming,
 | 
			
		||||
                                                                gpointer         user_data);
 | 
			
		||||
typedef GDBusMessage *(*GDBusMessageFilterFunction) (GDBusConnection *connection,
 | 
			
		||||
                                                     GDBusMessage    *message,
 | 
			
		||||
                                                     gboolean         incoming,
 | 
			
		||||
                                                     gpointer         user_data);
 | 
			
		||||
 | 
			
		||||
guint g_dbus_connection_add_filter (GDBusConnection            *connection,
 | 
			
		||||
                                    GDBusMessageFilterFunction  filter_function,
 | 
			
		||||
 
 | 
			
		||||
@@ -468,14 +468,15 @@ _g_dbus_worker_emit_message_received (GDBusWorker  *worker,
 | 
			
		||||
    worker->message_received_callback (worker, message, worker->user_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GDBusMessageFilterResult
 | 
			
		||||
static GDBusMessage *
 | 
			
		||||
_g_dbus_worker_emit_message_about_to_be_sent (GDBusWorker  *worker,
 | 
			
		||||
                                              GDBusMessage *message)
 | 
			
		||||
{
 | 
			
		||||
  GDBusMessageFilterResult ret;
 | 
			
		||||
  ret = G_DBUS_MESSAGE_FILTER_RESULT_NO_EFFECT;
 | 
			
		||||
  GDBusMessage *ret;
 | 
			
		||||
  if (!worker->stopped)
 | 
			
		||||
    ret = worker->message_about_to_be_sent_callback (worker, message, worker->user_data);
 | 
			
		||||
  else
 | 
			
		||||
    ret = message;
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1243,28 +1244,35 @@ maybe_write_next_message (GDBusWorker *worker)
 | 
			
		||||
   */
 | 
			
		||||
  if (data != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      GDBusMessageFilterResult filter_result;
 | 
			
		||||
      guint32 old_serial;
 | 
			
		||||
      GDBusMessage *old_message;
 | 
			
		||||
      guchar *new_blob;
 | 
			
		||||
      gsize new_blob_size;
 | 
			
		||||
      GError *error;
 | 
			
		||||
 | 
			
		||||
      filter_result = _g_dbus_worker_emit_message_about_to_be_sent (worker, data->message);
 | 
			
		||||
      switch (filter_result)
 | 
			
		||||
      old_message = data->message;
 | 
			
		||||
      old_serial = g_dbus_message_get_serial (old_message);
 | 
			
		||||
      data->message = _g_dbus_worker_emit_message_about_to_be_sent (worker, data->message);
 | 
			
		||||
      if (data->message == old_message)
 | 
			
		||||
        {
 | 
			
		||||
        case G_DBUS_MESSAGE_FILTER_RESULT_NO_EFFECT:
 | 
			
		||||
          /* do nothing */
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case G_DBUS_MESSAGE_FILTER_RESULT_MESSAGE_CONSUMED:
 | 
			
		||||
          /* drop message */
 | 
			
		||||
          /* filters had no effect - do nothing */
 | 
			
		||||
        }
 | 
			
		||||
      else if (data->message == NULL)
 | 
			
		||||
        {
 | 
			
		||||
          /* filters dropped message */
 | 
			
		||||
          g_mutex_lock (worker->write_lock);
 | 
			
		||||
          worker->num_writes_pending -= 1;
 | 
			
		||||
          g_mutex_unlock (worker->write_lock);
 | 
			
		||||
          message_to_write_data_free (data);
 | 
			
		||||
          goto write_next;
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          /* filters altered the message -> reencode */
 | 
			
		||||
 | 
			
		||||
          if (g_dbus_message_get_serial (data->message) == 0)
 | 
			
		||||
            g_dbus_message_set_serial (data->message, old_serial);
 | 
			
		||||
 | 
			
		||||
        case G_DBUS_MESSAGE_FILTER_RESULT_MESSAGE_ALTERED:
 | 
			
		||||
          /* reencode altered message */
 | 
			
		||||
          error = NULL;
 | 
			
		||||
          new_blob = g_dbus_message_to_blob (data->message,
 | 
			
		||||
                                             &new_blob_size,
 | 
			
		||||
@@ -1286,7 +1294,6 @@ maybe_write_next_message (GDBusWorker *worker)
 | 
			
		||||
              data->blob = (gchar *) new_blob;
 | 
			
		||||
              data->blob_size = new_blob_size;
 | 
			
		||||
            }
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      write_message_async (worker,
 | 
			
		||||
 
 | 
			
		||||
@@ -39,9 +39,9 @@ typedef void (*GDBusWorkerMessageReceivedCallback) (GDBusWorker   *worker,
 | 
			
		||||
                                                    GDBusMessage  *message,
 | 
			
		||||
                                                    gpointer       user_data);
 | 
			
		||||
 | 
			
		||||
typedef GDBusMessageFilterResult (*GDBusWorkerMessageAboutToBeSentCallback) (GDBusWorker   *worker,
 | 
			
		||||
                                                                             GDBusMessage  *message,
 | 
			
		||||
                                                                             gpointer       user_data);
 | 
			
		||||
typedef GDBusMessage *(*GDBusWorkerMessageAboutToBeSentCallback) (GDBusWorker   *worker,
 | 
			
		||||
                                                                  GDBusMessage  *message,
 | 
			
		||||
                                                                  gpointer       user_data);
 | 
			
		||||
 | 
			
		||||
typedef void (*GDBusWorkerDisconnectedCallback)    (GDBusWorker   *worker,
 | 
			
		||||
                                                    gboolean       remote_peer_vanished,
 | 
			
		||||
 
 | 
			
		||||
@@ -1214,31 +1214,6 @@ typedef enum
 | 
			
		||||
  G_DBUS_MESSAGE_BYTE_ORDER_LITTLE_ENDIAN = 'l'
 | 
			
		||||
} GDBusMessageByteOrder;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * GDBusMessageFilterResult:
 | 
			
		||||
 * @G_DBUS_MESSAGE_FILTER_RESULT_NO_EFFECT: The filter function had
 | 
			
		||||
 * no effect on the message - the message will be passed on to the
 | 
			
		||||
 * next filter function and/or sent to the remote peer.
 | 
			
		||||
 * @G_DBUS_MESSAGE_FILTER_RESULT_MESSAGE_CONSUMED: The message was
 | 
			
		||||
 * consumed by the filter function and will be dropped - the message
 | 
			
		||||
 * will not be passed to other filter functions and/or sent to the
 | 
			
		||||
 * remote peer.
 | 
			
		||||
 * @G_DBUS_MESSAGE_FILTER_RESULT_MESSAGE_ALTERED: The message was
 | 
			
		||||
 * modified - the message will still be passed on to the next filter
 | 
			
		||||
 * function and/or sent to the remote peer.
 | 
			
		||||
 *
 | 
			
		||||
 * Possible return values for #GDBusMessageFilterFunction when
 | 
			
		||||
 * handling a #GDBusMessage.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.26
 | 
			
		||||
 */
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
  G_DBUS_MESSAGE_FILTER_RESULT_NO_EFFECT,
 | 
			
		||||
  G_DBUS_MESSAGE_FILTER_RESULT_MESSAGE_CONSUMED,
 | 
			
		||||
  G_DBUS_MESSAGE_FILTER_RESULT_MESSAGE_ALTERED
 | 
			
		||||
} GDBusMessageFilterResult;
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __GIO_ENUMS_H__ */
 | 
			
		||||
 
 | 
			
		||||
@@ -62,13 +62,13 @@ static const GDBusInterfaceVTable boo_vtable =
 | 
			
		||||
  NULL  /* _set_property */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static GDBusMessageFilterResult
 | 
			
		||||
static GDBusMessage *
 | 
			
		||||
some_filter_func (GDBusConnection *connection,
 | 
			
		||||
                  GDBusMessage    *message,
 | 
			
		||||
                  gboolean         incoming,
 | 
			
		||||
                  gpointer         user_data)
 | 
			
		||||
{
 | 
			
		||||
  return G_DBUS_MESSAGE_FILTER_RESULT_NO_EFFECT;
 | 
			
		||||
  return message;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -686,7 +686,7 @@ typedef struct
 | 
			
		||||
  guint32 serial;
 | 
			
		||||
} FilterData;
 | 
			
		||||
 | 
			
		||||
static GDBusMessageFilterResult
 | 
			
		||||
static GDBusMessage *
 | 
			
		||||
filter_func (GDBusConnection *connection,
 | 
			
		||||
             GDBusMessage    *message,
 | 
			
		||||
             gboolean         incoming,
 | 
			
		||||
@@ -706,40 +706,53 @@ filter_func (GDBusConnection *connection,
 | 
			
		||||
      data->num_outgoing += 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return G_DBUS_MESSAGE_FILTER_RESULT_NO_EFFECT;
 | 
			
		||||
  return message;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  GDBusMessageFilterResult incoming;
 | 
			
		||||
  GDBusMessageFilterResult outgoing;
 | 
			
		||||
  gboolean alter_incoming;
 | 
			
		||||
  gboolean alter_outgoing;
 | 
			
		||||
} FilterEffects;
 | 
			
		||||
 | 
			
		||||
static GDBusMessageFilterResult
 | 
			
		||||
static GDBusMessage *
 | 
			
		||||
other_filter_func (GDBusConnection *connection,
 | 
			
		||||
                   GDBusMessage    *message,
 | 
			
		||||
                   gboolean         incoming,
 | 
			
		||||
                   gpointer         user_data)
 | 
			
		||||
{
 | 
			
		||||
  FilterEffects *effects = user_data;
 | 
			
		||||
  GDBusMessageFilterResult ret;
 | 
			
		||||
  GDBusMessage *ret;
 | 
			
		||||
  gboolean alter;
 | 
			
		||||
 | 
			
		||||
  if (incoming)
 | 
			
		||||
    ret = effects->incoming;
 | 
			
		||||
    alter = effects->alter_incoming;
 | 
			
		||||
  else
 | 
			
		||||
    ret = effects->outgoing;
 | 
			
		||||
    alter = effects->alter_outgoing;
 | 
			
		||||
 | 
			
		||||
  if (ret == G_DBUS_MESSAGE_FILTER_RESULT_MESSAGE_ALTERED)
 | 
			
		||||
  if (alter)
 | 
			
		||||
    {
 | 
			
		||||
      GDBusMessage *copy;
 | 
			
		||||
      GVariant *body;
 | 
			
		||||
      gchar *s;
 | 
			
		||||
      gchar *s2;
 | 
			
		||||
      body = g_dbus_message_get_body (message);
 | 
			
		||||
 | 
			
		||||
      copy = g_dbus_message_copy (message, NULL);
 | 
			
		||||
      g_object_unref (message);
 | 
			
		||||
 | 
			
		||||
      body = g_dbus_message_get_body (copy);
 | 
			
		||||
      g_variant_get (body, "(s)", &s);
 | 
			
		||||
      s2 = g_strdup_printf ("MOD: %s", s);
 | 
			
		||||
      g_dbus_message_set_body (message, g_variant_new ("(s)", s2));
 | 
			
		||||
      g_dbus_message_set_body (copy, g_variant_new ("(s)", s2));
 | 
			
		||||
      g_free (s2);
 | 
			
		||||
      g_free (s);
 | 
			
		||||
 | 
			
		||||
      ret = copy;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      ret = message;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
@@ -784,6 +797,7 @@ test_connection_filter (void)
 | 
			
		||||
  GDBusConnection *c;
 | 
			
		||||
  FilterData data;
 | 
			
		||||
  GDBusMessage *m;
 | 
			
		||||
  GDBusMessage *m2;
 | 
			
		||||
  GDBusMessage *r;
 | 
			
		||||
  GError *error;
 | 
			
		||||
  guint filter_id;
 | 
			
		||||
@@ -819,21 +833,25 @@ test_connection_filter (void)
 | 
			
		||||
  while (data.num_handled == 0)
 | 
			
		||||
    g_thread_yield ();
 | 
			
		||||
 | 
			
		||||
  g_dbus_message_set_serial (m, 0);
 | 
			
		||||
  g_dbus_connection_send_message (c, m, G_DBUS_SEND_MESSAGE_FLAGS_NONE, &data.serial, &error);
 | 
			
		||||
  m2 = g_dbus_message_copy (m, &error);
 | 
			
		||||
  g_assert_no_error (error);
 | 
			
		||||
  g_dbus_connection_send_message (c, m2, G_DBUS_SEND_MESSAGE_FLAGS_NONE, &data.serial, &error);
 | 
			
		||||
  g_object_unref (m2);
 | 
			
		||||
  g_assert_no_error (error);
 | 
			
		||||
 | 
			
		||||
  while (data.num_handled == 1)
 | 
			
		||||
    g_thread_yield ();
 | 
			
		||||
 | 
			
		||||
  g_dbus_message_set_serial (m, 0);
 | 
			
		||||
  m2 = g_dbus_message_copy (m, &error);
 | 
			
		||||
  g_assert_no_error (error);
 | 
			
		||||
  r = g_dbus_connection_send_message_with_reply_sync (c,
 | 
			
		||||
                                                      m,
 | 
			
		||||
                                                      m2,
 | 
			
		||||
                                                      G_DBUS_SEND_MESSAGE_FLAGS_NONE,
 | 
			
		||||
                                                      -1,
 | 
			
		||||
                                                      &data.serial,
 | 
			
		||||
                                                      NULL, /* GCancellable */
 | 
			
		||||
                                                      &error);
 | 
			
		||||
  g_object_unref (m2);
 | 
			
		||||
  g_assert_no_error (error);
 | 
			
		||||
  g_assert (r != NULL);
 | 
			
		||||
  g_object_unref (r);
 | 
			
		||||
@@ -841,14 +859,16 @@ test_connection_filter (void)
 | 
			
		||||
 | 
			
		||||
  g_dbus_connection_remove_filter (c, filter_id);
 | 
			
		||||
 | 
			
		||||
  g_dbus_message_set_serial (m, 0);
 | 
			
		||||
  m2 = g_dbus_message_copy (m, &error);
 | 
			
		||||
  g_assert_no_error (error);
 | 
			
		||||
  r = g_dbus_connection_send_message_with_reply_sync (c,
 | 
			
		||||
                                                      m,
 | 
			
		||||
                                                      m2,
 | 
			
		||||
                                                      G_DBUS_SEND_MESSAGE_FLAGS_NONE,
 | 
			
		||||
                                                      -1,
 | 
			
		||||
                                                      &data.serial,
 | 
			
		||||
                                                      NULL, /* GCancellable */
 | 
			
		||||
                                                      &error);
 | 
			
		||||
  g_object_unref (m2);
 | 
			
		||||
  g_assert_no_error (error);
 | 
			
		||||
  g_assert (r != NULL);
 | 
			
		||||
  g_object_unref (r);
 | 
			
		||||
@@ -874,15 +894,14 @@ test_connection_filter (void)
 | 
			
		||||
  g_source_remove (timeout_mainloop_id);
 | 
			
		||||
  g_dbus_connection_signal_unsubscribe (c, signal_handler_id);
 | 
			
		||||
 | 
			
		||||
  /* now test all nine combinations... */
 | 
			
		||||
 | 
			
		||||
  /* now test some combinations... */
 | 
			
		||||
  filter_id = g_dbus_connection_add_filter (c,
 | 
			
		||||
                                            other_filter_func,
 | 
			
		||||
                                            &effects,
 | 
			
		||||
                                            NULL);
 | 
			
		||||
  /* -- */
 | 
			
		||||
  effects.incoming = G_DBUS_MESSAGE_FILTER_RESULT_NO_EFFECT;
 | 
			
		||||
  effects.outgoing = G_DBUS_MESSAGE_FILTER_RESULT_NO_EFFECT;
 | 
			
		||||
  effects.alter_incoming = FALSE;
 | 
			
		||||
  effects.alter_outgoing = FALSE;
 | 
			
		||||
  error = NULL;
 | 
			
		||||
  result = g_dbus_connection_call_sync (c,
 | 
			
		||||
                                        "com.example.TestService",      /* bus name */
 | 
			
		||||
@@ -900,8 +919,8 @@ test_connection_filter (void)
 | 
			
		||||
  g_assert_cmpstr (s, ==, "You greeted me with 'Cat'. Thanks!");
 | 
			
		||||
  g_variant_unref (result);
 | 
			
		||||
  /* -- */
 | 
			
		||||
  effects.incoming = G_DBUS_MESSAGE_FILTER_RESULT_MESSAGE_ALTERED;
 | 
			
		||||
  effects.outgoing = G_DBUS_MESSAGE_FILTER_RESULT_MESSAGE_ALTERED;
 | 
			
		||||
  effects.alter_incoming = TRUE;
 | 
			
		||||
  effects.alter_outgoing = TRUE;
 | 
			
		||||
  error = NULL;
 | 
			
		||||
  result = g_dbus_connection_call_sync (c,
 | 
			
		||||
                                        "com.example.TestService",      /* bus name */
 | 
			
		||||
 
 | 
			
		||||
@@ -1313,7 +1313,7 @@ test_credentials (void)
 | 
			
		||||
#define OVERFLOW_NUM_SIGNALS 5000
 | 
			
		||||
#define OVERFLOW_TIMEOUT_SEC 10
 | 
			
		||||
 | 
			
		||||
static GDBusMessageFilterResult
 | 
			
		||||
static GDBusMessage *
 | 
			
		||||
overflow_filter_func (GDBusConnection *connection,
 | 
			
		||||
                      GDBusMessage    *message,
 | 
			
		||||
                      gboolean         incoming,
 | 
			
		||||
@@ -1321,7 +1321,7 @@ overflow_filter_func (GDBusConnection *connection,
 | 
			
		||||
{
 | 
			
		||||
  volatile gint *counter = user_data;
 | 
			
		||||
  *counter += 1;
 | 
			
		||||
  return G_DBUS_MESSAGE_FILTER_RESULT_NO_EFFECT;
 | 
			
		||||
  return message;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user