summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ebin/rexi.app6
-rw-r--r--ebin/rexi.appup5
-rw-r--r--src/rexi_monitor.erl40
3 files changed, 48 insertions, 3 deletions
diff --git a/ebin/rexi.app b/ebin/rexi.app
index e54a2533..6e80386a 100644
--- a/ebin/rexi.app
+++ b/ebin/rexi.app
@@ -1,7 +1,7 @@
{application, rexi, [
- {description, "Lightweight RPC server"},
- {vsn, "1.0"},
- {modules, [rexi, rexi_app, rexi_sup, rexi_server]},
+ {description, "lightweight RPC server"},
+ {vsn, "1.1"},
+ {modules, [rexi, rexi_app, rexi_sup, rexi_monitor, rexi_server]},
{registered, [rexi_sup, rexi_server]},
{applications, [kernel, stdlib]},
{mod, {rexi_app,[]}}
diff --git a/ebin/rexi.appup b/ebin/rexi.appup
new file mode 100644
index 00000000..7ed8ad73
--- /dev/null
+++ b/ebin/rexi.appup
@@ -0,0 +1,5 @@
+{"1.1",[{"1.0",[
+ {load_module, rexi},
+ {add_module, rexi_monitor},
+ {load_module, rexi_server}
+]}],[{"1.0",[]}]}.
diff --git a/src/rexi_monitor.erl b/src/rexi_monitor.erl
new file mode 100644
index 00000000..bbff22b3
--- /dev/null
+++ b/src/rexi_monitor.erl
@@ -0,0 +1,40 @@
+-module(rexi_monitor).
+-export([start/1, stop/1]).
+
+-include_lib("eunit/include/eunit.hrl").
+
+%% @doc spawn_links a process which monitors the supplied list of items and
+%% returns the process ID. If a monitored process exits, the caller will
+%% receive a {rexi_DOWN, MonitoringPid, DeadPid, Reason} message.
+-spec start([pid() | atom() | {atom(),node()}]) -> pid().
+start(Procs) ->
+ Parent = self(),
+ spawn_link(fun() ->
+ [erlang:monitor(process, P) || P <- Procs],
+ wait_monitors(Parent)
+ end).
+
+%% @doc Cleanly shut down the monitoring process and flush all rexi_DOWN
+%% messages from our mailbox.
+-spec stop(pid()) -> ok.
+stop(MonitoringPid) ->
+ MonitoringPid ! {self(), shutdown},
+ flush_down_messages().
+
+%% internal functions %%
+
+wait_monitors(Parent) ->
+ receive
+ {'DOWN', _, process, Pid, Reason} ->
+ Parent ! {rexi_DOWN, self(), Pid, Reason},
+ wait_monitors(Parent);
+ {Parent, shutdown} ->
+ ok
+ end.
+
+flush_down_messages() ->
+ receive {rexi_DOWN, _, _, _} ->
+ flush_down_messages()
+ after 0 ->
+ ok
+ end.