diff options
author | rowanbeentje <rowan@beent.je> | 2010-03-31 23:35:06 +0000 |
---|---|---|
committer | rowanbeentje <rowan@beent.je> | 2010-03-31 23:35:06 +0000 |
commit | 06e417594cd0fcdede2f0713c63a861bc65d7e99 (patch) | |
tree | de21be7bf852ec3a03c9baf2535ce4cebb5d0cdd /Source/SPSSHTunnel.m | |
parent | 836b96f7e1481938c0267448b940b5d8e202eb09 (diff) | |
download | sequelpro-06e417594cd0fcdede2f0713c63a861bc65d7e99.tar.gz sequelpro-06e417594cd0fcdede2f0713c63a861bc65d7e99.tar.bz2 sequelpro-06e417594cd0fcdede2f0713c63a861bc65d7e99.zip |
- Improve SPSSHTunnel question/password dialogs to no longer eat 100% CPU by switching from NSCondition blocking to NSLock blocking
- Improve behaviour of SSH tunnels with no password in keychain - prompt appropriately
- Set MXPConnection to check the proxy state when attempting to reconnect a dropped connection, extending the timer when an auth UI is up. This prevents a multiple-dialogs misbehaviour (or sometimes deadlock), addressing the last part of http://log.sequelpro.com/view/86 .
Diffstat (limited to 'Source/SPSSHTunnel.m')
-rw-r--r-- | Source/SPSSHTunnel.m | 59 |
1 files changed, 32 insertions, 27 deletions
diff --git a/Source/SPSSHTunnel.m b/Source/SPSSHTunnel.m index 46ceea97..207dc300 100644 --- a/Source/SPSSHTunnel.m +++ b/Source/SPSSHTunnel.m @@ -27,6 +27,7 @@ #import "RegexKitLite.h" #import "SPKeychain.h" #import "SPConstants.h" +#import "SPMainThreadTrampoline.h" #import <netinet/in.h> @@ -55,6 +56,7 @@ stateChangeSelector = nil; lastError = nil; debugMessages = [[NSMutableArray alloc] init]; + answerAvailableLock = [[NSLock alloc] init]; // Set up a connection for use by the tunnel process tunnelConnectionName = [[NSString alloc] initWithFormat:@"SequelPro-%lu", (unsigned long)[[NSString stringWithFormat:@"%f", [[NSDate date] timeIntervalSince1970]] hash]]; @@ -137,6 +139,14 @@ */ - (NSInteger) state { + + // See if an auth dialog is up + if (![answerAvailableLock tryLock]) { + return PROXY_STATE_WAITING_FOR_AUTH; + } + [answerAvailableLock unlock]; + + // Return the currently recorded state return connectionState; } @@ -467,21 +477,20 @@ */ - (BOOL) getResponseForQuestion:(NSString *)theQuestion { - // prepare the condition - [answerAvailableCondition lock]; - isAnswerAvailable = NO; + // Lock the answer available lock + [[answerAvailableLock onMainThread] lock]; - // request an answer on the main thread (UI stuff must be done on main thread) + // Request an answer on the main thread (UI stuff must be done on main thread) [self performSelectorOnMainThread:@selector(workerGetResponseForQuestion:) withObject:theQuestion waitUntilDone:YES]; - // wait for the signal in closeSSHQuestionSheet: - while (!isAnswerAvailable) [answerAvailableCondition wait]; + // Wait for closeSSHQuestionSheet: to unlock the lock, indicating an answer is available + while (![answerAvailableLock tryLock]) usleep(25000); - // save the answer + // Save the answer BOOL response = requestedResponse; - //unlock condition - [answerAvailableCondition unlock]; + // Unlock the lock again + [answerAvailableLock unlock]; //return the answer return response; @@ -507,13 +516,10 @@ */ - (IBAction) closeSSHQuestionSheet:(id)sender { - [answerAvailableCondition lock]; requestedResponse = [sender tag]==1 ? YES : NO; [NSApp endSheet:sshQuestionDialog]; [sshQuestionDialog orderOut:nil]; - isAnswerAvailable = YES; - [answerAvailableCondition signal]; - [answerAvailableCondition unlock]; + [[answerAvailableLock onMainThread] unlock]; } /* @@ -524,27 +530,26 @@ { if (![theHash isEqualToString:tunnelConnectionVerifyHash]) return nil; - // prepare the condition - [answerAvailableCondition lock]; - isAnswerAvailable = NO; + // Lock the answer available lock + [[answerAvailableLock onMainThread] lock]; - // request password on the main thread (UI stuff must be done on main thread) + // Request password on the main thread (UI stuff must be done on main thread) [self performSelectorOnMainThread:@selector(workerGetPasswordForQuery:) withObject:theQuery waitUntilDone:YES]; - // wait for the signal in closeSSHPasswordSheet: - while (!isAnswerAvailable) [answerAvailableCondition wait]; + // Wait for closeSSHPasswordSheet: to unlock the lock, indicating an answer is available + while (![answerAvailableLock tryLock]) usleep(25000); - // save the answer + // Save the answer NSString *thePassword = nil; if (requestedPassphrase) { thePassword = [NSString stringWithString:requestedPassphrase]; [requestedPassphrase release], requestedPassphrase = nil; } - //unlock condition - [answerAvailableCondition unlock]; + // Unlock the lock again + [answerAvailableLock unlock]; - //return the answer + // Return the answer return thePassword; } - (void) workerGetPasswordForQuery:(NSString *)theQuery @@ -577,7 +582,6 @@ */ - (IBAction) closeSSHPasswordSheet:(id)sender { - [answerAvailableCondition lock]; requestedResponse = [sender tag]==1 ? YES : NO; [NSApp endSheet:sshPasswordDialog]; [sshPasswordDialog orderOut:nil]; @@ -602,9 +606,7 @@ } } - isAnswerAvailable = YES; - [answerAvailableCondition signal]; - [answerAvailableCondition unlock]; + [[answerAvailableLock onMainThread] unlock]; } @@ -621,6 +623,9 @@ [tunnelConnection invalidate]; [tunnelConnection release]; [debugMessages release]; + [answerAvailableLock tryLock]; + [answerAvailableLock unlock]; + [answerAvailableLock release]; if (password) [password release]; if (keychainName) [keychainName release]; if (keychainAccount) [keychainAccount release]; |