Ignore:
Timestamp:
Jul 13, 2018 6:30:16 AM (23 months ago)
Author:
meeh <meeh@…>
Branches:
master
Children:
818e70d
Parents:
21b3864
Message:

Fixed a load of issues related to my "sync" approach, and Mac OSX's "async" API.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • launchers/macosx/obj-cpp/main.mm

    r21b3864 r6d0f80f  
    55#include <string>
    66#include <list>
    7 #include <experimental/optional>
     7#include <sys/stat.h>
     8#include <stdlib.h>
     9#include <future>
     10#include <vector>
    811
    912#import <Foundation/Foundation.h>
     
    2427#include "AppDelegate.h"
    2528#include "StatusItemButton.h"
    26 #include "JavaRunner.h"
     29#include "RouterTask.h"
    2730#include "JavaHelper.h"
     31#include "fn.h"
     32#include "optional.hpp"
    2833
    2934#define DEF_I2P_VERSION "0.9.35"
     
    4449
    4550
     51std::future<int> startupRouter(NSString* javaBin, NSArray<NSString*>* arguments, NSString* i2pBaseDir) {
     52/*
     53  NSLog(@"Arguments: %@", [NSString stringWithUTF8String:arguments.c_str()]);
     54  auto launchLambda = [](JavaRunner *javaRun) {
     55    javaRun->javaProcess->start_process();
     56    auto pid = javaRun->javaProcess->pid();
     57    std::cout << "I2P Router process id = " << pid << std::endl;
     58
     59    // Blocking
     60    javaRun->javaProcess->wait();
     61  };
     62  auto callbackAfterExit = [](){
     63    printf("Callback after exit\n");
     64  };
     65  NSLog(@"Still fine!");
     66
     67  setGlobalRouterObject(new JavaRunner{ javaBin, arguments, i2pBaseDir, std::move(launchLambda), std::move(callbackAfterExit) });
     68
     69  NSLog(@"Still fine!");
     70  return std::async(std::launch::async, [&]{
     71      getGlobalRouterObject().value()->execute();
     72      return 0;
     73    });
     74*/
     75    CFShow(arguments);
     76
     77    @try {
     78        RTaskOptions* options = [RTaskOptions alloc];
     79        options.binPath = javaBin;
     80        options.arguments = arguments;
     81        options.i2pBaseDir = i2pBaseDir;
     82        auto instance = [[[RouterTask alloc] initWithOptions: options] autorelease];
     83        //auto pid = [instance execute];
     84        //NSThread *thr = [[NSThread alloc] initWithTarget:instance selector:@selector(execute) object:nil];
     85        [instance execute];
     86        return std::async(std::launch::async, [&instance]{
     87          return 1;//[instance getPID];
     88        });
     89    }
     90    @catch (NSException *e)
     91        {
     92                NSLog(@"Expection occurred %@", [e reason]);
     93        return std::async(std::launch::async, [&]{
     94          return 0;
     95        });
     96        }
     97}
     98
     99
    46100@implementation MenuBarCtrl
    47101
     
    83137{
    84138  NSLog(@"Clicked stopJavaRouterBtnHandler");
     139  if (getGlobalRouterObject().has_value())
     140  {
     141      //getGlobalRouterObject().value()->requestRouterShutdown();
     142      NSLog(@"Requested shutdown");
     143  }
    85144}
    86145
     
    172231
    173232@implementation AppDelegate
     233
     234- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center
     235                               shouldPresentNotification:(NSUserNotification *)notification {
     236    return YES;
     237}
    174238
    175239- (NSString *)userSelectJavaHome:(JvmListPtr)rawJvmList
     
    225289  CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication);
    226290  //CFPreferencesSetAppValue(@"javaHome", (CFPropertyListRef)cfDefaultHome, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);
    227  
     291
    228292  if (self.enableVerboseLogging) NSLog(@"Default preferences stored!");
    229293}
     
    232296- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    233297  // Init application here
     298  [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:self];
    234299  // Start with user preferences
    235300  self.userPreferences = [NSUserDefaults standardUserDefaults];
     
    247312  if (self.enableVerboseLogging) NSLog(@"Java home from preferences: %@", javaHomePref);
    248313
    249   [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:self];
    250314
    251315  // This is the only GUI the user experience on a regular basis.
     
    256320
    257321  NSLog(@"We should have started the statusbar object by now...");
     322
     323  // Figure out base directory
     324  const char* pathFromHome = "/Users/%s/Library/I2P";
     325  auto username = getenv("USER");
     326  char buffer[strlen(pathFromHome)+strlen(username)];
     327  sprintf(buffer, pathFromHome, username);
     328  std::string i2pBaseDir(buffer);
     329  if (self.enableVerboseLogging) printf("Home directory is: %s\n", buffer);
     330
     331
    258332  //[statusBarButton setAction:@selector(itemClicked:)];
    259333  //dispatch_async(dispatch_get_main_queue(), ^{
     
    274348  };
    275349
    276 
    277   auto launchLambda = [&pref](JavaRunner *javaRun) {
    278     javaRun->javaProcess->start_process();
    279     auto pid = javaRun->javaProcess->pid();
    280     std::cout << "I2P Router process id = " << pid << std::endl;
    281 
    282     // Blocking
    283     javaRun->javaProcess->wait();
    284   };
    285   auto callbackAfterExit = [=](){
    286     printf("Callback after exit\n");
    287   };
    288 
    289   try {
    290 
    291     // Get Java home
     350  auto getJavaBin = [&getJavaHomeLambda]() -> std::string {
     351      // Get Java home
    292352    auto javaHome = getJavaHomeLambda();
    293353    trim(javaHome); // Trim to remove endline
    294354    auto javaBin = std::string(javaHome);
    295355    javaBin += "/bin/java"; // Append java binary to path.
    296     //printf("hello world: %s\n", javaBin.c_str());
    297     if (self.enableVerboseLogging) NSLog(@"Defaults: %@", [pref dictionaryRepresentation]);
    298 
    299     auto r = new JavaRunner{ javaBin, launchLambda, callbackAfterExit };
    300     r->execute();
     356    return javaBin;
     357  };
     358
     359  auto buildClassPath = [](std::string basePath) -> std::vector<std::string> {
     360      return globVector(basePath+std::string("/lib/*.jar"));
     361  };
     362
     363  auto sendUserNotification = [&](NSString* title, NSString* informativeText) -> void {
     364    NSUserNotification *userNotification = [[[NSUserNotification alloc] init] autorelease];
     365
     366    userNotification.title = title;
     367    userNotification.informativeText = informativeText;
     368    userNotification.soundName = NSUserNotificationDefaultSoundName;
     369
     370    [[NSUserNotificationCenter defaultUserNotificationCenter] scheduleNotification:userNotification];
     371  };
     372
     373
     374  // Get paths
     375  NSBundle *launcherBundle = [NSBundle mainBundle];
     376
     377  std::string basearg("-Di2p.dir.base=");
     378  basearg += i2pBaseDir;
     379
     380  std::string zippath("-Di2p.base.zip=");
     381  zippath += [[launcherBundle pathForResource:@"base" ofType:@"zip"] UTF8String];
     382
     383  std::string jarfile("-cp ");
     384  jarfile += [[launcherBundle pathForResource:@"launcher" ofType:@"jar"] UTF8String];
     385
     386  struct stat sb;
     387  if ( !(stat(buffer, &sb) == 0 && S_ISDIR(sb.st_mode)) )
     388  {
     389    // I2P is not extracted.
     390    if (self.enableVerboseLogging) printf("I2P Directory don't exists!\n");
     391
     392    // Create directory
     393    mkdir(buffer, S_IRUSR | S_IWUSR | S_IXUSR);
     394
     395    auto cli = JavaRunner::defaultFlagsForExtractorJob;
     396    setenv("I2PBASE", buffer, true);
     397    setenv("ZIPPATH", zippath.c_str(), true);
     398    //setenv("DYLD_LIBRARY_PATH",".:/usr/lib:/lib:/usr/local/lib", true);
     399
     400    cli.push_back(basearg);
     401    cli.push_back(zippath);
     402    cli.push_back(jarfile);
     403    cli.push_back("net.i2p.launchers.BaseExtractor");
     404
     405    //auto charCli = map(cli, [](std::string str){ return str.c_str(); });
     406    std::string execStr = getJavaBin();
     407    for_each(cli, [&execStr](std::string str){ execStr += std::string(" ") + str; });
     408
     409    printf("\n\nTrying cmd: %s\n\n", execStr.c_str());
     410    try {
     411        sendUserNotification((NSString*)CFSTR("I2P Extraction"), (NSString*)CFSTR("Please hold on while we extract I2P. You'll get a new message once done!"));
     412        int extractStatus = Popen(execStr.c_str(), environment{{
     413            {"ZIPPATH", zippath.c_str()},
     414            {"I2PBASE", buffer}
     415        }}).wait();
     416        printf("Extraction exit code %d\n",extractStatus);
     417        sendUserNotification((NSString*)CFSTR("I2P Extraction"), (NSString*)CFSTR("Extraction complete!"));
     418    } catch (subprocess::OSError &err) {
     419        printf("Something bad happened: %s\n", err.what());
     420    }
     421
     422  } else {
     423      if (self.enableVerboseLogging) printf("I2P directory found!\n");
     424  }
     425
     426  // Expect base to be extracted by now.
     427
     428  auto jarList = buildClassPath(std::string(buffer));
     429  std::string classpathStrHead = "-classpath";
     430  std::string classpathStr = "";
     431  classpathStr += [[launcherBundle pathForResource:@"launcher" ofType:@"jar"] UTF8String];
     432  std::string prefix(i2pBaseDir);
     433  prefix += "/lib/";
     434  for_each(jarList, [&classpathStr](std::string str){ classpathStr += std::string(":") + str; });
     435  //if (self.enableVerboseLogging) NSLog(@"Classpath: %@\n",[NSString stringWithUTF8String:classpathStr.c_str()]);
     436
     437
     438
     439  try {
     440    auto argList = JavaRunner::defaultStartupFlags;
     441
     442    std::string baseDirArg("-Di2p.dir.base=");
     443    baseDirArg += i2pBaseDir;
     444    std::string javaLibArg("-Djava.library.path=");
     445    javaLibArg += i2pBaseDir;
     446    // TODO: pass this to JVM
     447    auto java_opts = getenv("JAVA_OPTS");
     448
     449    argList.push_back([NSString stringWithUTF8String:baseDirArg.c_str()]);
     450    argList.push_back([NSString stringWithUTF8String:javaLibArg.c_str()]);
     451    argList.push_back([NSString stringWithUTF8String:classpathStrHead.c_str()]);
     452    argList.push_back([NSString stringWithUTF8String:classpathStr.c_str()]);
     453    argList.push_back(@"net.i2p.router.Router");
     454    auto javaBin = getJavaBin();
     455
     456
     457    sendUserNotification(@"I2P Launcher", @"I2P Router is starting up!");
     458    auto nsJavaBin = [NSString stringWithUTF8String:javaBin.c_str()];
     459    auto nsBasePath = [NSString stringWithUTF8String:i2pBaseDir.c_str()];
     460    NSArray* arrArguments = [NSArray arrayWithObjects:&argList[0] count:argList.size()];
     461    startupRouter(nsJavaBin, arrArguments, nsBasePath);
     462    //if (self.enableVerboseLogging) NSLog(@"Defaults: %@", [pref dictionaryRepresentation]);
    301463  } catch (std::exception &err) {
    302     std::cerr << "Exception: " << err.what() << std::endl; 
     464    std::cerr << "Exception: " << err.what() << std::endl;
    303465  }
    304466}
Note: See TracChangeset for help on using the changeset viewer.