[erlang-questions] Unidirectional linking?

Raimo Niskanen <>
Wed May 25 11:45:12 CEST 2011


On Wed, May 25, 2011 at 09:28:31AM +0200, Mazen Harake wrote:
> Perhaps something like this:
> 
> process_flag(trap_exit, true),
> Parent = self(),
> Child = spawn_link(fun() -> Parent ! (catch Op) end),
> receive
>   {'EXIT', ParentsParent, Reason} ->
>     exit(Reason);
>   Result ->
>     Result
>  after N ->
>     unlink(Child),
>     exit(Child, timeout),
>     timeout
> end.

Can the parent always have trap_exit true?

If so this becomes (rather) simple:

  process_flag(trap_exit, true),
  ,
  ,
  Parent = self(),
  Ref = make_ref(),
  Child = spawn_link(fun() -> Parent ! {Ref,Op()} end),
  receive
    {'EXIT',Child,Reason} ->
      receive
        {Ref,Result} ->
          {ok,Result}
      after 0 ->
        {error,Reason}
      end;
  after N ->
    exit(Child, timeout),
      receive
        {'EXIT',Child,timeout} ->
          receive
            {Ref,Result} ->
              {ok,Result}
          after 0 ->
            timeout
          end
      end
  end

If you have no control over the parent trap_exit flag I see
no other alternative than involving a third process.

Note that when a linked process exits normally, the link
causes no exit at the other end.

You maybe should think about using supervisers
and all the other heavy OTP stuff. It was designed for
this kind of problems.



> 
> if you get an exit signal from the parent's parent you will exit if you are
> in the receive clause and you will ignore it (unless it is a kill) if you
> are in between the unlink and exit child?
> 
> I do however still think that this is very defensive and that the
> probability of getting an exit between unlink and exit is very small unless
> the timeout in N is exactly the same (very very close to) the timeout that
> the parent's parent has for exiting the parent.
> 
> 
> 
> On 25 May 2011 08:51, Igor Ribeiro Sucupira <> wrote:
> 
> > Supposing someone used the same logic (with timeout/kill) to spawn the
> > parent process, the parent could be killed at any moment (but yeah: it
> > would be bad luck to have that happening right after it called
> > unlink).
> >
> > Thanks.
> > Igor.
> >
> > On Wed, May 25, 2011 at 3:20 AM, Mazen Harake <>
> > wrote:
> > > Why would someone "kill the parent"? Do you have processes which are
> > > randomly choosing other processes to terminate? ;)
> > >
> > > If your answer is "No" then I would suggest that you just kill the worker
> > > processes that is taking to long, kill it in cold blood, imo.
> > >
> > > There is no reason to think about too many "if"-scenarios when the
> > scenarios
> > > are too far fetched. Try the simple version first :)
> > >
> > > otherwise you can either trap_exits or use monitors instead.
> > >
> > > /M
> > >
> > > On 25 May 2011 08:00, Igor Ribeiro Sucupira <> wrote:
> > >>
> > >> Suppose there is a heavy operation Op that in some cases takes so long
> > >> to finish that the caller loses interest in the result and gives up.
> > >>
> > >> I want to perform that operation in a way that allows me to:
> > >> 1) Interrupt its execution if it does not finish in N milliseconds.
> > >> 2) Interrupt its execution if the calling process exits (here I'm
> > >> already supposing Op has to be run in another Erlang process, due to
> > >> goal 1).
> > >>
> > >> To implement that, it seems unidirectional linking would be needed. Is
> > >> there another safe and convenient way to do it?
> > >>
> > >> The first idea I had was something like this:
> > >>
> > >> Parent = self(),
> > >> Child = spawn_link(fun() -> Parent ! (catch Op) end),
> > >> receive Result -> Result
> > >> after N -> unlink(Child), exit(Child, timeout), timeout
> > >> end.
> > >>
> > >> But, if Parent is killed by another process right after calling
> > >> unlink, Child would be left executing.
> > >> Another problem is that I don't want Parent to die if Child exits for
> > >> non-timeout reasons (although it seems very unlikely in the code
> > >> above, with the catch).
> > >>
> > >> I was now thinking of substituting unlink(Child) with
> > >> process_flag(trap_exit, true) and then kill Child, receive its exit
> > >> message, set trap_exit to false again (I'm assuming it was false), and
> > >> finally check if there were other exit messages (suiciding if it was
> > >> the case).
> > >>
> > >> But then the code would become too ugly, so I got lazy and decided to
> > >> post to this list.  :-)
> > >>
> > >> What do you think?
> > >>
> > >> Thanks.
> > >> Igor.
> > >> _______________________________________________
> > >> erlang-questions mailing list
> > >> 
> > >> http://erlang.org/mailman/listinfo/erlang-questions
> > >
> > >
> >

> _______________________________________________
> erlang-questions mailing list
> 
> http://erlang.org/mailman/listinfo/erlang-questions


-- 

/ Raimo Niskanen, Erlang/OTP, Ericsson AB



More information about the erlang-questions mailing list