don't remove the child on wait/kill
- important for wait with timout(0) as we may want to try again until the process has realy exited. - make process_release release the process instead
This commit is contained in:
@@ -543,6 +543,8 @@ enum SystemClauseType {
|
|||||||
ProcessWait,
|
ProcessWait,
|
||||||
#[strum_discriminants(strum(props(Arity = "1", Name = "$process_kill")))]
|
#[strum_discriminants(strum(props(Arity = "1", Name = "$process_kill")))]
|
||||||
ProcessKill,
|
ProcessKill,
|
||||||
|
#[strum_discriminants(strum(props(Arity = "1", Name = "$process_release")))]
|
||||||
|
ProcessRelease,
|
||||||
#[strum_discriminants(strum(props(Arity = "1", Name = "$pid")))]
|
#[strum_discriminants(strum(props(Arity = "1", Name = "$pid")))]
|
||||||
Pid,
|
Pid,
|
||||||
#[strum_discriminants(strum(props(Arity = "4", Name = "$chars_base64")))]
|
#[strum_discriminants(strum(props(Arity = "4", Name = "$chars_base64")))]
|
||||||
@@ -1834,6 +1836,7 @@ fn generate_instruction_preface() -> TokenStream {
|
|||||||
&Instruction::CallProcessCreate |
|
&Instruction::CallProcessCreate |
|
||||||
&Instruction::CallProcessWait |
|
&Instruction::CallProcessWait |
|
||||||
&Instruction::CallProcessKill |
|
&Instruction::CallProcessKill |
|
||||||
|
&Instruction::CallProcessRelease |
|
||||||
&Instruction::CallPid |
|
&Instruction::CallPid |
|
||||||
&Instruction::CallCharsBase64 |
|
&Instruction::CallCharsBase64 |
|
||||||
&Instruction::CallDevourWhitespace |
|
&Instruction::CallDevourWhitespace |
|
||||||
@@ -2075,6 +2078,7 @@ fn generate_instruction_preface() -> TokenStream {
|
|||||||
&Instruction::ExecuteProcessCreate |
|
&Instruction::ExecuteProcessCreate |
|
||||||
&Instruction::ExecuteProcessWait |
|
&Instruction::ExecuteProcessWait |
|
||||||
&Instruction::ExecuteProcessKill |
|
&Instruction::ExecuteProcessKill |
|
||||||
|
&Instruction::ExecuteProcessRelease |
|
||||||
&Instruction::ExecutePid |
|
&Instruction::ExecutePid |
|
||||||
&Instruction::ExecuteCharsBase64 |
|
&Instruction::ExecuteCharsBase64 |
|
||||||
&Instruction::ExecuteDevourWhitespace |
|
&Instruction::ExecuteDevourWhitespace |
|
||||||
|
|||||||
@@ -53,7 +53,9 @@ process_kill(Pid) :-
|
|||||||
must_be(integer, Pid),
|
must_be(integer, Pid),
|
||||||
'$process_kill'(Pid).
|
'$process_kill'(Pid).
|
||||||
|
|
||||||
process_release(Pid) :- process_wait(Pid, _).
|
process_release(Pid) :-
|
||||||
|
process_wait(Pid, _),
|
||||||
|
'$process_release'(Pid).
|
||||||
|
|
||||||
|
|
||||||
must_be_known_options(_, _, []).
|
must_be_known_options(_, _, []).
|
||||||
|
|||||||
@@ -4811,6 +4811,14 @@ impl Machine {
|
|||||||
try_or_throw!(self.machine_st, self.process_kill());
|
try_or_throw!(self.machine_st, self.process_kill());
|
||||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||||
}
|
}
|
||||||
|
&Instruction::CallProcessRelease => {
|
||||||
|
try_or_throw!(self.machine_st, self.process_release());
|
||||||
|
step_or_fail!(self, self.machine_st.p += 1);
|
||||||
|
}
|
||||||
|
&Instruction::ExecuteProcessRelease => {
|
||||||
|
try_or_throw!(self.machine_st, self.process_release());
|
||||||
|
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||||
|
}
|
||||||
&Instruction::CallPid => {
|
&Instruction::CallPid => {
|
||||||
self.pid();
|
self.pid();
|
||||||
step_or_fail!(self, self.machine_st.p += 1);
|
step_or_fail!(self, self.machine_st.p += 1);
|
||||||
|
|||||||
@@ -8498,13 +8498,14 @@ impl Machine {
|
|||||||
Ok(child) => {
|
Ok(child) => {
|
||||||
let pid = child.id();
|
let pid = child.id();
|
||||||
|
|
||||||
|
dbg!(pid);
|
||||||
|
|
||||||
self.machine_st.child_processes.insert(pid, child);
|
self.machine_st.child_processes.insert(pid, child);
|
||||||
|
|
||||||
self.machine_st.bind(
|
unify!(
|
||||||
pid_r
|
self.machine_st,
|
||||||
.as_var()
|
pid_r,
|
||||||
.expect("invalid values should have been rejected on the prolog side"),
|
fixnum_as_cell!(Fixnum::build_with(pid))
|
||||||
fixnum_as_cell!(Fixnum::build_with(pid)),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -8637,7 +8638,7 @@ impl Machine {
|
|||||||
.existence_error(ExistenceError::Process(pid_r));
|
.existence_error(ExistenceError::Process(pid_r));
|
||||||
return Err(self.machine_st.error_form(err, stub_gen()));
|
return Err(self.machine_st.error_form(err, stub_gen()));
|
||||||
};
|
};
|
||||||
let Some(mut child) = self.machine_st.child_processes.remove(&pid) else {
|
let Some(child) = self.machine_st.child_processes.get_mut(&pid) else {
|
||||||
let err = self
|
let err = self
|
||||||
.machine_st
|
.machine_st
|
||||||
.existence_error(ExistenceError::Process(pid_r));
|
.existence_error(ExistenceError::Process(pid_r));
|
||||||
@@ -8679,7 +8680,6 @@ impl Machine {
|
|||||||
self.machine_st.throw_resource_error(resource_err_loc);
|
self.machine_st.throw_resource_error(resource_err_loc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
} else {
|
} else {
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
{
|
{
|
||||||
@@ -8687,7 +8687,7 @@ impl Machine {
|
|||||||
|
|
||||||
if let Some(signal) = ExitStatusExt::signal(&exit_status) {
|
if let Some(signal) = ExitStatusExt::signal(&exit_status) {
|
||||||
let mut writer =
|
let mut writer =
|
||||||
Heap::functor_writer(functor!(atom!("signal"), [fixnum(signal)]));
|
Heap::functor_writer(functor!(atom!("killed"), [fixnum(signal)]));
|
||||||
|
|
||||||
match writer(&mut self.machine_st.heap) {
|
match writer(&mut self.machine_st.heap) {
|
||||||
Ok(loc) => {
|
Ok(loc) => {
|
||||||
@@ -8696,20 +8696,18 @@ impl Machine {
|
|||||||
Err(resource_err_loc) => {
|
Err(resource_err_loc) => {
|
||||||
self.machine_st.throw_resource_error(resource_err_loc);
|
self.machine_st.throw_resource_error(resource_err_loc);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
Ok(())
|
|
||||||
} else {
|
} else {
|
||||||
unify!(self.machine_st, status_r, atom_as_cell!(atom!("unknown")));
|
unify!(self.machine_st, status_r, atom_as_cell!(atom!("unknown")));
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(not(unix))]
|
#[cfg(not(unix))]
|
||||||
{
|
{
|
||||||
unify!(self.machine_st, status_r, atom_as_cell!(atom!("unknown")));
|
unify!(self.machine_st, status_r, atom_as_cell!(atom!("unknown")));
|
||||||
|
}
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
let perm_error = self.machine_st.permission_error(
|
let perm_error = self.machine_st.permission_error(
|
||||||
Permission::Modify,
|
Permission::Modify,
|
||||||
@@ -8737,7 +8735,7 @@ impl Machine {
|
|||||||
.existence_error(ExistenceError::Process(pid_r));
|
.existence_error(ExistenceError::Process(pid_r));
|
||||||
return Err(self.machine_st.error_form(err, stub_gen()));
|
return Err(self.machine_st.error_form(err, stub_gen()));
|
||||||
};
|
};
|
||||||
let Some(mut child) = self.machine_st.child_processes.remove(&pid) else {
|
let Some(child) = self.machine_st.child_processes.get_mut(&pid) else {
|
||||||
let err = self
|
let err = self
|
||||||
.machine_st
|
.machine_st
|
||||||
.existence_error(ExistenceError::Process(pid_r));
|
.existence_error(ExistenceError::Process(pid_r));
|
||||||
@@ -8752,6 +8750,25 @@ impl Machine {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn process_release(&mut self) -> CallResult {
|
||||||
|
fn stub_gen() -> Vec<FunctorElement> {
|
||||||
|
functor_stub(atom!("process_release"), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
let pid_r = self.deref_register(1);
|
||||||
|
let Some(pid) = pid_r
|
||||||
|
.to_fixnum()
|
||||||
|
.and_then(|elem| elem.get_num().try_into().ok())
|
||||||
|
else {
|
||||||
|
let err = self
|
||||||
|
.machine_st
|
||||||
|
.existence_error(ExistenceError::Process(pid_r));
|
||||||
|
return Err(self.machine_st.error_form(err, stub_gen()));
|
||||||
|
};
|
||||||
|
self.machine_st.child_processes.remove(&pid);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn chars_base64(&mut self) -> CallResult {
|
pub(crate) fn chars_base64(&mut self) -> CallResult {
|
||||||
let padding = cell_as_atom!(self.deref_register(3));
|
let padding = cell_as_atom!(self.deref_register(3));
|
||||||
|
|||||||
Reference in New Issue
Block a user