[Telepathy-commits] [telepathy-idle/master] Handle buggy servers that don't quit properly
Jonathon Jongsma
jonathon.jongsma at collabora.co.uk
Fri Feb 13 17:43:18 PST 2009
This fix kills 2 related bugs at once (and thus fixes both of the tests that I
just added on this branch).
1. It disables receiving further messages after we send our QUIT message, so
that we don't process a stray "welcome" message and accidentally try to
transition to CONNECTED state while we're in the middle of disconnecting.
2. Schedules a forceful server disconnection for 2s after we send our QUIT
message in the case that the remote server does not close the socket. This
means that we send the dbus method return for Disconnect() at most 2s after
receiving it, rather than depending on the remote server to disconnect us
before we send the dbus method return. I suppose I could have just
disconnected immediately rather than scheduling it for 2s in the future, but
I wanted to stay as close to current behavior as possible.
---
src/idle-connection.c | 22 ++++++++++++++++++++++
1 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/src/idle-connection.c b/src/idle-connection.c
index 6c2d645..52faabf 100644
--- a/src/idle-connection.c
+++ b/src/idle-connection.c
@@ -152,6 +152,7 @@ struct _IdleConnectionPrivate {
/* if we are quitting asynchronously */
gboolean quitting;
+ guint force_disconnect_id;
/* AliasChanged aggregation */
GPtrArray *queued_aliases;
@@ -426,6 +427,15 @@ static gboolean _finish_shutdown_idle_func(gpointer data) {
return FALSE;
}
+static gboolean
+_force_disconnect (gpointer data)
+{
+ IdleConnection *conn = IDLE_CONNECTION(data);
+ IdleConnectionPrivate *priv = IDLE_CONNECTION_GET_PRIVATE(conn);
+ idle_server_connection_iface_disconnect(priv->conn, NULL);
+ return FALSE;
+}
+
static void _iface_disconnected(TpBaseConnection *self) {
IdleConnection *conn = IDLE_CONNECTION(self);
IdleConnectionPrivate *priv = IDLE_CONNECTION_GET_PRIVATE(conn);
@@ -433,6 +443,11 @@ static void _iface_disconnected(TpBaseConnection *self) {
send_quit_request(conn);
priv->quitting = TRUE;
+ /* don't handle any more messages, we're quitting. See e.g. bug #19762 */
+ idle_parser_remove_handlers_by_data(conn->parser, conn);
+ /* schedule forceful disconnect for 2 seconds if the remote server doesn't
+ * respond or disconnect before then */
+ priv->force_disconnect_id = g_timeout_add_seconds(2, _force_disconnect, conn);
}
static void _iface_shut_down(TpBaseConnection *self) {
@@ -519,6 +534,13 @@ static void sconn_status_changed_cb(IdleServerConnectionIface *sconn, IdleServer
IdleConnectionPrivate *priv = IDLE_CONNECTION_GET_PRIVATE(conn);
TpConnectionStatusReason tp_reason;
+ /* cancel scheduled forced disconnect since we are now disconnected */
+ if (state == SERVER_CONNECTION_STATE_NOT_CONNECTED &&
+ priv->force_disconnect_id) {
+ g_source_remove(priv->force_disconnect_id);
+ priv->force_disconnect_id = 0;
+ }
+
IDLE_DEBUG("called with state %u", state);
switch (reason) {
--
1.5.6.5
More information about the telepathy-commits
mailing list