Connection: cancel connect_async when Disconnect() is called
Will Thompson
11 years ago
151 | 151 | */ |
152 | 152 | gboolean sconn_connected; |
153 | 153 | |
154 | /* Used for idle_server_connection_connect_async(). */ | |
155 | GCancellable *connect_cancellable; | |
156 | ||
154 | 157 | /* When we sent a PING to the server which it hasn't PONGed for yet, or 0 if |
155 | 158 | * there isn't a PING outstanding. |
156 | 159 | */ |
407 | 410 | priv->conn = NULL; |
408 | 411 | } |
409 | 412 | |
413 | g_clear_object (&priv->connect_cancellable); | |
414 | ||
410 | 415 | if (priv->queued_aliases_owners) |
411 | 416 | tp_handle_set_destroy(priv->queued_aliases_owners); |
412 | 417 | |
619 | 624 | if (priv->conn == NULL) { |
620 | 625 | g_idle_add(_finish_shutdown_idle_func, self); |
621 | 626 | } else if (!priv->sconn_connected) { |
622 | IDLE_DEBUG("TODO: cancel connecting"); | |
627 | IDLE_DEBUG("cancelling connection"); | |
628 | g_cancellable_cancel (priv->connect_cancellable); | |
623 | 629 | } else { |
624 | 630 | idle_server_connection_disconnect_async(priv->conn, NULL, NULL, NULL); |
625 | 631 | } |
761 | 767 | g_signal_connect(sconn, "disconnected", (GCallback)(sconn_disconnected_cb), conn); |
762 | 768 | |
763 | 769 | priv->conn = sconn; |
764 | idle_server_connection_connect_async(sconn, NULL, _connection_connect_ready, conn); | |
770 | g_warn_if_fail (priv->connect_cancellable == NULL); | |
771 | priv->connect_cancellable = g_cancellable_new (); | |
772 | idle_server_connection_connect_async(sconn, priv->connect_cancellable, _connection_connect_ready, conn); | |
765 | 773 | } |
766 | 774 | |
767 | 775 | static gboolean keepalive_timeout_cb(gpointer user_data); |
430 | 430 | |
431 | 431 | result = g_simple_async_result_new(G_OBJECT(conn), callback, user_data, idle_server_connection_connect_async); |
432 | 432 | |
433 | task = g_task_new (conn, cancellable, | |
434 | _connect_to_host_ready, result); | |
433 | task = g_task_new (conn, cancellable, _connect_to_host_ready, result); | |
435 | 434 | g_task_run_in_thread (task, _connect_in_thread); |
436 | 435 | |
437 | 436 | change_state(conn, SERVER_CONNECTION_STATE_CONNECTING, SERVER_CONNECTION_STATE_REASON_REQUESTED); |
5 | 5 | connect/connect-reject-ssl.py \ |
6 | 6 | connect/connect-fail.py \ |
7 | 7 | connect/connect-fail-ssl.py \ |
8 | connect/disconnect-before-socket-connected.py \ | |
8 | 9 | connect/disconnect-during-cert-verification.py \ |
9 | 10 | connect/ping.py \ |
10 | 11 | connect/server-quit-ignore.py \ |
0 | """ | |
1 | Test disconnecting before the TCP session is established. | |
2 | """ | |
3 | ||
4 | from idletest import exec_test | |
5 | from servicetest import call_async | |
6 | ||
7 | def test(q, bus, conn, stream): | |
8 | conn.Connect() | |
9 | q.expect('dbus-signal', signal='StatusChanged', args=[1, 1]) | |
10 | ||
11 | # We want the call to Disconnect to reach Idle before the call to | |
12 | # g_socket_client_connect_to_host(), which connects to this Python process, | |
13 | # completes. I tried making the Twisted infrastructure stop calling | |
14 | # .accept() but that doesn't seem to have any effect. | |
15 | # | |
16 | # But! All is not lost! Making a blocking call to Disconnect() does the | |
17 | # job, because we block in libdbus and Twisted doesn't get a chance to poll | |
18 | # the listening socket until Disconnect() returns. | |
19 | conn.Disconnect() | |
20 | ||
21 | # The bug was that Idle would not try to cancel the in-progress connection | |
22 | # attempt. It worked when the connection was blocked on TLS verification | |
23 | # (see disconnect-during-cert-verification.py) because closing that channel | |
24 | # (as a side-effect of disconnecting) caused the TCP connection attempt to | |
25 | # fail, but didn't work in this case. | |
26 | q.expect('dbus-signal', signal='StatusChanged', args=[2, 1]) | |
27 | ||
28 | if __name__ == '__main__': | |
29 | exec_test(test) | |
30 |