os: add Process.finalise() and Process.free() methods to cleanup pipe descriptors
parent
2a6a9c5222
commit
4728d102d9
|
@ -245,6 +245,7 @@ fn (mut context Context) compilation_runner_loop() {
|
||||||
}
|
}
|
||||||
if !context.child_process.is_alive() {
|
if !context.child_process.is_alive() {
|
||||||
context.child_process.wait()
|
context.child_process.wait()
|
||||||
|
context.child_process.close()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -315,18 +316,20 @@ fn (mut context Context) manager_main() {
|
||||||
time.sleep(200 * time.millisecond)
|
time.sleep(200 * time.millisecond)
|
||||||
}
|
}
|
||||||
if !(worker_process.code == 255 && worker_process.status == .exited) {
|
if !(worker_process.code == 255 && worker_process.status == .exited) {
|
||||||
|
worker_process.close()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
worker_process.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut context Context) worker_main() {
|
fn (mut context Context) worker_main() {
|
||||||
context.rerun_channel = chan RerunCommand{cap: 10}
|
context.rerun_channel = chan RerunCommand{cap: 10}
|
||||||
os.signal(C.SIGINT, fn () {
|
os.signal_opt(.int, fn (_ os.Signal) {
|
||||||
mut context := unsafe { &Context(voidptr(&ccontext)) }
|
mut context := unsafe { &Context(voidptr(&ccontext)) }
|
||||||
context.is_exiting = true
|
context.is_exiting = true
|
||||||
context.kill_pgroup()
|
context.kill_pgroup()
|
||||||
})
|
}) or { panic(err) }
|
||||||
go context.compilation_runner_loop()
|
go context.compilation_runner_loop()
|
||||||
change_detection_loop(context)
|
change_detection_loop(context)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,14 @@ module os
|
||||||
// ProcessState.stopped - the process was running, but was stopped temporarily
|
// ProcessState.stopped - the process was running, but was stopped temporarily
|
||||||
// ProcessState.exited - the process has finished/exited
|
// ProcessState.exited - the process has finished/exited
|
||||||
// ProcessState.aborted - the process was terminated by a signal
|
// ProcessState.aborted - the process was terminated by a signal
|
||||||
|
// ProcessState.closed - the process resources like opened file descriptors were freed/discarded, final state.
|
||||||
pub enum ProcessState {
|
pub enum ProcessState {
|
||||||
not_started
|
not_started
|
||||||
running
|
running
|
||||||
stopped
|
stopped
|
||||||
exited
|
exited
|
||||||
aborted
|
aborted
|
||||||
|
closed
|
||||||
}
|
}
|
||||||
|
|
||||||
[heap]
|
[heap]
|
||||||
|
@ -132,6 +134,34 @@ pub fn (mut p Process) wait() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// close - free the OS resources associated with the process.
|
||||||
|
// Can be called multiple times, but will free the resources just once.
|
||||||
|
// This sets the process state to .closed, which is final.
|
||||||
|
pub fn (mut p Process) close() {
|
||||||
|
if p.status in [.not_started, .closed] {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.status = .closed
|
||||||
|
$if !windows {
|
||||||
|
for i in 0 .. 3 {
|
||||||
|
if p.stdio_fd[i] != 0 {
|
||||||
|
fd_close(p.stdio_fd[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[unsafe]
|
||||||
|
pub fn (mut p Process) free() {
|
||||||
|
p.close()
|
||||||
|
unsafe {
|
||||||
|
p.filename.free()
|
||||||
|
p.err.free()
|
||||||
|
p.args.free()
|
||||||
|
p.env.free()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// _spawn - should not be called directly, but only by p.run()/p.wait() .
|
// _spawn - should not be called directly, but only by p.run()/p.wait() .
|
||||||
// It encapsulates the fork/execve mechanism that allows the
|
// It encapsulates the fork/execve mechanism that allows the
|
||||||
|
|
|
@ -52,6 +52,7 @@ fn test_run() {
|
||||||
//
|
//
|
||||||
eprintln('polling iterations: $i')
|
eprintln('polling iterations: $i')
|
||||||
assert i < 50
|
assert i < 50
|
||||||
|
p.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_wait() {
|
fn test_wait() {
|
||||||
|
@ -61,6 +62,7 @@ fn test_wait() {
|
||||||
assert p.status == .exited
|
assert p.status == .exited
|
||||||
assert p.code == 0
|
assert p.code == 0
|
||||||
assert p.pid != os.getpid()
|
assert p.pid != os.getpid()
|
||||||
|
p.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_slurping_output() {
|
fn test_slurping_output() {
|
||||||
|
@ -73,6 +75,7 @@ fn test_slurping_output() {
|
||||||
assert p.code == 0
|
assert p.code == 0
|
||||||
output := p.stdout_slurp().trim_space()
|
output := p.stdout_slurp().trim_space()
|
||||||
errors := p.stderr_slurp().trim_space()
|
errors := p.stderr_slurp().trim_space()
|
||||||
|
p.close()
|
||||||
$if trace_process_output ? {
|
$if trace_process_output ? {
|
||||||
eprintln('---------------------------')
|
eprintln('---------------------------')
|
||||||
eprintln('p output: "$output"')
|
eprintln('p output: "$output"')
|
||||||
|
|
Loading…
Reference in New Issue