Skip to content

Commit

Permalink
SapMachine #1693: Add support for starting child processes in an own …
Browse files Browse the repository at this point in the history
…process group also for Windows
  • Loading branch information
RealCLanger authored Jul 4, 2024
1 parent 09dca1a commit 46d6542
Show file tree
Hide file tree
Showing 12 changed files with 208 additions and 235 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2024 SAP SE. All rights reserved.
* Copyright (c) 2024 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand All @@ -23,15 +23,10 @@
* questions.
*/

#include <errno.h>
#include <unistd.h>
#include <signal.h>
package jdk.internal.access;

#include "com_sap_jdk_ext_process_ProcessGroupHelperImpl.h"
import java.io.IOException;

JNIEXPORT jint JNICALL Java_com_sap_jdk_ext_process_ProcessGroupHelperImpl_killProcessGroup0
(JNIEnv *env, jclass ignore, jlong pid_of_leader, jboolean force)
{
int rc = kill(-(pid_t)pid_of_leader, force ? SIGKILL : SIGTERM);
return ((rc == -1 && errno != 0) ? errno : rc);
public interface JavaLangProcessAccess {
public void destroyProcessGroup(Process leader, boolean force) throws IOException;
}
16 changes: 16 additions & 0 deletions src/java.base/share/classes/jdk/internal/access/SharedSecrets.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ public class SharedSecrets {
private static JavaLangModuleAccess javaLangModuleAccess;
// SapMachine 2024-06-12: process group extension
private static JavaLangProcessBuilderAccess javaLangProcessBuilderAccess;
private static JavaLangProcessAccess javaLangProcessAccess;
private static JavaLangRefAccess javaLangRefAccess;
private static JavaLangReflectAccess javaLangReflectAccess;
private static JavaIOAccess javaIOAccess;
Expand Down Expand Up @@ -203,6 +204,21 @@ public static JavaLangProcessBuilderAccess getJavaLangProcessBuilderAccess() {
return access;
}

// SapMachine 2024-07-01: process group extension
public static void setJavaLangProcessAccess(JavaLangProcessAccess jlpa) {
javaLangProcessAccess = jlpa;
}

// SapMachine 2024-07-01: process group extension
public static JavaLangProcessAccess getJavaLangProcessAccess() {
var access = javaLangProcessAccess;
if (access == null) {
ensureClassInitialized(Process.class);
access = javaLangProcessAccess;
}
return access;
}

public static void setJavaLangRefAccess(JavaLangRefAccess jlra) {
javaLangRefAccess = jlra;
}
Expand Down
21 changes: 21 additions & 0 deletions src/java.base/unix/classes/java/lang/ProcessImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
import java.security.PrivilegedExceptionAction;
import jdk.internal.access.JavaIOFileDescriptorAccess;
import jdk.internal.access.SharedSecrets;
//SapMachine 2024-07-01: process group extension
import jdk.internal.access.JavaLangProcessAccess;
import jdk.internal.util.OperatingSystem;
import jdk.internal.util.StaticProperty;
import sun.security.action.GetPropertyAction;
Expand Down Expand Up @@ -571,8 +573,27 @@ public String toString() {

private static native void init();

// SapMachine 2024-07-01: process group extension
private static native int terminateProcessGroup(long pid, boolean force);

private void terminateProcessGroup(boolean force) throws IOException {
int rc = terminateProcessGroup(pid, force);
if (rc != 0) {
throw new IOException("Failed to kill process group (errno = " + rc + ")");
}
}

static {
init();
// SapMachine 2024-07-01: process group extension
SharedSecrets.setJavaLangProcessAccess(
new JavaLangProcessAccess() {
@Override
public void destroyProcessGroup(Process leader, boolean force) throws IOException {
((ProcessImpl)leader).terminateProcessGroup(force);
}
}
);
}

/**
Expand Down
11 changes: 11 additions & 0 deletions src/java.base/unix/native/libjava/ProcessImpl_md.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@
#include <sys/wait.h>
#include <signal.h>
#include <string.h>
/* SapMachine 2024-06-12: process group extension */
#include <errno.h>
#include <unistd.h>

#include <spawn.h>

Expand Down Expand Up @@ -820,3 +823,11 @@ Java_java_lang_ProcessImpl_forkAndExec(JNIEnv *env,
closeSafely(err[0]); err[0] = -1;
goto Finally;
}

/* SapMachine 2024-06-12: process group extension */
JNIEXPORT jint JNICALL
Java_java_lang_ProcessImpl_terminateProcessGroup(JNIEnv *env, jclass ignore, jlong pid_of_leader, jboolean force)
{
int rc = kill(-(pid_t)pid_of_leader, force ? SIGKILL : SIGTERM);
return ((rc == -1 && errno != 0) ? errno : rc);
}
50 changes: 45 additions & 5 deletions src/java.base/windows/classes/java/lang/ProcessImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
import java.util.regex.Pattern;

import jdk.internal.access.JavaIOFileDescriptorAccess;
//SapMachine 2024-07-01: process group extension
import jdk.internal.access.JavaLangProcessAccess;
import jdk.internal.access.SharedSecrets;
import jdk.internal.ref.CleanerFactory;
import jdk.internal.misc.Blocker;
Expand All @@ -61,6 +63,18 @@ final class ProcessImpl extends Process {
private static final JavaIOFileDescriptorAccess fdAccess
= SharedSecrets.getJavaIOFileDescriptorAccess();

// SapMachine 2024-07-01: process group extension
static {
SharedSecrets.setJavaLangProcessAccess(
new JavaLangProcessAccess() {
@Override
public void destroyProcessGroup(Process leader, boolean force) {
((ProcessImpl)leader).terminateProcessGroup(force);
}
}
);
}

// Windows platforms support a forcible kill signal.
static final boolean SUPPORTS_NORMAL_TERMINATION = false;

Expand Down Expand Up @@ -159,7 +173,8 @@ static Process start(String cmdarray[],
}

Process p = new ProcessImpl(cmdarray, envblock, dir,
stdHandles, forceNullOutputStream, redirectErrorStream);
// SapMachine 2024-07-01: process group extension
stdHandles, forceNullOutputStream, redirectErrorStream, createNewProcessGroupOnSpawn);
if (redirects != null) {
// Copy the handles's if they are to be redirected to another process
if (stdHandles[0] >= 0
Expand Down Expand Up @@ -426,13 +441,18 @@ private static int countLeadingBackslash(int verificationType,
private InputStream stdout_stream;
private InputStream stderr_stream;

// SapMachine 2024-07-01: process group extension
private final long hJob;

@SuppressWarnings("removal")
private ProcessImpl(String cmd[],
final String envblock,
final String path,
final long[] stdHandles,
boolean forceNullOutputStream,
final boolean redirectErrorStream)
final boolean redirectErrorStream,
// SapMachine 2024-07-01: process group extension
final boolean createNewProcessGroupOnSpawn)
throws IOException
{
String cmdstr;
Expand Down Expand Up @@ -499,11 +519,18 @@ private ProcessImpl(String cmd[],
cmd);
}

// SapMachine 2024-07-01: process group extension
final long[] local_hJob = (createNewProcessGroupOnSpawn) ? new long[1] : null;
handle = create(cmdstr, envblock, path,
stdHandles, redirectErrorStream);
stdHandles, redirectErrorStream, local_hJob);
hJob = (createNewProcessGroupOnSpawn) ? local_hJob[0] : 0;

// Register a cleaning function to close the handle
final long local_handle = handle; // local to prevent capture of this
CleanerFactory.cleaner().register(this, () -> closeHandle(local_handle));
// SapMachine 2024-07-01: process group extension
CleanerFactory.cleaner().register(this, createNewProcessGroupOnSpawn ?
() -> closeHandle(local_handle) :
() -> {closeHandle(local_handle); closeHandle(local_hJob[0]);});

processHandle = ProcessHandleImpl.getInternal(getProcessId0(handle));

Expand Down Expand Up @@ -655,6 +682,17 @@ public Process destroyForcibly() {

private static native void terminateProcess(long handle);

// SapMachine 2024-07-01: process group extension
private static native void terminateProcessGroup(long hJob);

private void terminateProcessGroup(boolean force) {
if (hJob == 0) {
destroy();
} else {
terminateProcessGroup(hJob);
}
}

@Override
public long pid() {
return processHandle.pid();
Expand Down Expand Up @@ -708,7 +746,9 @@ private static synchronized native long create(String cmdstr,
String envblock,
String dir,
long[] stdHandles,
boolean redirectErrorStream)
boolean redirectErrorStream,
// SapMachine 2024-07-01: process group extension
long[] processGroup)
throws IOException;

/**
Expand Down
36 changes: 33 additions & 3 deletions src/java.base/windows/native/libjava/ProcessImpl_md.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,9 @@ static jlong processCreate(
const jchar *penvBlock,
const jchar *pdir,
jlong *handles,
jboolean redirectErrorStream)
jboolean redirectErrorStream,
/* SapMachine 2024-07-01: process group extension */
jlongArray processGroup)
{
jlong ret = 0L;
STARTUPINFOW si = {sizeof(si)};
Expand Down Expand Up @@ -328,6 +330,10 @@ static jlong processCreate(
processFlag &= ~CREATE_NO_WINDOW;
}

/* SapMachine 2024-07-01: process group extension */
if (processGroup)
processFlag |= CREATE_SUSPENDED;

si.dwFlags = STARTF_USESTDHANDLES;
if (!CreateProcessW(
NULL, /* executable name */
Expand All @@ -343,6 +349,17 @@ static jlong processCreate(
{
win32Error(env, L"CreateProcess");
} else {
/* SapMachine 2024-07-01: process group extension */
if (processGroup) {
__declspec(align(8)) HANDLE hJob = CreateJobObject(NULL, NULL);
if (!hJob) {
win32Error(env, L"CreateJobObject");
} else {
(*env)->SetLongArrayRegion(env, processGroup, 0, 1, (jlong *) &hJob);
AssignProcessToJobObject(hJob, pi.hProcess);
}
ResumeThread(pi.hThread);
}
closeSafely(pi.hThread);
ret = (jlong)pi.hProcess;
}
Expand All @@ -364,7 +381,9 @@ Java_java_lang_ProcessImpl_create(JNIEnv *env, jclass ignored,
jstring envBlock,
jstring dir,
jlongArray stdHandles,
jboolean redirectErrorStream)
jboolean redirectErrorStream,
/* SapMachine 2024-07-01: process group extension */
jlongArray processGroup)
{
jlong ret = 0;
if (cmd != NULL && stdHandles != NULL) {
Expand Down Expand Up @@ -393,7 +412,9 @@ Java_java_lang_ProcessImpl_create(JNIEnv *env, jclass ignored,
penvBlock,
pdir,
handles,
redirectErrorStream);
redirectErrorStream,
/* SapMachine 2024-07-01: process group extension */
processGroup);
free(pcmdCopy); // free mutable command line
}
(*env)->ReleaseLongArrayElements(env, stdHandles, handles, 0);
Expand Down Expand Up @@ -477,6 +498,15 @@ Java_java_lang_ProcessImpl_closeHandle(JNIEnv *env, jclass ignored, jlong handle
return (jboolean) CloseHandle((HANDLE) handle);
}

/* SapMachine 2024-07-01: process group extension */
JNIEXPORT void JNICALL
Java_java_lang_ProcessImpl_terminateProcessGroup(JNIEnv *env, jclass ignored, jlong hJob)
{
if (TerminateJobObject((HANDLE) hJob, 1) == 0) {
win32Error(env, L"TerminateJobObject");
}
}

JNIEXPORT jlong JNICALL
Java_java_lang_ProcessImpl_openForAtomicAppend(JNIEnv *env, jclass ignored, jstring path)
{
Expand Down
64 changes: 0 additions & 64 deletions src/jdk.sapext/share/classes/com/sap/jdk/ext/NativeLibHelper.java

This file was deleted.

Loading

0 comments on commit 46d6542

Please sign in to comment.