Browse Source

Improve external process handling

pull/62/head
nonlin-lin-chaos-order-etc-etal 7 months ago
parent
commit
ad0f9dd8b0
  1. 4
      app/src/main/java/org/purplei2p/i2pd/AbstractProcess.java
  2. 11
      app/src/main/java/org/purplei2p/i2pd/DaemonWrapper.java
  3. 7
      app/src/main/java/org/purplei2p/i2pd/ExternalProcessImpl.java
  4. 5
      app/src/main/java/org/purplei2p/i2pd/I2PDActivity.java
  5. 59
      app/src/main/java/org/purplei2p/i2pd/I2pdApi.java

4
app/src/main/java/org/purplei2p/i2pd/AbstractProcess.java

@ -1,5 +1,7 @@ @@ -1,5 +1,7 @@
package org.purplei2p.i2pd;
public interface AbstractProcess {
void kill();
/** @param tr can be null
*/
void kill(Throwable tr);
}

11
app/src/main/java/org/purplei2p/i2pd/DaemonWrapper.java

@ -153,13 +153,18 @@ public class DaemonWrapper { @@ -153,13 +153,18 @@ public class DaemonWrapper {
return getState().isStartedOkay();
}
public synchronized void stopDaemon() {
public void stopDaemon() {
stopDaemon(null);
}
public synchronized void stopDaemon(final Throwable throwable) {
if (isStartedOkay()) {
try {
I2pdApi.stopDaemon();
I2pdApi.stopDaemon(throwable);
} catch (Throwable tr) {
Log.e(TAG, "", tr);
}
if (throwable != null) lastThrowable = throwable;
setState(State.stopped);
}
}
@ -179,7 +184,7 @@ public class DaemonWrapper { @@ -179,7 +184,7 @@ public class DaemonWrapper {
String locale = getAppLocale();
Log.i(TAG, "setting webconsole language to " + locale);
daemonStartResult = I2pdApi.startDaemon(ctx, i2pdpath, locale);
daemonStartResult = I2pdApi.startDaemon(ctx, i2pdpath, locale, DaemonWrapper.this);
if ("ok".equals(daemonStartResult)) {
setState(State.startedOkay);
} else

7
app/src/main/java/org/purplei2p/i2pd/ExternalProcessImpl.java

@ -3,17 +3,20 @@ package org.purplei2p.i2pd; @@ -3,17 +3,20 @@ package org.purplei2p.i2pd;
import android.util.Log;
public class ExternalProcessImpl implements AbstractProcess {
public static final String TAG = "ExtProcKill";
private final int pid;
public ExternalProcessImpl(int pid) {
this.pid = pid;
}
public void kill() {
public void kill(Throwable reasonThrowable) {
if(reasonThrowable!=null) Log.e(TAG,"reasonThrowable", reasonThrowable);
else Log.e(TAG,"reasonThrowable==null");
try {
Runtime.getRuntime().exec(new String[]{
"/system/bin/sh", "-c", "kill " + pid
});
}catch(Throwable tr){
Log.e("ExtProcKill","",tr);
Log.e(TAG,"",tr);
}
}
}

5
app/src/main/java/org/purplei2p/i2pd/I2PDActivity.java

@ -83,9 +83,12 @@ public class I2PDActivity extends Activity { @@ -83,9 +83,12 @@ public class I2PDActivity extends Activity {
// I2CPState.setChecked(I2pdApi.getI2CPState());
// }
final Throwable lastThrowable = daemon.getLastThrowable();
String startResultStr = DaemonWrapper.State.startFailed.equals(state) ? String.format(": %s", daemon.getDaemonStartResult()) : "";
String stopReasonStr = DaemonWrapper.State.stopped.equals(state) && lastThrowable != null ?
String.format(": %s", lastThrowable) : "";
String graceStr = DaemonWrapper.State.gracefulShutdownInProgress.equals(state) ? String.format(": %s %s", formatGraceTimeRemaining(), getText(R.string.remaining)) : "";
textView.setText(String.format("%s%s%s", getText(state.getStatusStringResourceId()), startResultStr, graceStr));
textView.setText(String.format("%s%s%s%s", getText(state.getStatusStringResourceId()), startResultStr, graceStr, stopReasonStr));
} catch (Throwable tr) {
Log.e(TAG,"error ignored",tr);
}

59
app/src/main/java/org/purplei2p/i2pd/I2pdApi.java

@ -29,19 +29,32 @@ public class I2pdApi { @@ -29,19 +29,32 @@ public class I2pdApi {
* returns error info if failed
* returns "ok" if daemon initialized and started okay
*/
public static String startDaemon(Context ctx, String dataDir, String language){
public static String startDaemon(final Context ctx, final String dataDir, String language, final DaemonWrapper daemonWrapper){
try {
i2pdProcess = null;
I2pdApi.dataDir = dataDir;
Process p = Runtime.getRuntime().exec(new String[]{
File pidFile = new File(dataDir, "i2pd.pid");
final Process p = Runtime.getRuntime().exec(new String[]{
ctx.getApplicationInfo().nativeLibraryDir + "/libi2pd.so",
"--datadir=" + dataDir
"--datadir=" + dataDir,
"--pidfile=" + pidFile.getAbsolutePath()
});
i2pdProcess = () -> {
i2pdProcess = (Throwable tr) -> {
try {
p.destroy();
} catch (Throwable tr) {
Log.e(TAG, "", tr);
if (p.isAlive()) {
if (tr != null)
Log.e(TAG, "destroying the subprocess \"i2pd\", reason: " + tr, tr);
else
Log.e(TAG, "destroying the subprocess \"i2pd\", reason: null");
p.destroy();
}else{
if (tr != null)
Log.e(TAG, "skipping destroy of a dead subprocess \"i2pd\", reason: " + tr, tr);
else
Log.e(TAG, "skipping destroy of a dead subprocess \"i2pd\", reason: null");
}
} catch (Throwable tr2) {
Log.e(TAG, "", tr2);
}
};
new Thread(() -> {
@ -60,7 +73,7 @@ public class I2pdApi { @@ -60,7 +73,7 @@ public class I2pdApi {
} catch (Throwable tr) {
Log.e(TAG, "", tr);
}
}, "i2pd-stdout");
}, "i2pd-stdout").start();
new Thread(() -> {
try {
try (BufferedInputStream bis = new BufferedInputStream(p.getErrorStream())) {
@ -77,7 +90,29 @@ public class I2pdApi { @@ -77,7 +90,29 @@ public class I2pdApi {
} catch (Throwable tr) {
Log.e(TAG, "", tr);
}
}, "i2pd-stderr");
try {
p.waitFor();
} catch (Throwable tr) {
Log.e(TAG, "", tr);
}
final int errorLevel = p.exitValue();
Log.i(TAG, "i2pd process exit code: " + errorLevel);
final Throwable trReason = new Throwable("subprocess \"i2pd\" exited with exit code " + errorLevel);
try {
stopDaemon(trReason);
Log.i(TAG, "stopDaemon completed");
} catch (Throwable tr) {
Log.e(TAG, "Called stopDaemon, got exception", tr);
}
new Thread(() -> {
try {
daemonWrapper.stopDaemon(trReason);
Log.i(TAG, "daemonWrapper.stopDaemon completed");
} catch (Throwable tr) {
Log.e(TAG, "Called daemonWrapper.stopDaemon, got exception", tr);
}
}, "stop the daemonWrapper thread").start();
}, "i2pd-stderr").start();
new Thread(() -> {
try {
try (BufferedOutputStream bos = new BufferedOutputStream(p.getOutputStream())) {
@ -94,7 +129,7 @@ public class I2pdApi { @@ -94,7 +129,7 @@ public class I2pdApi {
} catch (Throwable tr) {
Log.e(TAG, "", tr);
}
}, "i2pd-stdin");
}, "i2pd-stdin").start();
return "ok";
} catch (Throwable tr) {
Log.e(TAG, "", tr);
@ -102,10 +137,10 @@ public class I2pdApi { @@ -102,10 +137,10 @@ public class I2pdApi {
}
}
public static void stopDaemon(){
public static void stopDaemon(Throwable tr){
AbstractProcess p = i2pdProcess;
if (p != null) {
p.kill();
p.kill(tr);
i2pdProcess = null;
}
}

Loading…
Cancel
Save