mirror of
https://github.com/ipfs/kubo.git
synced 2026-03-12 19:57:55 +08:00
85 lines
2.0 KiB
Go
85 lines
2.0 KiB
Go
package harness
|
|
|
|
import (
|
|
"os"
|
|
"sync"
|
|
"syscall"
|
|
"time"
|
|
)
|
|
|
|
// processTracker keeps track of all daemon processes started during tests
|
|
type processTracker struct {
|
|
mu sync.Mutex
|
|
processes map[int]*os.Process
|
|
}
|
|
|
|
// globalProcessTracker is a package-level tracker for all spawned daemons
|
|
var globalProcessTracker = &processTracker{
|
|
processes: make(map[int]*os.Process),
|
|
}
|
|
|
|
// RegisterProcess adds a process to the tracker
|
|
func (pt *processTracker) RegisterProcess(proc *os.Process) {
|
|
if proc == nil {
|
|
return
|
|
}
|
|
pt.mu.Lock()
|
|
defer pt.mu.Unlock()
|
|
pt.processes[proc.Pid] = proc
|
|
log.Debugf("registered daemon process PID %d", proc.Pid)
|
|
}
|
|
|
|
// UnregisterProcess removes a process from the tracker
|
|
func (pt *processTracker) UnregisterProcess(pid int) {
|
|
pt.mu.Lock()
|
|
defer pt.mu.Unlock()
|
|
delete(pt.processes, pid)
|
|
log.Debugf("unregistered daemon process PID %d", pid)
|
|
}
|
|
|
|
// KillAll forcefully terminates all tracked processes
|
|
func (pt *processTracker) KillAll() {
|
|
pt.mu.Lock()
|
|
defer pt.mu.Unlock()
|
|
|
|
for pid, proc := range pt.processes {
|
|
log.Debugf("force killing daemon process PID %d", pid)
|
|
|
|
// Try SIGTERM first
|
|
if err := proc.Signal(syscall.SIGTERM); err != nil {
|
|
if !IsProcessDone(err) {
|
|
log.Debugf("error sending SIGTERM to PID %d: %v", pid, err)
|
|
}
|
|
}
|
|
|
|
// Give it a moment to terminate
|
|
time.Sleep(100 * time.Millisecond)
|
|
|
|
// Force kill if still running
|
|
if err := proc.Kill(); err != nil {
|
|
if !IsProcessDone(err) {
|
|
log.Debugf("error killing PID %d: %v", pid, err)
|
|
}
|
|
}
|
|
|
|
// Clean up entry
|
|
delete(pt.processes, pid)
|
|
}
|
|
|
|
if len(pt.processes) > 0 {
|
|
log.Debugf("cleaned up %d daemon processes", len(pt.processes))
|
|
}
|
|
}
|
|
|
|
// IsProcessDone checks if an error indicates the process has already exited
|
|
func IsProcessDone(err error) bool {
|
|
return err == os.ErrProcessDone
|
|
}
|
|
|
|
// CleanupDaemonProcesses kills all tracked daemon processes
|
|
// This should be called in test cleanup or panic recovery
|
|
func CleanupDaemonProcesses() {
|
|
globalProcessTracker.KillAll()
|
|
}
|
|
|