From a7800682c2a2fcd9bb5c85d2f5f965486b3a72d5 Mon Sep 17 00:00:00 2001 From: rowanbeentje Date: Sat, 27 Mar 2010 22:49:10 +0000 Subject: - Improve MCPConnection behaviour with respect to run loops and proxies, improving both proxy disconnection and reconnection after dropped connections - Slightly tweak SPSSHTunnel to improve proxy behaviour --- Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m | 36 +++++++++++++++++----- 1 file changed, 29 insertions(+), 7 deletions(-) (limited to 'Frameworks/MCPKit/MCPFoundationKit') diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m b/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m index 549d0013..8fc42a3e 100644 --- a/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m +++ b/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m @@ -461,28 +461,50 @@ static BOOL sTruncateLongFieldInLogs = YES; mConnected = NO; isDisconnecting = NO; - // If there is a tunnel, ensure it's disconnected and attempt to reconnect it in blocking fashion + // If there is a proxy, ensure it's disconnected and attempt to reconnect it in blocking fashion if (connectionProxy) { [connectionProxy setConnectionStateChangeSelector:nil delegate:nil]; if ([connectionProxy state] != PROXY_STATE_IDLE) [connectionProxy disconnect]; + + // Loop until the proxy has disconnected or the connection timeout has passed + NSDate *proxyDisconnectStartDate = [NSDate date], *eventLoopStartDate; + while ([connectionProxy state] != PROXY_STATE_IDLE + && [[NSDate date] timeIntervalSinceDate:proxyDisconnectStartDate] < connectionTimeout) + { + eventLoopStartDate = [NSDate date]; + [[NSRunLoop currentRunLoop] runMode:NSModalPanelRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.25]]; + if ([[NSDate date] timeIntervalSinceDate:eventLoopStartDate] < 0.25) { + usleep(250000 - (100000 * [[NSDate date] timeIntervalSinceDate:eventLoopStartDate])); + } + } + + // Reconnect the proxy, looping up to the connection timeout [connectionProxy connect]; - NSDate *tunnelStartDate = [NSDate date], *interfaceInteractionTimer; - - // Allow the tunnel to attempt to connect in a loop + NSDate *proxyStartDate = [NSDate date], *interfaceInteractionTimer; while (1) { + + // If the proxy has connected, break out of the loop if ([connectionProxy state] == PROXY_STATE_CONNECTED) { connectionPort = [connectionProxy localPort]; break; } - if ([[NSDate date] timeIntervalSinceDate:tunnelStartDate] > (connectionTimeout + 1)) { + + // If the proxy connection attempt time has exceeded the timeout, abort. + if ([[NSDate date] timeIntervalSinceDate:proxyStartDate] > (connectionTimeout + 1)) { [connectionProxy disconnect]; break; } - // Process events for a short time, allowing dialogs to be shown but waiting for the tunnel + // Process events for a short time, allowing dialogs to be shown but waiting for + // the proxy. Capture how long this interface action took, so that if it was + // longer than the time alloted it can be added to the connection timeout. interfaceInteractionTimer = [NSDate date]; [[NSRunLoop currentRunLoop] runMode:NSModalPanelRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.25]]; - tunnelStartDate = [tunnelStartDate addTimeInterval:([[NSDate date] timeIntervalSinceDate:interfaceInteractionTimer] - 0.25)]; + if ([[NSDate date] timeIntervalSinceDate:interfaceInteractionTimer] > 0.25) { + proxyStartDate = [proxyStartDate addTimeInterval:([[NSDate date] timeIntervalSinceDate:interfaceInteractionTimer] - 0.25)]; + } else { + usleep(250000 - (100000 * [[NSDate date] timeIntervalSinceDate:interfaceInteractionTimer])); + } } currentProxyState = [connectionProxy state]; -- cgit v1.2.3