/jaerlang-code/code/socket_dist/lib_chan_mm.erl

https://github.com/killme2008/erlib · Erlang · 70 lines · 46 code · 6 blank · 18 comment · 0 complexity · baba264163c5a71766d769ab9790199d MD5 · raw file

  1. %% ---
  2. %% Excerpted from "Programming Erlang",
  3. %% published by The Pragmatic Bookshelf.
  4. %% Copyrights apply to this code. It may not be used to create training material,
  5. %% courses, books, articles, and the like. Contact us if you are in doubt.
  6. %% We make no guarantees that this code is fit for any purpose.
  7. %% Visit http://www.pragmaticprogrammer.com/titles/jaerlang for more book information.
  8. %%---
  9. %% Protocol
  10. %% To the controlling process
  11. %% {chan, MM, Term}
  12. %% {chan_closed, MM}
  13. %% From any process
  14. %% {send, Term}
  15. %% close
  16. -module(lib_chan_mm).
  17. %% TCP Middle man
  18. %% Models the interface to gen_tcp
  19. -export([loop/2, send/2, close/1, controller/2, set_trace/2, trace_with_tag/2]).
  20. send(Pid, Term) -> Pid ! {send, Term}.
  21. close(Pid) -> Pid ! close.
  22. controller(Pid, Pid1) -> Pid ! {setController, Pid1}.
  23. set_trace(Pid, X) -> Pid ! {trace, X}.
  24. trace_with_tag(Pid, Tag) ->
  25. set_trace(Pid, {true,
  26. fun(Msg) ->
  27. io:format("MM:~p ~p~n",[Tag, Msg])
  28. end}).
  29. loop(Socket, Pid) ->
  30. %% trace_with_tag(self(), trace),
  31. process_flag(trap_exit, true),
  32. loop1(Socket, Pid, false).
  33. loop1(Socket, Pid, Trace) ->
  34. receive
  35. {tcp, Socket, Bin} ->
  36. Term = binary_to_term(Bin),
  37. trace_it(Trace,{socketReceived, Term}),
  38. Pid ! {chan, self(), Term},
  39. loop1(Socket, Pid, Trace);
  40. {tcp_closed, Socket} ->
  41. trace_it(Trace, socketClosed),
  42. Pid ! {chan_closed, self()};
  43. {'EXIT', Pid, Why} ->
  44. trace_it(Trace,{controllingProcessExit, Why}),
  45. gen_tcp:close(Socket);
  46. {setController, Pid1} ->
  47. trace_it(Trace, {changedController, Pid}),
  48. loop1(Socket, Pid1, Trace);
  49. {trace, Trace1} ->
  50. trace_it(Trace, {setTrace, Trace1}),
  51. loop1(Socket, Pid, Trace1);
  52. close ->
  53. trace_it(Trace, closedByClient),
  54. gen_tcp:close(Socket);
  55. {send, Term} ->
  56. trace_it(Trace, {sendingMessage, Term}),
  57. gen_tcp:send(Socket, term_to_binary(Term)),
  58. loop1(Socket, Pid, Trace);
  59. UUg ->
  60. io:format("lib_chan_mm: protocol error:~p~n",[UUg]),
  61. loop1(Socket, Pid, Trace)
  62. end.
  63. trace_it(false, _) -> void;
  64. trace_it({true, F}, M) -> F(M).