Archivi per la categoria erlang
Giochini in Erlang
Esempio rubato spudoratamente da OpenDLM:
-module(dig_test).
-export([run_test/0]).
-export([init/0]).
-spec(run_test() -> pid()).
run_test() ->
spawn(?MODULE, init, []).
-spec(init() -> none()).
init() ->
TWFG = digraph:new(),
%% Simulate the same TWFG present in OpenDLM specs
C1 = add_client(TWFG, c1),
R1 = add_resource(TWFG, r1),
C2 = add_client(TWFG, c2),
R2 = add_resource(TWFG, r2),
R3 = add_resource(TWFG, r3),
C3 = add_client(TWFG, c3),
digraph:add_edge(TWFG, C1, R1),
digraph:add_edge(TWFG, R1, C2),
digraph:add_edge(TWFG, C2, R2),
digraph:add_edge(TWFG, C2, R3),
digraph:add_edge(TWFG, R2, C3),
digraph:add_edge(TWFG, R3, C1),
detect_deadlock_for(TWFG, R1),
digraph:delete(TWFG),
exit(normal).
-spec(add_client(digraph(), atom()) -> digraph:vertex()).
add_client(WaitForGraph, ClientName) ->
add_vertex(WaitForGraph, {client, ClientName}).
-spec(add_resource(digraph(), atom()) -> digraph:vertex()).
add_resource(WaitForGraph, ResourceName) ->
add_vertex(WaitForGraph, {resource, ResourceName}).
-spec(add_vertex(digraph(), term()) -> digraph:vertex()).
add_vertex(WaitForGraph, Label) ->
Vertex = digraph:add_vertex(WaitForGraph),
digraph:add_vertex(WaitForGraph, Vertex, Label).
-spec(detect_deadlock_for(digraph(), digraph:vertex()) -> ok).
detect_deadlock_for(WaitForGraph, Vertex) ->
case digraph:get_cycle(WaitForGraph, Vertex) of
false ->
io:format("No deadlocks detected for ~p~n", [vertex_name(WaitForGraph, Vertex)]);
VList ->
io:format("Deadlock detected between ~p~n", [vertices_names(WaitForGraph, VList)])
end.
-spec(vertex_name(digraph(), digraph:vertex()) -> term()).
vertex_name(WaitForGraph, Vertex) ->
{_, Name} = digraph:vertex(WaitForGraph, Vertex),
Name.
-spec(vertices_names(digraph(), nil() | [digraph:vertex()]) -> nil() | [term()]).
vertices_names(WaitForGraph, VList) ->
vertices_names(WaitForGraph, VList, []).
-spec(vertices_names(digraph(), nil() | [digraph:vertex()], nil() | [term()]) -> nil() | [term()]).
vertices_names(_WaitForGraph, [], Acc) ->
lists:reverse(Acc);
vertices_names(WaitForGraph, [Vertex|Tail], Acc) ->
vertices_names(WaitForGraph, Tail, [vertex_name(WaitForGraph, Vertex)|Acc]).
(se vi state chiedendo perché TWFG non varia, la risposta è che digraph usa ETS per mantenere lo stato del grafo).




