ProcessWait,
#[strum_discriminants(strum(props(Arity = "1", Name = "$process_kill")))]
ProcessKill,
+ #[strum_discriminants(strum(props(Arity = "1", Name = "$process_release")))]
+ ProcessRelease,
#[strum_discriminants(strum(props(Arity = "1", Name = "$pid")))]
Pid,
#[strum_discriminants(strum(props(Arity = "4", Name = "$chars_base64")))]
&Instruction::CallProcessCreate |
&Instruction::CallProcessWait |
&Instruction::CallProcessKill |
+ &Instruction::CallProcessRelease |
&Instruction::CallPid |
&Instruction::CallCharsBase64 |
&Instruction::CallDevourWhitespace |
&Instruction::ExecuteProcessCreate |
&Instruction::ExecuteProcessWait |
&Instruction::ExecuteProcessKill |
+ &Instruction::ExecuteProcessRelease |
&Instruction::ExecutePid |
&Instruction::ExecuteCharsBase64 |
&Instruction::ExecuteDevourWhitespace |
try_or_throw!(self.machine_st, self.process_kill());
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 => {
self.pid();
step_or_fail!(self, self.machine_st.p += 1);
Ok(child) => {
let pid = child.id();
+ dbg!(pid);
+
self.machine_st.child_processes.insert(pid, child);
- self.machine_st.bind(
- pid_r
- .as_var()
- .expect("invalid values should have been rejected on the prolog side"),
- fixnum_as_cell!(Fixnum::build_with(pid)),
+ unify!(
+ self.machine_st,
+ pid_r,
+ fixnum_as_cell!(Fixnum::build_with(pid))
);
Ok(())
.existence_error(ExistenceError::Process(pid_r));
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
.machine_st
.existence_error(ExistenceError::Process(pid_r));
self.machine_st.throw_resource_error(resource_err_loc);
}
}
- Ok(())
} else {
#[cfg(unix)]
{
if let Some(signal) = ExitStatusExt::signal(&exit_status) {
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) {
Ok(loc) => {
Err(resource_err_loc) => {
self.machine_st.throw_resource_error(resource_err_loc);
}
- };
- Ok(())
+ }
} else {
unify!(self.machine_st, status_r, atom_as_cell!(atom!("unknown")));
- Ok(())
}
}
#[cfg(not(unix))]
{
unify!(self.machine_st, status_r, atom_as_cell!(atom!("unknown")));
- Ok(())
}
}
+ Ok(())
}
Err(_) => {
let perm_error = self.machine_st.permission_error(
.existence_error(ExistenceError::Process(pid_r));
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
.machine_st
.existence_error(ExistenceError::Process(pid_r));
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)]
pub(crate) fn chars_base64(&mut self) -> CallResult {
let padding = cell_as_atom!(self.deref_register(3));