summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2013-06-03 10:38:04 +0100
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2013-06-04 12:31:57 +0100
commit92700fd33acbe264f1794cf0f3a39d3ad5692ccf (patch)
tree988983f4b9a358f6f3eba9a9832f992ee135579c
parent0561059639160cbd11e1764ef861348c0c23831c (diff)
WockyJingleFactory: ref session while calling parse()
wocky_jingle_session_parse() advances the session's state machine. In particular, it may cause termination, which causes the session to be removed from the factory's hash table, which may cause its last ref to be released. Until recently, this would have gone unnoticed, but wocky_jingle_session_acknowledge_iq() now emits a signal from the session (to check whether it has the "is Google webmail" quirk), and that causes a check that it is in fact still a valid session object. Also correct a misleading comment spotted while debugging this: priv->sessions owns both key and sess. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=65131 Signed-off-by: Simon McVittie <simon.mcvittie@collabora.co.uk> Reviewed-by: Xavier Claessens <xavier.claessens@collabora.co.uk>
-rw-r--r--wocky/wocky-jingle-factory.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/wocky/wocky-jingle-factory.c b/wocky/wocky-jingle-factory.c
index f099df2..3d4237d 100644
--- a/wocky/wocky-jingle-factory.c
+++ b/wocky/wocky-jingle-factory.c
@@ -405,6 +405,11 @@ jingle_cb (
if (sess == NULL)
goto REQUEST_ERROR;
+ else
+ /* One of the possible outcomes of wocky_jingle_session_parse() is that
+ * the Jingle session is terminated, which removes it from our
+ * hash table, which could release its last ref. */
+ g_object_ref (sess);
/* now act on the message */
if (!wocky_jingle_session_parse (sess, action, msg, &error))
@@ -422,6 +427,7 @@ jingle_cb (
/* all went well, we can acknowledge the IQ */
wocky_jingle_session_acknowledge_iq (sess, msg);
+ g_object_unref (sess);
return TRUE;
REQUEST_ERROR:
@@ -430,8 +436,13 @@ REQUEST_ERROR:
wocky_porter_send_iq_gerror (porter, msg, error);
g_error_free (error);
- if (sess != NULL && new_session)
- wocky_jingle_session_terminate (sess, WOCKY_JINGLE_REASON_UNKNOWN, NULL, NULL);
+ if (sess != NULL)
+ {
+ if (new_session)
+ wocky_jingle_session_terminate (sess, WOCKY_JINGLE_REASON_UNKNOWN, NULL, NULL);
+
+ g_object_unref (sess);
+ }
return TRUE;
}
@@ -510,7 +521,7 @@ create_session (WockyJingleFactory *fac,
g_signal_connect (sess, "terminated",
(GCallback) session_terminated_cb, fac);
- /* Takes ownership of key */
+ /* Takes ownership of key and sess */
g_hash_table_insert (priv->sessions, key, sess);
DEBUG ("new session (%s, %s) @ %p", jid, sid_, sess);