[erlang-patches] Supervisor Shutdown

Vance Shipley vances@REDACTED
Fri Apr 1 21:14:53 CEST 2011


In a recent project(*) I found it necessary to forge an EXIT
message in order to shutdown a supervisor which I had earlier
dynamically added as a child to a simple_one_for_one supervisor.
Finding this rather distasteful I created the attached patch to
add a terminate/1 function to the supervisor module.

	git fetch git@REDACTED:vances/otp.git supervisor_terminate

-- 
	-Vance

(*) http://github.com/vances/radierl
-------------- next part --------------
>From c3b1cd9a4c8d1a426dde5f482047807323e6da09 Mon Sep 17 00:00:00 2001
From: Vance Shipley <vances@REDACTED>
Date: Fri, 1 Apr 2011 14:11:33 -0400
Subject: [PATCH] Implement new API function to shutdown a supervisor.

When a supervisor is a dynamically started child of a
simple_one_for_one supervisor there is currently no
method to cleanly terminate it later.  The work around
is to send it an EXIT message forged with the pid of the
parent supervisor.  The new terminate/1 API function will
cleanly shutdown the supervisor and all children.
---
 lib/stdlib/doc/src/supervisor.xml |   12 ++++++++++++
 lib/stdlib/src/supervisor.erl     |    9 ++++++++-
 2 files changed, 20 insertions(+), 1 deletions(-)

diff --git a/lib/stdlib/doc/src/supervisor.xml b/lib/stdlib/doc/src/supervisor.xml
index 45fa084..e49a603 100644
--- a/lib/stdlib/doc/src/supervisor.xml
+++ b/lib/stdlib/doc/src/supervisor.xml
@@ -306,6 +306,18 @@ child_spec() = {Id,StartFunc,Restart,Shutdown,Type,Modules}
       </desc>
     </func>
     <func>
+      <name>terminate(SupRef) -> ok</name>
+      <fsummary>Terminate a supervisor.</fsummary>
+      <type>
+        <v>SupRef = Name | {Name,Node} | {global,Name} | pid()</v>
+        <v> Name = Node = atom()</v>
+      </type>
+      <desc>
+        <p>Tells the supervisor <c>SupRef</c> to terminate all children
+          and shutdown.</p>
+      </desc>
+    </func>
+    <func>
       <name>terminate_child(SupRef, Id) -> Result</name>
       <fsummary>Terminate a child process belonging to a supervisor.</fsummary>
       <type>
diff --git a/lib/stdlib/src/supervisor.erl b/lib/stdlib/src/supervisor.erl
index 3c5800e..511db36 100644
--- a/lib/stdlib/src/supervisor.erl
+++ b/lib/stdlib/src/supervisor.erl
@@ -23,7 +23,7 @@
 %% External exports
 -export([start_link/2, start_link/3,
 	 start_child/2, restart_child/2,
-	 delete_child/2, terminate_child/2,
+	 delete_child/2, terminate/1, terminate_child/2,
 	 which_children/1, count_children/1,
 	 check_childspecs/1]).
 
@@ -130,6 +130,10 @@ restart_child(Supervisor, Name) ->
 delete_child(Supervisor, Name) ->
     call(Supervisor, {delete_child, Name}).
 
+-spec terminate(sup_ref()) -> 'ok'.
+terminate(Supervisor) ->
+	call(Supervisor, terminate).
+
 %%-----------------------------------------------------------------
 %% Func: terminate_child/2
 %% Returns: ok | {error, Reason}
@@ -341,6 +345,9 @@ handle_call({delete_child, Name}, _From, State) ->
 	    {reply, {error, not_found}, State}
     end;
 
+handle_call(terminate, From, State) ->
+	{stop, shutdown, ok, State};
+
 handle_call({terminate_child, Name}, _From, State) ->
     case get_child(Name, State) of
 	{value, Child} ->
-- 
1.7.3.2



More information about the erlang-patches mailing list