%
% Program 7.2, Concurrent Programming in Erlang by J. Armstrong et al.
%
-module(normal).
-export([start/1, p1/1, test/1]).

start(N) ->
    register(start, spawn_link(normal, p1, [N - 1])).

p1(0) ->
    top1();
p1(N) ->
    top(spawn_link(normal, p1, [N - 1]),N).

top(Next, N) ->
    receive
	X ->
	    Next ! X,
	    io:format("Process ~w received ~w~n", [N,X]),
	    top(Next,N)
    end.

top1() ->
    receive
	stop ->
	    io:format("Last process now exiting ~n", []),
	    exit(finished);
	X ->
	    io:format("Last process received ~w~n", [X]),
	    top1()
    end.

test(Mess) ->
    start ! Mess.

%%
%% Use, e.g., as follows:
%%
%% > c(normal).
%% {ok,normal}
%% > normal:start(3).
%% true
%% > normal:test(m).
%% Process 2 received m
%% Process 1 received m
%% Last process received m
%% m
%% > normal:test(stop).
%% Process 2 received stop
%% Process 1 received stop
%% Last process now exiting 
%% stop
%% ** exception exit: finished
%% > normal:test(m).
%% ** exception error: bad argument
%%      in function  normal:test/1 (normal.erl, line 31)

 
