suggested patches, c.erl, proc_lib.erl
Ulf Wiger
etxuwig@REDACTED
Fri Feb 28 17:38:07 CET 2003
(This is not sent directly to erlang-patches, partly because
I'd like some feedback on it. Please read on.)
Personally, I like processes started with proc_lib when it
comes to debugging (when SASL is running, you get crash
reports), but I also like the convention of spawning
processes using a fun, e.g.
start_registered(server, fun() -> start_server(Port, Me) end).
(partly because you don't have to export the init function,
and partly because it makes it easier to follow the logic --
and you can use 'tags' in Emacs to jump directly to the init
function. ;)
As I'm working with Joe's excellent UBF server, I decided to
try to marry the two. Joe used spawning with funs, but
(obviously) not proc_lib. The attached diff makes it
possible to call proc_lib:spawn(fun() -> ... end), and
proc_lib:spawn_link(fun() -> ... end), etc. (I did _not_
modify proc_lib:start(), mainly because it got a bit
confusing with arities.)
I also modified c.erl to make the output from i() a little
more descriptive. Here, I'd welcome a way to present
processes started with a fun in a better way. Example:
<0.62.0> proc_socket_server:cold_start/4 233 196 0
picoSocketServer_8800 proc_socket_server:socket_loop/5 11
<0.63.0> supervisor:'cath.server.superviso 233 165 0
'cath.server.supervis gen_server:loop/6 12
<0.64.0> proc_socket_server:start_child/3 233 22 0
prim_inet:accept0/2 15
<0.65.0> #Fun:ubf_utils.0[#Fun<plugin_hand 233 62 0
plugin_handler:manager_loop/3 10
<0.66.0> #Fun:ubf_utils.0[#Fun<plugin_hand 377 71 0
plugin_handler:manager_loop/3 10
<0.67.0> #Fun:ubf_utils.0[#Fun<plugin_hand 233 70 0
plugin_handler:manager_loop/3 10
<0.68.0> #Fun:ubf_utils.0[#Fun<plugin_hand 233 74 0
plugin_handler:manager_loop/3 10
<0.69.0> 'cath.server.control':init/1 233 30 0
control gen_server:loop/6 12
<0.98.0> shell:evaluator/3 987 150353 0
c:pinfo/1 38
<0.120.0> #Fun:erl_eval.19[{eval,{shell,loc 233 44 0
timer:sleep/1 21
Total 43056 1017785 0
If it's not entirely obvious, the information concerning
funs consists of the module name and first digit in the
"name" of the fun (e.g. #Fun<erl_eval.19.280769>), followed
by the results of the call erlang:fun_info(F, env) -- that
is, the bindings.
Comments welcome.
/Uffe
--
Ulf Wiger, Senior Specialist,
/ / / Architecture & Design of Carrier-Class Software
/ / / Strategic Product & System Management
/ / / Ericsson AB, Connectivity and Control Nodes
-------------- next part --------------
251a252,255
> mfa_string(F) when function(F) ->
> Str = fun_string(F),
> {env,Env} = erlang:fun_info(F, env),
> io_lib:format("#Fun:~s~p", [Str,Env]);
256a261,268
> fun_string(F) ->
> Str = erlang:fun_to_list(F),
> {match,A,B} = regexp:match(Str,"<.*>"),
> Info = string:substr(Str,A+1,B-2),
> {match,C,1} = regexp:match(lists:reverse(Info),"\\."),
> string:substr(Info,1,length(Info)-C).
>
>
292c304
< {proc_lib, init_p, 5} ->
---
> {proc_lib, init_p, _} ->
-------------- next part --------------
27,28c27,29
< -export([spawn/3,spawn_link/3,spawn/4,spawn_link/4,
< spawn_opt/4,
---
> -export([spawn/1,spawn_link/1, spawn/2, spawn_link/2,
> spawn/3,spawn_link/3,spawn/4,spawn_link/4,
> spawn_opt/2, spawn_opt/4,
31c32
< init_p/5,format/1,initial_call/1,translate_initial_call/1]).
---
> init_p/3,init_p/5,format/1,initial_call/1,translate_initial_call/1]).
32a34,38
> spawn(F) when function(F) ->
> Parent = get_my_name(),
> Ancestors = get_ancestors(),
> erlang:spawn(proc_lib,init_p,[Parent,Ancestors,F]).
>
37a44,48
> spawn_link(F) when function(F) ->
> Parent = get_my_name(),
> Ancestors = get_ancestors(),
> erlang:spawn_link(proc_lib,init_p,[Parent,Ancestors,F]).
>
42a54,58
> spawn(Node, F) when function(F) ->
> Parent = get_my_name(),
> Ancestors = get_ancestors(),
> erlang:spawn(Node,proc_lib,init_p,[Parent,Ancestors,F]).
>
47a64,68
> spawn_link(Node,F) when function(F) ->
> Parent = get_my_name(),
> Ancestors = get_ancestors(),
> erlang:spawn_link(Node,proc_lib,init_p,[Parent,Ancestors,F]).
>
53c74,78
<
---
> spawn_opt(F, Opts) when function(F) ->
> Parent = get_my_name(),
> Ancestors = get_ancestors(),
> erlang:spawn_opt(proc_lib,init_p,[Parent,Ancestors,F],Opts).
>
67a93,98
> init_p(Parent,Ancestors,F) when function(F) ->
> put('$ancestors',[Parent|Ancestors]),
> put('$initial_call',F),
> Result = (catch F()),
> exit_p(Result,F).
>
73c104
< exit_p(Result,M,F,A).
---
> exit_p(Result,{M,F,A}).
75,76c106,107
< exit_p({'EXIT',Reason},M,F,A) ->
< crash_report(Reason,M,F,A),
---
> exit_p({'EXIT',Reason},StartF) ->
> crash_report(Reason,StartF),
78c109
< exit_p(Reason,_,_,_) ->
---
> exit_p(Reason,_) ->
151a183,184
> {value,{_,F}} when function(F) ->
> F;
162a196
>
166a201,202
> F when function(F) ->
> F;
195,199c231,235
<
< crash_report(normal,_,_,_) -> ok;
< crash_report(shutdown,_,_,_) -> ok;
< crash_report(Reason,M,F,A) ->
< OwnReport = my_info(Reason,M,F,A),
---
>
> crash_report(normal,_) -> ok;
> crash_report(shutdown,_) -> ok;
> crash_report(Reason,StartF) ->
> OwnReport = my_info(Reason,StartF),
205c241
< my_info(Reason,M,F,A) ->
---
> my_info(Reason,StartF) ->
209c245
< {initial_call, {M, F, A}},
---
> {initial_call, StartF},
More information about the erlang-questions
mailing list