]> Repositorios git - scryer-prolog.git/commitdiff
don't remove the child on wait/kill
authorBennet Bleßmann <[email protected]>
Sun, 20 Jul 2025 22:06:03 +0000 (00:06 +0200)
committerBennet Bleßmann <[email protected]>
Fri, 1 Aug 2025 18:33:15 +0000 (20:33 +0200)
- 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

build/instructions_template.rs
src/lib/process.pl
src/machine/dispatch.rs
src/machine/system_calls.rs

index 0c1320b1d003e02f8d418ed8b077384ac6a067ae..346e68afc84a28db87db0dc99c8efc7b8a414e30 100644 (file)
@@ -543,6 +543,8 @@ enum SystemClauseType {
     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")))]
@@ -1834,6 +1836,7 @@ fn generate_instruction_preface() -> TokenStream {
                     &Instruction::CallProcessCreate |
                     &Instruction::CallProcessWait |
                     &Instruction::CallProcessKill |
+                    &Instruction::CallProcessRelease |
                     &Instruction::CallPid |
                     &Instruction::CallCharsBase64 |
                     &Instruction::CallDevourWhitespace |
@@ -2075,6 +2078,7 @@ fn generate_instruction_preface() -> TokenStream {
                     &Instruction::ExecuteProcessCreate |
                     &Instruction::ExecuteProcessWait |
                     &Instruction::ExecuteProcessKill |
+                    &Instruction::ExecuteProcessRelease |
                     &Instruction::ExecutePid |
                     &Instruction::ExecuteCharsBase64 |
                     &Instruction::ExecuteDevourWhitespace |
index b17b3224cbf90569d2aa1f6a05ea07bbc26b4f44..358484c53587c5fae8bcce3d94de8343aa56ab1c 100644 (file)
@@ -53,7 +53,9 @@ process_kill(Pid) :-
     must_be(integer, Pid),
     '$process_kill'(Pid).
 
-process_release(Pid) :- process_wait(Pid, _).
+process_release(Pid) :- 
+    process_wait(Pid, _),
+    '$process_release'(Pid).
 
 
 must_be_known_options(_, _,  []).
index 66133c3c683f5ffdf7d444440f58da9f2d5a4a01..00396e239012d1e40057f821a2facc0fcd1ceea5 100644 (file)
@@ -4811,6 +4811,14 @@ impl Machine {
                         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);
index f40a6cbceaaac58b2fad3661d4d5e8809b5ceaa2..a1eb15be3aaf9817004fb3f09e29a29349c28bdf 100644 (file)
@@ -8498,13 +8498,14 @@ impl Machine {
             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(())
@@ -8637,7 +8638,7 @@ impl Machine {
                 .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));
@@ -8679,7 +8680,6 @@ impl Machine {
                             self.machine_st.throw_resource_error(resource_err_loc);
                         }
                     }
-                    Ok(())
                 } else {
                     #[cfg(unix)]
                     {
@@ -8687,7 +8687,7 @@ impl Machine {
 
                         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) => {
@@ -8696,19 +8696,17 @@ impl Machine {
                                 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(
@@ -8737,7 +8735,7 @@ impl Machine {
                 .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));
@@ -8752,6 +8750,25 @@ impl Machine {
         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));