GNOME Bugzilla – Bug 621945
Filter outgoing messages in GDBusConnection
Last modified: 2010-07-16 15:16:35 UTC
I am developing a server on GIO. The server need re-dispatch all outgoing messages to other connections by match rules like dbus-daemon. But I can not find a way to get those outgoing messages. Do you have any suggestion? Or could you add a new API to get all outgoing messages when those messages are sent via socket. For example g_dbus_connection_add_outgoing_filter. Thanks.
Yeah, I thought about this the other day and it would probably be nice if GDBusMessageFilterFunction took a boolean for the direction of the message. It's an ABI/API change but I don't think that matters too much.
I think it is OK. Another idea is add parameter of g_dbus_connection_add_filter to specify the filter's directions (in, out, or both).
Created attachment 164053 [details] [review] make connection filter support outgoing message I created a patch for this requirement. Please check it.
Created attachment 164072 [details] [review] Update the patch. Update the patch to fix a dead lock.
Some comments on the patch - We shouldn't send outgoing message at all if a filter returns TRUE (and we need to document that as well). Which means we need call the filter before writing the message out. Which means that the CB should be called MessageAboutToBeSent instead of MessageSent - Need a comment in gdbusprivate.c:write_message_in_idle_cb() explaining why it's fine to call out to user code and then write_message() without holding the lock > --- a/gio/tests/gdbus-connection.c > +++ b/gio/tests/gdbus-connection.c > @@ -561,11 +561,17 @@ typedef struct > static gboolean > filter_func (GDBusConnection *connection, > GDBusMessage *message, > + gboolean is_incoming, > gpointer user_data) > { > FilterData *data = user_data; > guint32 reply_serial; > > + if (!is_incoming) { > + /* g_debug ("outgoing message"); */ > + return FALSE; > + } > + > reply_serial = g_dbus_message_get_reply_serial (message); - There's coding style issues (braces misplaced) - Shouldn't return in the middle of a function (use goto or conditionals instead) - Should actually test that things work - for example, counting the number of times we've been called with @is_incoming == FALSE is good enough I've reworked your patch with these fixes.
Fixed here http://git.gnome.org/browse/glib/commit/?id=45411ccbe3c9d1b08332942d1e7b594330688126 Thanks!
Hi, David, I found a problem with the filter. It looks like the message has been serialized to data buffer before calling the filter for outgoing messages. So we can change the attributes of message in the filter (I need change the sender of the message), but it will not effect the buffer to be write into the socket. Could you change the other of serializing the message and calling filter for outgoing messages? Thanks.
(In reply to comment #7) > Hi, David, > > I found a problem with the filter. It looks like the message has been > serialized to data buffer before calling the filter for outgoing messages. So > we can change the attributes of message in the filter (I need change the sender > of the message), but it will not effect the buffer to be write into the socket. > > Could you change the other of serializing the message and calling filter for > outgoing messages? Thanks. I don't think we can. The reason we serialize the message to data *before* this is to be able to return errors at message submission time (e.g. in another thread). If we were to do this we would need to somehow check that a message has been altered between running filters and after (g_dbus_message_get_last_change() etc.) and that leads to a lot of overhead/complexity. As a work-around, just consume the message (returning TRUE in the handler) and then submit the message again using g_dbus_connection_send_message().
How about call the filter in the default main loop thread for outgoing message(in g_dbus_connection_send_lock function)? It can be before the serializing the message.
(In reply to comment #9) > How about call the filter in the default main loop thread for outgoing > message(in g_dbus_connection_send_lock function)? It can be before the > serializing the message. Could be - I've raised this in bug 624546.