aboutsummaryrefslogtreecommitdiffstats
path: root/system/doc/tutorial/complex5.erl
diff options
context:
space:
mode:
Diffstat (limited to 'system/doc/tutorial/complex5.erl')
-rw-r--r--system/doc/tutorial/complex5.erl56
1 files changed, 56 insertions, 0 deletions
diff --git a/system/doc/tutorial/complex5.erl b/system/doc/tutorial/complex5.erl
new file mode 100644
index 0000000000..473056dd11
--- /dev/null
+++ b/system/doc/tutorial/complex5.erl
@@ -0,0 +1,56 @@
+-module(complex5).
+-export([start/1, stop/0, init/1]).
+-export([foo/1, bar/1]).
+
+start(SharedLib) ->
+ case erl_ddll:load_driver(".", SharedLib) of
+ ok -> ok;
+ {error, already_loaded} -> ok;
+ _ -> exit({error, could_not_load_driver})
+ end,
+ spawn(?MODULE, init, [SharedLib]).
+
+init(SharedLib) ->
+ register(complex, self()),
+ Port = open_port({spawn, SharedLib}, []),
+ loop(Port).
+
+stop() ->
+ complex ! stop.
+
+foo(X) ->
+ call_port({foo, X}).
+bar(Y) ->
+ call_port({bar, Y}).
+
+call_port(Msg) ->
+ complex ! {call, self(), Msg},
+ receive
+ {complex, Result} ->
+ Result
+ end.
+
+loop(Port) ->
+ receive
+ {call, Caller, Msg} ->
+ Port ! {self(), {command, encode(Msg)}},
+ receive
+ {Port, {data, Data}} ->
+ Caller ! {complex, decode(Data)}
+ end,
+ loop(Port);
+ stop ->
+ Port ! {self(), close},
+ receive
+ {Port, closed} ->
+ exit(normal)
+ end;
+ {'EXIT', Port, Reason} ->
+ io:format("~p ~n", [Reason]),
+ exit(port_terminated)
+ end.
+
+encode({foo, X}) -> [1, X];
+encode({bar, Y}) -> [2, Y].
+
+decode([Int]) -> Int.