From 7358bb6777d1f3d110882c3cd54caa7ea5713c4a Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Mon, 11 Mar 2024 23:18:10 +0100 Subject: [PATCH] Add `Env::is_process_alive` and `LocalPid::is_alive` --- rustler/src/types/local_pid.rs | 11 +++++++++++ rustler_tests/lib/rustler_test.ex | 1 + rustler_tests/native/rustler_test/src/lib.rs | 1 + .../native/rustler_test/src/test_env.rs | 10 +++++++--- rustler_tests/test/env_test.exs | 18 ++++++++++++++++++ 5 files changed, 38 insertions(+), 3 deletions(-) diff --git a/rustler/src/types/local_pid.rs b/rustler/src/types/local_pid.rs index 437569ae..9babda8b 100644 --- a/rustler/src/types/local_pid.rs +++ b/rustler/src/types/local_pid.rs @@ -15,6 +15,11 @@ impl LocalPid { pub fn from_c_arg(erl_nif_pid: ErlNifPid) -> Self { LocalPid { c: erl_nif_pid } } + + /// Check whether the given process is alive + pub fn is_alive(self, env: Env) -> bool { + env.is_process_alive(self) + } } impl<'a> Decoder<'a> for LocalPid { @@ -48,4 +53,10 @@ impl<'a> Env<'a> { c: unsafe { pid.assume_init() }, } } + + /// Checks whether the given process is alive + pub fn is_process_alive(self, pid: LocalPid) -> bool { + let res = unsafe { rustler_sys::enif_is_process_alive(self.as_c_arg(), pid.as_c_arg()) }; + res != 0 + } } diff --git a/rustler_tests/lib/rustler_test.ex b/rustler_tests/lib/rustler_test.ex index ce63a45d..9a7c9b63 100644 --- a/rustler_tests/lib/rustler_test.ex +++ b/rustler_tests/lib/rustler_test.ex @@ -87,6 +87,7 @@ defmodule RustlerTest do def send_all(_, _), do: err() def send(_, _), do: err() def whereis_pid(_), do: err() + def is_process_alive(_), do: err() def sublists(_), do: err() def tuple_echo(_), do: err() diff --git a/rustler_tests/native/rustler_test/src/lib.rs b/rustler_tests/native/rustler_test/src/lib.rs index a7a4f700..594da3d1 100644 --- a/rustler_tests/native/rustler_test/src/lib.rs +++ b/rustler_tests/native/rustler_test/src/lib.rs @@ -63,6 +63,7 @@ rustler::init!( test_env::send_all, test_env::send, test_env::whereis_pid, + test_env::is_process_alive, test_env::sublists, test_codegen::tuple_echo, test_codegen::record_echo, diff --git a/rustler_tests/native/rustler_test/src/test_env.rs b/rustler_tests/native/rustler_test/src/test_env.rs index c50b31e8..06dd63d6 100644 --- a/rustler_tests/native/rustler_test/src/test_env.rs +++ b/rustler_tests/native/rustler_test/src/test_env.rs @@ -24,9 +24,13 @@ pub fn send<'a>(env: Env<'a>, pid: LocalPid, msg: Term<'a>) -> Atom { } #[rustler::nif] -pub fn whereis_pid<'a>(env: Env<'a>, term: Term<'a>) -> Term<'a> { - let result = env.whereis_pid(term); - result.encode(env) +pub fn whereis_pid<'a>(env: Env<'a>, term: Term<'a>) -> Option { + env.whereis_pid(term) +} + +#[rustler::nif] +pub fn is_process_alive(env: Env, pid: LocalPid) -> bool { + env.is_process_alive(pid) } #[rustler::nif] diff --git a/rustler_tests/test/env_test.exs b/rustler_tests/test/env_test.exs index d0f16e0b..972f096e 100644 --- a/rustler_tests/test/env_test.exs +++ b/rustler_tests/test/env_test.exs @@ -68,6 +68,24 @@ defmodule RustlerTest.EnvTest do assert nil == RustlerTest.whereis_pid(:not_a_registered_name) end + test "is_process_alive" do + assert true == RustlerTest.is_process_alive(self()) + + task = + Task.async(fn -> + receive do + :exit -> :ok + end + end) + + assert true == RustlerTest.is_process_alive(task.pid) + + send(task.pid, :exit) + Task.await(task) + + assert false == RustlerTest.is_process_alive(task.pid) + end + test "send_error" do task = Task.async(fn ->