source: launchers/macosx/obj-cpp/RouterTask.mm @ 6d0f80f

Last change on this file since 6d0f80f was 6d0f80f, checked in by meeh <meeh@…>, 23 months ago

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

  • Property mode set to 100644
File size: 4.3 KB
Line 
1#include "RouterTask.h"
2
3#include <dispatch/dispatch.h>
4#include <future>
5#include <stdlib.h>
6
7#include "optional.hpp"
8#include "subprocess.hpp"
9
10#import <AppKit/AppKit.h>
11
12@implementation RTaskOptions
13@end
14
15@implementation RouterTask
16
17- (instancetype) initWithOptions : (RTaskOptions*) options
18{
19    self.input = [NSFileHandle fileHandleWithStandardInput];
20    self.routerTask = [NSTask new];
21    self.processPipe = [NSPipe new];
22    [self.routerTask setLaunchPath:options.binPath];
23    [self.routerTask setArguments:options.arguments];
24    NSDictionary *envDict = @{
25        @"I2PBASE": options.i2pBaseDir
26    };
27    [self.routerTask setEnvironment: envDict];
28    [self.routerTask setStandardOutput:self.processPipe];
29        [self.routerTask setStandardError:self.processPipe];
30/*
31    self.readLogHandle = [self.processPipe fileHandleForReading];
32    NSData *inData = nil;
33    self.totalLogData = [[[NSMutableData alloc] init] autorelease];
34
35    while ((inData = [self.readLogHandle availableData]) &&
36        [inData length]) {
37        [self.totalLogData appendData:inData];
38    }
39*/
40    return self;
41}
42
43- (int) execute
44{
45    //@try {
46        [self.routerTask launch];
47        [self.input waitForDataInBackgroundAndNotify];
48        [[self.processPipe fileHandleForReading] waitForDataInBackgroundAndNotify];
49        [[NSNotificationCenter defaultCenter] addObserverForName:NSFileHandleDataAvailableNotification
50                                                          object:[self.processPipe fileHandleForReading] queue:nil
51                                                      usingBlock:^(NSNotification *note)
52         {
53             // Read from shell output
54             NSData *outData = [[self.processPipe fileHandleForReading] availableData];
55             NSString *outStr = [[NSString alloc] initWithData:outData encoding:NSUTF8StringEncoding];
56             if ([outStr length] > 1) {
57                 NSLog(@"output: %@", outStr);
58             }
59
60             // Continue waiting for shell output.
61             [[self.processPipe fileHandleForReading] waitForDataInBackgroundAndNotify];
62         }];
63         //[self.routerTask waitUntilExit];
64        //NSThread *thr = [[NSThread alloc] initWithTarget:self.routerTask selector:@selector(launch) object:nil];
65        //[self.routerTask waitUntilExit];
66        return 1;
67    /*}
68    @catch (NSException *e)
69        {
70                NSLog(@"Expection occurred %@", [e reason]);
71        return 0;
72        }*/
73}
74
75- (int) getPID
76{
77    return [self.routerTask processIdentifier];
78}
79
80@end
81
82
83
84
85using namespace subprocess;
86
87std::mutex globalRouterStatusMutex;
88
89const std::vector<NSString*> JavaRunner::defaultStartupFlags {
90    @"-Xmx512M",
91    @"-Xms128m",
92    @"-Djava.awt.headless=true",
93    @"-Dwrapper.logfile=/tmp/router.log",
94    @"-Dwrapper.logfile.loglevel=DEBUG",
95    @"-Dwrapper.java.pidfile=/tmp/routerjvm.pid",
96    @"-Dwrapper.console.loglevel=DEBUG"
97};
98
99const std::vector<std::string> JavaRunner::defaultFlagsForExtractorJob {
100    "-Xmx512M",
101    "-Xms128m",
102    "-Djava.awt.headless=true"
103};
104
105JavaRunner::JavaRunner(std::string& javaBin, std::string& arguments, std::string& i2pBaseDir, const fp_proc_t& execFn, const fp_t& cb)
106  : javaBinaryPath(javaBin), javaRouterArgs(arguments), _i2pBaseDir(i2pBaseDir), executingFn(execFn), exitCallbackFn(cb)
107{
108  execLine = javaBinaryPath;
109  execLine += " " + std::string(javaRouterArgs.c_str());
110  printf("CLI: %s\n",execLine.c_str());
111  javaProcess = std::shared_ptr<Popen>(new Popen(execLine, environment{{
112            {"I2PBASE", _i2pBaseDir},
113            {"JAVA_OPTS", getenv("JAVA_OPTS")}
114        }}, defer_spawn{true}));
115}
116
117void JavaRunner::requestRouterShutdown()
118{
119    // SIGHUP
120    javaProcess->kill(1);
121}
122
123std::experimental::optional<std::future<int> > JavaRunner::execute()
124{
125  try {
126    auto executingFn = dispatch_block_create(DISPATCH_BLOCK_INHERIT_QOS_CLASS, ^{
127      this->executingFn(this);
128    });
129    dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), executingFn);
130    dispatch_block_wait(executingFn, DISPATCH_TIME_FOREVER);
131
132    // Here, the process is done executing.
133
134    printf("Finished executingFn - Runs callbackFn\n");
135    this->exitCallbackFn();
136    return std::async(std::launch::async, []{ return 0; });
137  } catch (std::exception* ex) {
138    printf("ERROR: %s\n", ex->what());
139    return std::experimental::nullopt;
140  }
141}
Note: See TracBrowser for help on using the repository browser.