diff --git a/Managers/UTMJSONStream.m b/Managers/UTMJSONStream.m index 31753e562..27ea1904a 100644 --- a/Managers/UTMJSONStream.m +++ b/Managers/UTMJSONStream.m @@ -204,6 +204,11 @@ - (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode { [self disconnect]; break; } + case NSStreamEventOpenCompleted: { + NSLog(@"Connected to stream"); + [self.delegate jsonStream:self connected:(aStream == _inputStream)]; + break; + } default: { break; } diff --git a/Managers/UTMJSONStreamDelegate.h b/Managers/UTMJSONStreamDelegate.h index d87b6945a..ac411b85d 100644 --- a/Managers/UTMJSONStreamDelegate.h +++ b/Managers/UTMJSONStreamDelegate.h @@ -22,6 +22,7 @@ NS_ASSUME_NONNULL_BEGIN @protocol UTMJSONStreamDelegate +- (void)jsonStream:(UTMJSONStream *)stream connected:(BOOL)readStream; - (void)jsonStream:(UTMJSONStream *)stream receivedDictionary:(NSDictionary *)dict; - (void)jsonStream:(UTMJSONStream *)stream seenError:(NSError *)error; diff --git a/Managers/UTMQemuManager.h b/Managers/UTMQemuManager.h index a50978e8d..910d550ae 100644 --- a/Managers/UTMQemuManager.h +++ b/Managers/UTMQemuManager.h @@ -26,6 +26,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, readonly) UTMJSONStream *jsonStream; @property (nonatomic, weak) id delegate; +@property (nonatomic, assign) int retries; - (void)connect; - (void)disconnect; diff --git a/Managers/UTMQemuManager.m b/Managers/UTMQemuManager.m index 27222ba2a..576cea1a6 100644 --- a/Managers/UTMQemuManager.m +++ b/Managers/UTMQemuManager.m @@ -23,6 +23,7 @@ extern NSString *const kUTMErrorDomain; const int64_t kRPCTimeout = (int64_t)10*1000000000; +const int64_t kRetryWait = (int64_t)1*1000000000; static void utm_shutdown_handler(bool guest, ShutdownCause reason, void *ctx) { UTMQemuManager *self = (__bridge UTMQemuManager *)ctx; @@ -163,10 +164,24 @@ - (void)disconnect { [_jsonStream disconnect]; } +- (void)jsonStream:(UTMJSONStream *)stream connected:(BOOL)readStream { + NSLog(@"QMP connection successful! (readStream:%d)", readStream); + self.retries = 0; // connection was successful +} + - (void)jsonStream:(UTMJSONStream *)stream seenError:(NSError *)error { + NSLog(@"QMP stream error seen: %@", error); if (_rpc_finish) { _rpc_finish(nil, error); } + [self disconnect]; + if (self.retries > 0) { + self.retries--; + NSLog(@"QMP connection failed, retries left: %d", self.retries); + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, kRetryWait), dispatch_get_main_queue(), ^{ + [self->_jsonStream connect]; + }); + } } - (void)jsonStream:(UTMJSONStream *)stream receivedDictionary:(NSDictionary *)dict { diff --git a/Managers/UTMVirtualMachine.m b/Managers/UTMVirtualMachine.m index 855e44ac7..6085c8c8f 100644 --- a/Managers/UTMVirtualMachine.m +++ b/Managers/UTMVirtualMachine.m @@ -253,6 +253,7 @@ - (BOOL)startVM { if (tries == 0) { [self errorTriggered:NSLocalizedString(@"Failed to connect to display server.", @"UTMVirtualMachine")]; } + self->_qemu.retries = kMaxConnectionTries; [self->_qemu connect]; _is_busy = NO; return YES;