THRIFT-211. erlang: Support "tethered" clients

Add a client option that causes clients to monitor their creators
and terminate when the creator dies.  This makes it possible to
prevent client leaks without linking, because the latter causes
application code to be killed when a transport error occurs and
exits are not trapped.

git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@781636 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/erl/src/thrift_client.erl b/lib/erl/src/thrift_client.erl
index 92c531a..d5bb146 100644
--- a/lib/erl/src/thrift_client.erl
+++ b/lib/erl/src/thrift_client.erl
@@ -101,12 +101,14 @@
 %% ProtocolFactory :: fun() -> thrift_protocol()
 start(ProtocolFactory, Service, ClientOpts)
   when is_function(ProtocolFactory), is_atom(Service) ->
-    Starter =
+    {Starter, Opts} =
         case lists:keysearch(monitor, 1, ClientOpts) of
             {value, {monitor, link}} ->
-                start_link;
+                {start_link, []};
+            {value, {monitor, tether}} ->
+                {start, [{tether, self()}]};
             _ ->
-                start
+                {start, []}
         end,
 
     Connect =
@@ -119,7 +121,7 @@
         end,
 
 
-    Started = gen_server:Starter(?MODULE, [Service], []),
+    Started = gen_server:Starter(?MODULE, [Service, Opts], []),
 
     if
         Connect ->
@@ -171,7 +173,13 @@
 %%                         {stop, Reason}
 %% Description: Initiates the server
 %%--------------------------------------------------------------------
-init([Service]) ->
+init([Service, Opts]) ->
+    case lists:keysearch(tether, 1, Opts) of
+        {value, {tether, Pid}} ->
+            erlang:monitor(process, Pid);
+        _Else ->
+            ok
+    end,
     {ok, #state{service = Service}}.
 
 %%--------------------------------------------------------------------
@@ -262,6 +270,11 @@
 %%                                       {stop, Reason, State}
 %% Description: Handling all non call/cast messages
 %%--------------------------------------------------------------------
+handle_info({'DOWN', MonitorRef, process, Pid, _Info}, State)
+  when is_reference(MonitorRef), is_pid(Pid) ->
+    %% We don't actually verify the correctness of the DOWN message.
+    {stop, parent_died, State};
+
 handle_info(_Info, State) ->
     {noreply, State}.