source: launchers/macosx/RouterTask.mm @ f76874a

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

Adding XCode workspace & Xcode project, and some files missing from last commit.

Please note that Xcode project embedds the packing script (meaning it runs "ant" - zip files, and moves it to bundle)

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