diff --git a/gui_ocamlmsgAppDelegate.m b/gui_ocamlmsgAppDelegate.m index 22d1270..ae9601a 100644 --- a/gui_ocamlmsgAppDelegate.m +++ b/gui_ocamlmsgAppDelegate.m @@ -7,6 +7,9 @@ // #import "gui_ocamlmsgAppDelegate.h" +#include + +#define HOP_STARTUP_DEADLINE_SECONDS 30 @implementation gui_ocamlmsgAppDelegate @@ -22,11 +25,48 @@ name: NSTaskDidTerminateNotification object: nil]; - [task setCurrentDirectoryPath: @"/Users/tonyg/src/ocamlmsg"]; - [task setLaunchPath: @"/Users/tonyg/src/ocamlmsg/ocamlmsg.native"]; - [task setArguments: [NSArray new]]; - [task launch]; - sleep(1); + NSString *serverBinaryPath = [[NSBundle mainBundle] resourcePath]; + [task setCurrentDirectoryPath: serverBinaryPath]; + NSString *serverBinary = [serverBinaryPath stringByAppendingPathComponent: @"ocamlmsg.native"]; + [task setLaunchPath: serverBinary]; + + NSString *readyFile = [NSTemporaryDirectory() stringByAppendingPathComponent: @"hop.ready."]; + readyFile = [readyFile stringByAppendingFormat: @"%d", getpid()]; + char const *readyFileUtf8 = [readyFile UTF8String]; + unlink(readyFileUtf8); + + [task setArguments: [NSArray arrayWithObjects: @"--ready-file", readyFile, nil]]; + + @try { + [task launch]; + } + @catch (NSException *e) { + NSLog(@"Could not launch server %@: %@", serverBinary, [e reason]); + [NSApp terminate: self]; + @throw; + } + + int foundReadyFile = 0; + time_t startTime = time(NULL); + while ([task isRunning] && time(NULL) - startTime < HOP_STARTUP_DEADLINE_SECONDS) { + struct stat s; + if (lstat(readyFileUtf8, &s) != -1) { + foundReadyFile = 1; + break; + } + if (errno != ENOENT) { + perror("lstat of readyFileUtf8"); + exit(EXIT_FAILURE); + } + usleep(100000); + } + unlink(readyFileUtf8); + + if (!foundReadyFile) { + NSLog(@"Server did not start up within %d seconds.", HOP_STARTUP_DEADLINE_SECONDS); + [NSApp terminate: self]; + return; + } [[webview mainFrame] loadRequest: [NSURLRequest requestWithURL: @@ -34,7 +74,9 @@ } - (void) applicationWillTerminate: (NSNotification *) notification { - [task terminate]; + if ([task isRunning]) { + [task terminate]; + } } - (void) taskStatusChanged: (NSNotification *) aNotification {