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

Last change on this file since c8490a3 was c8490a3, checked in by meeh <meeh@…>, 2 years ago

Starting to get stable and usable. Basically everything is based on callbacks.

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