[telepathy-gabble/master] Simplify gabble_jingle_session_send, fixing a leak

Will Thompson will.thompson at collabora.co.uk
Mon Apr 27 09:43:47 PDT 2009


Previously, gabble_jingle_session_send passed the JingleSession as the
weak object to _gabble_connection_send_with_reply. This worked, but
meant that the jingle_reply_ctx was leaked for IQs that didn't return
before the session was terminated.

By removing some unused generality from the callbacks, the context
struct was removed completely. Now the weak object is supplied by the
caller; since only two callers actually use the IQ reply, this wasn't
invasive to fix.
---
 src/jingle-content.c |   13 +++----
 src/jingle-session.c |   83 ++++++++++++++++++++++++--------------------------
 src/jingle-session.h |   10 +++--
 3 files changed, 52 insertions(+), 54 deletions(-)

diff --git a/src/jingle-content.c b/src/jingle-content.c
index 3df57e3..56689dd 100644
--- a/src/jingle-content.c
+++ b/src/jingle-content.c
@@ -959,17 +959,16 @@ gabble_jingle_content_change_direction (GabbleJingleContent *c,
 }
 
 static void
-_on_remove_reply (GabbleJingleSession *sess, gboolean success,
-    LmMessage *reply, gpointer user_data)
+_on_remove_reply (GObject *c_as_obj,
+    gboolean success,
+    LmMessage *reply)
 {
-  GabbleJingleContent *c = GABBLE_JINGLE_CONTENT (user_data);
+  GabbleJingleContent *c = GABBLE_JINGLE_CONTENT (c_as_obj);
   GabbleJingleContentPrivate *priv = c->priv;
 
   g_assert (priv->state == JINGLE_CONTENT_STATE_REMOVING);
 
   g_signal_emit (c, signals[REMOVED], 0);
-
-  g_object_unref (c);
 }
 
 void
@@ -1004,8 +1003,8 @@ gabble_jingle_content_remove (GabbleJingleContent *c, gboolean signal_peer)
       msg = gabble_jingle_session_new_message (c->session,
           JINGLE_ACTION_CONTENT_REMOVE, &sess_node);
       gabble_jingle_content_produce_node (c, sess_node, FALSE);
-      g_object_ref (c);
-      gabble_jingle_session_send (c->session, msg, _on_remove_reply, c);
+      gabble_jingle_session_send (c->session, msg, _on_remove_reply,
+          (GObject *) c);
     }
   else
     {
diff --git a/src/jingle-session.c b/src/jingle-session.c
index 002b49e..d1e53bd 100644
--- a/src/jingle-session.c
+++ b/src/jingle-session.c
@@ -1441,74 +1441,71 @@ _fill_content (GabbleJingleSession *sess,
     }
 }
 
-struct jingle_reply_ctx {
-  JingleReplyHandler handler;
-  gpointer user_data;
-};
-
 static LmHandlerResult
 _process_reply (GabbleConnection *conn,
-    LmMessage *sent, LmMessage *reply, GObject *obj, gpointer user_data)
+    LmMessage *sent,
+    LmMessage *reply,
+    GObject *obj,
+    gpointer cb_)
 {
-  GabbleJingleSession *sess = GABBLE_JINGLE_SESSION (obj);
-  struct jingle_reply_ctx *ctx = user_data;
+  JingleReplyHandler cb = cb_;
 
-  if (lm_message_get_sub_type (reply) == LM_MESSAGE_SUB_TYPE_RESULT)
-    {
-      ctx->handler (sess, TRUE, reply, ctx->user_data);
-    }
-  else
-    {
-      ctx->handler (sess, FALSE, reply, ctx->user_data);
-    }
+  cb (obj, (lm_message_get_sub_type (reply) == LM_MESSAGE_SUB_TYPE_RESULT),
+      reply);
 
-  g_free (ctx);
   return LM_HANDLER_RESULT_REMOVE_MESSAGE;
 }
 
+/**
+ * gabble_jingle_session_send:
+ * @sess: a session
+ * @msg: a stanza, of which this function will take ownership
+ * @cb: callback for the IQ reply, or %NULL to ignore the reply
+ * @weak_object: an object to pass to @cb, or %NULL
+ *
+ * Sends an IQ, optionally calling @cb for the reply. If @weak_object is not
+ * NULL, @cb will only be called if @weak_object is still alive.
+ */
 void
-gabble_jingle_session_send (GabbleJingleSession *sess, LmMessage *msg,
-    JingleReplyHandler cb, gpointer user_data)
+gabble_jingle_session_send (GabbleJingleSession *sess,
+    LmMessage *msg,
+    JingleReplyHandler cb,
+    GObject *weak_object)
 {
-  GabbleJingleSessionPrivate *priv = sess->priv;
-
   if (cb != NULL)
-    {
-      struct jingle_reply_ctx *ctx = g_new0 (struct jingle_reply_ctx, 1);
-
-      ctx->handler = cb;
-      ctx->user_data = user_data;
-
-      _gabble_connection_send_with_reply (priv->conn, msg,
-          _process_reply, G_OBJECT (sess), ctx, NULL);
-    }
+    _gabble_connection_send_with_reply (sess->priv->conn, msg,
+        _process_reply, weak_object, cb, NULL);
   else
-    {
-      _gabble_connection_send_with_reply (priv->conn, msg,
-          NULL, NULL, NULL, NULL);
-    }
+    _gabble_connection_send_with_reply (sess->priv->conn, msg,
+        NULL, NULL, NULL, NULL);
 
   lm_message_unref (msg);
 }
 
 static void
-_on_initiate_reply (GabbleJingleSession *sess, gboolean success,
-    LmMessage *reply, gpointer user_data)
+_on_initiate_reply (GObject *sess_as_obj,
+    gboolean success,
+    LmMessage *reply)
 {
+  GabbleJingleSession *sess = GABBLE_JINGLE_SESSION (sess_as_obj);
+
   if (success)
-      set_state (sess, JS_STATE_PENDING_INITIATED, 0);
+    set_state (sess, JS_STATE_PENDING_INITIATED, 0);
   else
-      set_state (sess, JS_STATE_ENDED, TP_CHANNEL_GROUP_CHANGE_REASON_NONE);
+    set_state (sess, JS_STATE_ENDED, TP_CHANNEL_GROUP_CHANGE_REASON_NONE);
 }
 
 static void
-_on_accept_reply (GabbleJingleSession *sess, gboolean success,
-    LmMessage *reply, gpointer user_data)
+_on_accept_reply (GObject *sess_as_obj,
+    gboolean success,
+    LmMessage *reply)
 {
+  GabbleJingleSession *sess = GABBLE_JINGLE_SESSION (sess_as_obj);
+
   if (success)
-      set_state (sess, JS_STATE_ACTIVE, 0);
+    set_state (sess, JS_STATE_ACTIVE, 0);
   else
-      set_state (sess, JS_STATE_ENDED, TP_CHANNEL_GROUP_CHANGE_REASON_NONE);
+    set_state (sess, JS_STATE_ENDED, TP_CHANNEL_GROUP_CHANGE_REASON_NONE);
 }
 
 static gboolean
@@ -1576,7 +1573,7 @@ try_session_initiate_or_accept (GabbleJingleSession *sess)
 
   msg = gabble_jingle_session_new_message (sess, action, &sess_node);
   _map_initial_contents (sess, _fill_content, sess_node);
-  gabble_jingle_session_send (sess, msg, handler, NULL);
+  gabble_jingle_session_send (sess, msg, handler, (GObject *) sess);
   set_state (sess, new_state, 0);
 
   /* now all initial contents can transmit their candidates */
diff --git a/src/jingle-session.h b/src/jingle-session.h
index eaeef83..a5379ba 100644
--- a/src/jingle-session.h
+++ b/src/jingle-session.h
@@ -103,10 +103,12 @@ gabble_jingle_session_add_content (GabbleJingleSession *sess, JingleMediaType mt
 GType gabble_jingle_session_get_content_type (GabbleJingleSession *);
 GList *gabble_jingle_session_get_contents (GabbleJingleSession *sess);
 
-typedef void (*JingleReplyHandler) (GabbleJingleSession *, gboolean success,
-    LmMessage *reply, gpointer user_data);
-void gabble_jingle_session_send (GabbleJingleSession *sess, LmMessage *msg,
-    JingleReplyHandler cb, gpointer user_data);
+typedef void (*JingleReplyHandler) (GObject *, gboolean success,
+    LmMessage *reply);
+void gabble_jingle_session_send (GabbleJingleSession *sess,
+    LmMessage *msg,
+    JingleReplyHandler cb,
+    GObject *weak_object);
 
 void gabble_jingle_session_send_held (GabbleJingleSession *sess, gboolean held);
 
-- 
1.5.6.5




More information about the telepathy-commits mailing list