Hi Ale
I went and had another look at my_supervisor.erl (it's on pp153-4 of
the book, and in the code zipfile). I was looking in the wrong place
for the pids, but start_link isn't the right place either.
The function start_children/1 goes through the list of {Mod, Func,
Args} starting each in turn (with apply/3) and returning a list of
{Pid, {Mod, Func, Args}}:
start_children([]) -> [];
start_children([{M, F, A} | ChildSpecList]) ->
case (catch apply(M,F,A)) of
{ok, Pid} ->
[{Pid, {M,F,A}}|start_children(ChildSpecList)];
_ ->
start_children(ChildSpecList)
end.
To get a report of the actual pids in the running childlist I added a
report entry to the receive loop:
loop(ChildList) ->
receive
{'EXIT', Pid, _Reason} ->
NewChildList = restart_child(Pid, ChildList),
loop(NewChildList);
{stop, From} ->
From ! {reply, terminate(ChildList)};
{report, From} ->
From ! {reply, {length(ChildList), getPids(ChildList)}},
loop(ChildList)
end.
report(Name) ->
Name ! {report, self()},
receive {reply, Reply} -> Reply end.
getPids([]) -> [];
getPids([{Pid, {Mod,_F,_A}}|T]) ->
[{Mod,Pid}|getPids(T)].
However, the pids don't seem to be added to the list:
1> c(my_supervisor).
{ok,my_supervisor}
2> c(mutex).
{ok,mutex}
3> my_supervisor:start_link(my_supervisor, [{mutex, start, []}]).
ok
4> mutex:wait().
linking to and locking for <0.33.0>
ok_waiting
5> my_supervisor:report(my_supervisor).
{0,[]}
In fact, apply(mutex, start, [])., does not return {ok, Pid}, but
true. So, although mutex is started, and we can communicate with it,
and although my_supervisor is trapping exits, mutex is not being added
to the supervision tree.
I have two conclusions:
1: children should be rewritten to return {ok, Pid} from their
initialisation functions. Fair enough;
2: The example code is broken: processes which start up ok but do not
return {ok, Pid} to apply/3 seem to be playing along but are not in
fact in the supervision tree. When restart_child/2 is called on one
of them the supervisor crashes. I am wrong surely?
Best wishes
Ivan