Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 49 additions & 39 deletions concore.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,75 +39,85 @@ private static boolean isWindows() {

private static void registerPid() {
try {
String pid = String.valueOf(ProcessHandle.current().pid());
ProcessHandle current = ProcessHandle.current();
long pid = current.pid();
long startTimeMs = current.info().startInstant()
.orElseThrow(() -> new IllegalStateException(
"Process start time is unavailable"))
.toEpochMilli();
String record = pid + "|" + startTimeMs + System.lineSeparator();
try (FileChannel channel = FileChannel.open(PID_REGISTRY_FILE,
StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.APPEND)) {
StandardOpenOption.CREATE, StandardOpenOption.WRITE,
StandardOpenOption.APPEND)) {
try (FileLock lock = channel.lock()) {
channel.write(ByteBuffer.wrap((pid + System.lineSeparator()).getBytes(java.nio.charset.StandardCharsets.UTF_8)));
ByteBuffer buffer = ByteBuffer.wrap(
record.getBytes(java.nio.charset.StandardCharsets.UTF_8));
while (buffer.hasRemaining()) {
channel.write(buffer);
}
}
}
} catch (IOException e) {
} catch (IOException | RuntimeException e) {
}
}

private static void cleanupPid() {
String pid = String.valueOf(ProcessHandle.current().pid());
if (!Files.exists(PID_REGISTRY_FILE)) return;
List<String> remaining = new ArrayList<>();
try (FileChannel channel = FileChannel.open(PID_REGISTRY_FILE,
StandardOpenOption.READ, StandardOpenOption.WRITE)) {
try (FileLock lock = channel.lock()) {
ByteBuffer buf = ByteBuffer.allocate((int) channel.size());
channel.read(buf);
while (buf.hasRemaining() && channel.read(buf) != -1) {
}
buf.flip();
String content = java.nio.charset.StandardCharsets.UTF_8.decode(buf).toString();
String content = java.nio.charset.StandardCharsets.UTF_8
.decode(buf).toString();
List<String> remaining = new ArrayList<>();
for (String line : content.split("\\R")) {
String trimmed = line.trim();
if (!trimmed.isEmpty() && !trimmed.equals(pid)) {
remaining.add(trimmed);
if (!trimmed.isEmpty()) {
String entryPid = trimmed.split("\\|", 2)[0].trim();
if (!entryPid.equals(pid)) {
remaining.add(trimmed);
}
}
}
StringBuilder sb = new StringBuilder();
for (String entry : remaining) {
sb.append(entry).append(System.lineSeparator());
}
channel.truncate(0);
channel.position(0);
if (!remaining.isEmpty()) {
StringBuilder sb = new StringBuilder();
for (String r : remaining) sb.append(r).append(System.lineSeparator());
channel.write(ByteBuffer.wrap(sb.toString().getBytes(java.nio.charset.StandardCharsets.UTF_8)));
ByteBuffer output = ByteBuffer.wrap(
sb.toString().getBytes(
java.nio.charset.StandardCharsets.UTF_8));
while (output.hasRemaining()) {
channel.write(output);
}
}
} catch (IOException e) {
}
if (remaining.isEmpty()) {
try { Files.deleteIfExists(PID_REGISTRY_FILE); } catch (IOException e) {}
try { Files.deleteIfExists(KILL_SCRIPT_FILE); } catch (IOException e) {}
}
}

private static void writeKillScript() {
try {
String regName = PID_REGISTRY_FILE.getFileName().toString();
String batName = KILL_SCRIPT_FILE.getFileName().toString();
String script = "@echo off\r\n";
script += "if not exist \"%~dp0" + regName + "\" (\r\n";
script += " echo No PID registry found. Nothing to kill.\r\n";
script += " exit /b 0\r\n";
script += ")\r\n";
script += "for /f \"usebackq tokens=*\" %%p in (\"%~dp0" + regName + "\") do (\r\n";
script += " powershell -NoProfile -Command \"(Get-CimInstance Win32_Process -Filter 'ProcessId=%%p').CommandLine\" 2>nul | findstr /i \"concore\" >nul\r\n";
script += " if not errorlevel 1 (\r\n";
script += " echo Killing concore process %%p\r\n";
script += " taskkill /F /PID %%p >nul 2>&1\r\n";
script += " ) else (\r\n";
script += " echo Skipping PID %%p - not a concore process or not running\r\n";
script += " )\r\n";
script += ")\r\n";
script += "del /q \"%~dp0" + regName + "\" 2>nul\r\n";
script += "del /q \"%~dp0" + batName + "\" 2>nul\r\n";
Files.write(KILL_SCRIPT_FILE, script.getBytes(java.nio.charset.StandardCharsets.UTF_8));
String helperName = "concorekill.ps1";
String script =
"@echo off\r\n" +
"setlocal\r\n" +
"if not exist \"%~dp0" + helperName + "\" (\r\n" +
" echo Missing process cleanup helper: \"%~dp0"
+ helperName + "\"\r\n" +
" exit /b 1\r\n" +
")\r\n" +
"powershell.exe -NoLogo -NoProfile -NonInteractive "
+ "-ExecutionPolicy Bypass -File \"%~dp0"
+ helperName + "\"\r\n" +
"exit /b %ERRORLEVEL%\r\n";
Files.write(KILL_SCRIPT_FILE,
script.getBytes(java.nio.charset.StandardCharsets.UTF_8));
} catch (IOException e) {
}
}

/**
* Sets maxtime from concore.maxtime file, or uses defaultValue if file not found.
* Catches both IOException and RuntimeException to match Python safe_literal_eval.
Expand Down
112 changes: 46 additions & 66 deletions concore.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,103 +31,83 @@
_PID_REGISTRY_FILE = os.path.join(_BASE_DIR, "concorekill_pids.txt")
_KILL_SCRIPT_FILE = os.path.join(_BASE_DIR, "concorekill.bat")

def _current_pid_record():
"""Return current PID and process creation time in Unix milliseconds."""
import psutil
process = psutil.Process(os.getpid())
start_time_ms = int(process.create_time() * 1000)
return f"{process.pid}|{start_time_ms}"
def _register_pid():
"""Append current PID to the shared registry file. Uses file locking on Windows."""
"""Append current process identity to the shared registry."""
import psutil
try:
record = _current_pid_record()
with open(_PID_REGISTRY_FILE, "a") as f:
if hasattr(sys, 'getwindowsversion'):
import msvcrt
try:
f.seek(0)
msvcrt.locking(f.fileno(), msvcrt.LK_LOCK, _LOCK_LEN)
f.write(str(os.getpid()) + "\n")
f.write(record + "\n")
f.flush()
finally:
try:
f.seek(0)
msvcrt.locking(f.fileno(), msvcrt.LK_UNLCK, _LOCK_LEN)
except OSError:
except (OSError, ValueError):
pass
else:
f.write(str(os.getpid()) + "\n")
except OSError:
f.write(record + "\n")
except (OSError, psutil.Error):
pass

def _cleanup_pid():
"""Remove current PID from registry on exit. Uses file locking on Windows."""
"""Remove current process entries while preserving the shared files."""
pid = str(os.getpid())
try:
if not os.path.exists(_PID_REGISTRY_FILE):
return
with open(_PID_REGISTRY_FILE, "r+") as f:
if hasattr(sys, 'getwindowsversion'):
is_windows = hasattr(sys, "getwindowsversion")
if is_windows:
import msvcrt
try:
msvcrt.locking(f.fileno(), msvcrt.LK_LOCK, _LOCK_LEN)
pids = [line.strip() for line in f if line.strip()]
remaining = [p for p in pids if p != pid]
if remaining:
f.seek(0)
f.truncate()
for p in remaining:
f.write(p + "\n")
else:
f.close()
try:
os.remove(_PID_REGISTRY_FILE)
except OSError:
pass
try:
os.remove(_KILL_SCRIPT_FILE)
except OSError:
pass
return
finally:
f.seek(0)
msvcrt.locking(f.fileno(), msvcrt.LK_LOCK, _LOCK_LEN)
try:
f.seek(0)
entries = [line.strip() for line in f if line.strip()]
remaining = [
entry for entry in entries
if entry.split("|", 1)[0].strip() != pid
]
f.seek(0)
f.truncate()
for entry in remaining:
f.write(entry + "\n")
f.flush()
finally:
if is_windows:
try:
f.seek(0)
msvcrt.locking(f.fileno(), msvcrt.LK_UNLCK, _LOCK_LEN)
except (OSError, ValueError):
pass
else:
pids = [line.strip() for line in f if line.strip()]
remaining = [p for p in pids if p != pid]
if remaining:
f.seek(0)
f.truncate()
for p in remaining:
f.write(p + "\n")
else:
f.close()
try:
os.remove(_PID_REGISTRY_FILE)
except OSError:
pass
try:
os.remove(_KILL_SCRIPT_FILE)
except OSError:
pass
except OSError:
pass

def _write_kill_script():
"""Generate concorekill.bat that validates each PID before killing."""
"""Generate a batch launcher for the shared PowerShell cleanup helper."""
try:
reg_name = os.path.basename(_PID_REGISTRY_FILE)
bat_name = os.path.basename(_KILL_SCRIPT_FILE)
script = "@echo off\r\n"
script += 'if not exist "%~dp0' + reg_name + '" (\r\n'
script += " echo No PID registry found. Nothing to kill.\r\n"
script += " exit /b 0\r\n"
script += ")\r\n"
script += 'for /f "usebackq tokens=*" %%p in ("%~dp0' + reg_name + '") do (\r\n'
script += ' powershell -NoProfile -Command "(Get-CimInstance Win32_Process -Filter \'ProcessId=%%p\').CommandLine" 2>nul | findstr /i "concore" >nul\r\n'
script += " if not errorlevel 1 (\r\n"
script += " echo Killing concore process %%p\r\n"
script += " taskkill /F /PID %%p >nul 2>&1\r\n"
script += " ) else (\r\n"
script += " echo Skipping PID %%p - not a concore process or not running\r\n"
script += " )\r\n"
script += ")\r\n"
script += 'del /q "%~dp0' + reg_name + '" 2>nul\r\n'
script += 'del /q "%~dp0' + bat_name + '" 2>nul\r\n'
helper_name = "concorekill.ps1"
script = (
"@echo off\r\n"
"setlocal\r\n"
'if not exist "%~dp0' + helper_name + '" (\r\n'
' echo Missing process cleanup helper: "%~dp0' + helper_name + '"\r\n'
" exit /b 1\r\n"
")\r\n"
'powershell.exe -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "%~dp0' + helper_name + '"\r\n'
"exit /b %ERRORLEVEL%\r\n"
)
with open(_KILL_SCRIPT_FILE, "w", newline="") as f:
f.write(script)
except OSError:
Expand Down
Loading
Loading