Cleanup child processes on Windows VisualC and Mingw. On Linux those processes quit when ngspice quits.

This commit is contained in:
Brian Taylor 2023-10-18 14:48:16 -07:00 committed by Holger Vogt
parent 864ef7925c
commit 04c68d5f30
1 changed files with 30 additions and 4 deletions

View File

@ -126,6 +126,7 @@ typedef struct {
int pipe_to_child; int pipe_to_child;
int pipe_from_child; int pipe_from_child;
unsigned int error_count; unsigned int error_count;
int pid_of_child;
uint8_t N_din, N_dout; // number of inputs/outputs bytes uint8_t N_din, N_dout; // number of inputs/outputs bytes
Digital_State_t dout_old[256]; // max possible storage to track output changes Digital_State_t dout_old[256]; // max possible storage to track output changes
} Process_t; } Process_t;
@ -133,6 +134,7 @@ typedef struct {
#if defined(_MSC_VER) || defined(__MINGW64__) #if defined(_MSC_VER) || defined(__MINGW64__)
#include <io.h> #include <io.h>
static int w_start(char *system_command, const char *const *argv, Process_t * process); static int w_start(char *system_command, const char *const *argv, Process_t * process);
static void w_cleanup_child_process(Process_t *process);
#endif #endif
static int sendheader(Process_t * process, int N_din, int N_dout) static int sendheader(Process_t * process, int N_din, int N_dout)
@ -292,6 +294,7 @@ static int start(char *system_command, char * c_argv[], Process_t * process)
} }
} }
else { else {
process->pid_of_child = pid;
process->pipe_to_child = pipe_to_child[1]; process->pipe_to_child = pipe_to_child[1];
process->pipe_from_child = pipe_from_child[0]; process->pipe_from_child = pipe_from_child[0];
close(pipe_to_child[0]); close(pipe_to_child[0]);
@ -302,13 +305,15 @@ static int start(char *system_command, char * c_argv[], Process_t * process)
} }
#endif #endif
static void cm_d_process_callback(ARGS, Mif_Callback_Reason_t reason) static void cm_d_process_callback(ARGS, Mif_Callback_Reason_t reason)
{ {
switch (reason) { switch (reason) {
case MIF_CB_DESTROY: { case MIF_CB_DESTROY: {
Process_t *proc = STATIC_VAR(process); Process_t *proc = STATIC_VAR(process);
if (proc) { if (proc) {
#if defined(_MSC_VER) || defined(__MINGW64__)
w_cleanup_child_process(proc);
#endif
free(proc); free(proc);
STATIC_VAR(process) = NULL; STATIC_VAR(process) = NULL;
} }
@ -467,6 +472,9 @@ void cm_d_process(ARGS)
#if defined(_MSC_VER) || defined(__MINGW64__) #if defined(_MSC_VER) || defined(__MINGW64__)
#undef BYTE
#undef BOOLEAN
#include <windows.h>
#include <process.h> #include <process.h>
#include <io.h> #include <io.h>
@ -474,7 +482,8 @@ static int w_start(char *system_command, const char *const *argv, Process_t * pr
{ {
int pipe_to_child[2]; int pipe_to_child[2];
int pipe_from_child[2]; int pipe_from_child[2];
intptr_t pid = 0; int pid;
intptr_t sp_result;
int mode = _O_BINARY; int mode = _O_BINARY;
size_t syscmd_len = 0; size_t syscmd_len = 0;
if (system_command) { if (system_command) {
@ -504,14 +513,31 @@ static int w_start(char *system_command, const char *const *argv, Process_t * pr
_close(pipe_from_child[1]); _close(pipe_from_child[1]);
_flushall(); _flushall();
pid = _spawnvp(_P_NOWAIT, system_command, argv); sp_result = _spawnvp(_P_NOWAIT, system_command, argv);
if (pid == -1) { if (sp_result == -1) {
cm_message_printf("ERROR: d_process failed to spawn %s", system_command); cm_message_printf("ERROR: d_process failed to spawn %s", system_command);
return 1; return 1;
} }
pid = GetProcessId((HANDLE)sp_result);
process->pid_of_child = pid;
cm_message_printf("Note: Process %s has pid %u", system_command, pid);
process->pipe_to_child = pipe_to_child[1]; process->pipe_to_child = pipe_to_child[1];
process->pipe_from_child = pipe_from_child[0]; process->pipe_from_child = pipe_from_child[0];
return 0; return 0;
} }
static void w_cleanup_child_process(Process_t *process)
{
HANDLE phand;
if (process && process->pid_of_child) {
phand = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process->pid_of_child);
if (phand != NULL) {
(void) TerminateProcess(phand, 0);
CloseHandle(phand);
}
process->pid_of_child = 0;
}
}
#endif #endif