Quellcode durchsuchen

ft: 代码修改

master
SisMaker vor 3 Jahren
Ursprung
Commit
a6e98dec17
4 geänderte Dateien mit 189 neuen und 190 gelöschten Zeilen
  1. +0
    -1
      include/eTpf.hrl
  2. +2
    -2
      src/callgrind/tpCallGrind.erl
  3. +182
    -182
      src/flame/tpFlame.erl
  4. +5
    -5
      src/tracer/tpTracerSocket.erl

+ 0
- 1
include/eTpf.hrl Datei anzeigen

@ -19,7 +19,6 @@
-export_type([input/0, userInput/0, traceOpts/0, tracerOpts/0]). -export_type([input/0, userInput/0, traceOpts/0, tracerOpts/0]).
-type pattern() :: module() | {app, atom()} | {callback, module(), atom()}. -type pattern() :: module() | {app, atom()} | {callback, module(), atom()}.
-type scope() :: {scope, [pid() | port() | all | processes | ports |existing | existing_processes | existing_ports |new | new_processes | new_ports]}. -type scope() :: {scope, [pid() | port() | all | processes | ports |existing | existing_processes | existing_ports |new | new_processes | new_ports]}.
-type input() :: [pattern() | scope()]. -type input() :: [pattern() | scope()].

+ 2
- 2
src/callgrind/tpCallGrind.erl Datei anzeigen

@ -9,8 +9,8 @@
%% @todo Add an option with a list of modules to exclude. %% @todo Add an option with a list of modules to exclude.
-type opts() :: #{ -type opts() :: #{
scope => global | per_process, %% Whether we filter the output per process.
running => boolean() %% Whether we compute and save wait times.
scope => global | per_process, %% Whether we filter the output per process.
running => boolean() %% Whether we compute and save wait times.
}. }.
-record(call, { -record(call, {

+ 182
- 182
src/flame/tpFlame.erl Datei anzeigen

@ -1,173 +1,173 @@
-module(tpFlame). -module(tpFlame).
-export([ -export([
pfs/2 %%
, pfm/2 %%
pfs/2 %%
, pfm/2 %%
]). ]).
-record(state, { -record(state, {
outputPath = "",
pid,
lastTs,
count = 0,
acc = []
outputPath = "",
pid,
lastTs,
count = 0,
acc = []
}). }).
-spec pfs(file:filename_all(), file:filename_all()) -> ok. -spec pfs(file:filename_all(), file:filename_all()) -> ok.
pfs(InputFile, OutputPath) -> pfs(InputFile, OutputPath) ->
{ok, FinalState} = tpFReader:fold(fun handleEvent/2, #state{outputPath = OutputPath}, InputFile),
flush(FinalState).
{ok, FinalState} = tpFReader:fold(fun handleEvent/2, #state{outputPath = OutputPath}, InputFile),
flush(FinalState).
-spec pfm(file:filename(), file:filename()) -> ok. -spec pfm(file:filename(), file:filename()) -> ok.
pfm(InputFiles, OutputPath) -> pfm(InputFiles, OutputPath) ->
PfFiles = filelib:wildcard(InputFiles),
doPfm(PfFiles, #state{outputPath = OutputPath}).
PfFiles = filelib:wildcard(InputFiles),
doPfm(PfFiles, #state{outputPath = OutputPath}).
doPfm([], State) -> doPfm([], State) ->
flush(State);
flush(State);
doPfm([InputFile | PfFiles], State) -> doPfm([InputFile | PfFiles], State) ->
{ok, NewState} = tpFReader:fold(fun handleEvent/2, State, InputFile),
doPfm(PfFiles, NewState).
{ok, NewState} = tpFReader:fold(fun handleEvent/2, State, InputFile),
doPfm(PfFiles, NewState).
handleEvent({Type, Pid, Ts, Arg}, State) -> handleEvent({Type, Pid, Ts, Arg}, State) ->
doExp({trace_ts, Pid, Type, Arg, Ts}, State);
doExp({trace_ts, Pid, Type, Arg, Ts}, State);
handleEvent({Type, Pid, Ts, Arg, ExtraOrMspec}, State) -> handleEvent({Type, Pid, Ts, Arg, ExtraOrMspec}, State) ->
doExp({trace_ts, Pid, Type, Arg, ExtraOrMspec, Ts}, State);
doExp({trace_ts, Pid, Type, Arg, ExtraOrMspec, Ts}, State);
handleEvent({Type, Pid, Ts, Arg, Extra, Mspec}, State) -> handleEvent({Type, Pid, Ts, Arg, Extra, Mspec}, State) ->
doExp({trace_ts, Pid, Type, Arg, Extra, Mspec, Ts}, State).
doExp({trace_ts, Pid, Type, Arg, Extra, Mspec, Ts}, State).
doExp(T, #state{outputPath = OutputPath} = State) -> doExp(T, #state{outputPath = OutputPath} = State) ->
trace_ts = element(1, T),
Pid = element(2, T),
PidState =
case erlang:get(Pid) of
undefined ->
io:format("~p ", [Pid]),
#state{outputPath = OutputPath};
SomeState ->
SomeState
end,
NewPidState = doExpInner(T, PidState),
erlang:put(Pid, NewPidState),
State.
trace_ts = element(1, T),
Pid = element(2, T),
PidState =
case erlang:get(Pid) of
undefined ->
io:format("~p ", [Pid]),
#state{outputPath = OutputPath};
SomeState ->
SomeState
end,
NewPidState = doExpInner(T, PidState),
erlang:put(Pid, NewPidState),
State.
%% in & out, without call context, don't help us %% in & out, without call context, don't help us
doExpInner({trace_ts, _Pid, InOut, _MFA, _TS}, #state{lastTs = undefined} = PS) when InOut == in; InOut == out -> doExpInner({trace_ts, _Pid, InOut, _MFA, _TS}, #state{lastTs = undefined} = PS) when InOut == in; InOut == out ->
PS;
PS;
%% return_from and return_to, without call context, don't help us %% return_from and return_to, without call context, don't help us
doExpInner({trace_ts, _Pid, Return, _MFA, _TS}, #state{lastTs = undefined} = PS) when Return == return_from; Return == return_to -> doExpInner({trace_ts, _Pid, Return, _MFA, _TS}, #state{lastTs = undefined} = PS) when Return == return_from; Return == return_to ->
PS;
PS;
doExpInner({trace_ts, Pid, call, MFA, BIN, TS}, #state{lastTs = LastTS, acc = Acc, count = Count} = PS) -> doExpInner({trace_ts, Pid, call, MFA, BIN, TS}, #state{lastTs = LastTS, acc = Acc, count = Count} = PS) ->
try
%% Calculate time elapsed, TS-LastTs.
%% 0. If Acc is empty, then skip step #1.
%% 1. Credit elapsed time to the stack on the top of Acc.
%% 2. Push a 0 usec item with this stack onto Acc.
Stak =
lists:filter(
fun(<<"unknown function">>) -> false;
(_) -> true
end, stak_binify(BIN)),
Stack0 = stak_trim(Stak),
MFA_bin = mfa_binify(MFA),
Stack1 = [MFA_bin | lists:reverse(Stack0)],
Acc2 =
case Acc of
[] ->
[{Stack1, 0}];
[{LastStack, LastTime} | Tail] ->
USec = TS - LastTS,
try
%% Calculate time elapsed, TS-LastTs.
%% 0. If Acc is empty, then skip step #1.
%% 1. Credit elapsed time to the stack on the top of Acc.
%% 2. Push a 0 usec item with this stack onto Acc.
Stak =
lists:filter(
fun(<<"unknown function">>) -> false;
(_) -> true
end, stak_binify(BIN)),
Stack0 = stak_trim(Stak),
MFA_bin = mfa_binify(MFA),
Stack1 = [MFA_bin | lists:reverse(Stack0)],
Acc2 =
case Acc of
[] ->
[{Stack1, 0}];
[{LastStack, LastTime} | Tail] ->
USec = TS - LastTS,
% io:format("Stack1: ~p ~p\n", [Stack1, USec]), % io:format("Stack1: ~p ~p\n", [Stack1, USec]),
[{Stack1, 0},
{LastStack, LastTime + USec} | Tail]
end,
%% TODO: more state tracking here.
PS#state{pid = Pid, lastTs = TS, count = Count + 1, acc = Acc2}
catch Class:Reason:StackTrace ->
io:format(user, "~p: ~p:~p @ ~p\n", [?LINE, Class, Reason, StackTrace]),
PS
end;
[{Stack1, 0},
{LastStack, LastTime + USec} | Tail]
end,
%% TODO: more state tracking here.
PS#state{pid = Pid, lastTs = TS, count = Count + 1, acc = Acc2}
catch Class:Reason:StackTrace ->
io:format(user, "~p: ~p:~p @ ~p\n", [?LINE, Class, Reason, StackTrace]),
PS
end;
doExpInner({trace_ts, _Pid, return_to, MFA, TS}, #state{lastTs = LastTS, acc = Acc} = S) -> doExpInner({trace_ts, _Pid, return_to, MFA, TS}, #state{lastTs = LastTS, acc = Acc} = S) ->
try
%% Calculate time elapsed, TS-LastTs.
%% 1. Credit elapsed time to the stack on the top of Acc.
%% 2. Push a 0 usec item with the "best" stack onto Acc.
%% "best" = MFA exists in the middle of the stack onto Acc,
%% or else MFA exists at the top of a stack elsewhere in Acc.
[{LastStack, LastTime} | Tail] = Acc,
MFA_bin = mfa_binify(MFA),
BestStack = lists:dropwhile(fun(SomeMFA) when SomeMFA /= MFA_bin -> true;
(_) -> false
end, find_matching_stack(MFA_bin, Acc)),
USec = TS - LastTS,
Acc2 = [{BestStack, 0},
{LastStack, LastTime + USec} | Tail],
try
%% Calculate time elapsed, TS-LastTs.
%% 1. Credit elapsed time to the stack on the top of Acc.
%% 2. Push a 0 usec item with the "best" stack onto Acc.
%% "best" = MFA exists in the middle of the stack onto Acc,
%% or else MFA exists at the top of a stack elsewhere in Acc.
[{LastStack, LastTime} | Tail] = Acc,
MFA_bin = mfa_binify(MFA),
BestStack = lists:dropwhile(fun(SomeMFA) when SomeMFA /= MFA_bin -> true;
(_) -> false
end, find_matching_stack(MFA_bin, Acc)),
USec = TS - LastTS,
Acc2 = [{BestStack, 0},
{LastStack, LastTime + USec} | Tail],
% io:format(user, "return-to: ~p\n", [lists:sublist(Acc2, 4)]), % io:format(user, "return-to: ~p\n", [lists:sublist(Acc2, 4)]),
S#state{lastTs = TS, acc = Acc2}
catch XX:YY:ZZ ->
io:format(user, "~p: ~p:~p @ ~p\n", [?LINE, XX, YY, ZZ]),
S
end;
S#state{lastTs = TS, acc = Acc2}
catch XX:YY:ZZ ->
io:format(user, "~p: ~p:~p @ ~p\n", [?LINE, XX, YY, ZZ]),
S
end;
doExpInner({trace_ts, _Pid, gc_start, _Info, TS}, #state{lastTs = LastTS, acc = Acc} = S) -> doExpInner({trace_ts, _Pid, gc_start, _Info, TS}, #state{lastTs = LastTS, acc = Acc} = S) ->
try
%% Push a 0 usec item onto Acc.
[{LastStack, LastTime} | Tail] = Acc,
NewStack = [<<"GARBAGE-COLLECTION">> | LastStack],
USec = TS - LastTS,
Acc2 = [{NewStack, 0},
{LastStack, LastTime + USec} | Tail],
try
%% Push a 0 usec item onto Acc.
[{LastStack, LastTime} | Tail] = Acc,
NewStack = [<<"GARBAGE-COLLECTION">> | LastStack],
USec = TS - LastTS,
Acc2 = [{NewStack, 0},
{LastStack, LastTime + USec} | Tail],
% io:format(user, "GC 1: ~p\n", [lists:sublist(Acc2, 4)]), % io:format(user, "GC 1: ~p\n", [lists:sublist(Acc2, 4)]),
S#state{lastTs = TS, acc = Acc2}
catch _XX:_YY:_ZZ ->
%% io:format(user, "~p: ~p:~p @ ~p\n", [?LINE, _XX, _YY, _ZZ]),
S
end;
S#state{lastTs = TS, acc = Acc2}
catch _XX:_YY:_ZZ ->
%% io:format(user, "~p: ~p:~p @ ~p\n", [?LINE, _XX, _YY, _ZZ]),
S
end;
doExpInner({trace_ts, _Pid, gc_end, _Info, TS}, #state{lastTs = LastTS, acc = Acc} = S) -> doExpInner({trace_ts, _Pid, gc_end, _Info, TS}, #state{lastTs = LastTS, acc = Acc} = S) ->
try
%% Push the GC time onto Acc, then push 0 usec item from last exec
%% stack onto Acc.
[{GCStack, GCTime}, {LastExecStack, _} | Tail] = Acc,
USec = TS - LastTS,
Acc2 = [{LastExecStack, 0}, {GCStack, GCTime + USec} | Tail],
try
%% Push the GC time onto Acc, then push 0 usec item from last exec
%% stack onto Acc.
[{GCStack, GCTime}, {LastExecStack, _} | Tail] = Acc,
USec = TS - LastTS,
Acc2 = [{LastExecStack, 0}, {GCStack, GCTime + USec} | Tail],
% io:format(user, "GC 2: ~p\n", [lists:sublist(Acc2, 4)]), % io:format(user, "GC 2: ~p\n", [lists:sublist(Acc2, 4)]),
S#state{lastTs = TS, acc = Acc2}
catch _XX:_YY:_ZZ ->
%% io:format(user, "~p: ~p:~p @ ~p\n", [?LINE, _XX, _YY, _ZZ]),
S
end;
S#state{lastTs = TS, acc = Acc2}
catch _XX:_YY:_ZZ ->
%% io:format(user, "~p: ~p:~p @ ~p\n", [?LINE, _XX, _YY, _ZZ]),
S
end;
doExpInner({trace_ts, _Pid, out, MFA, TS}, #state{lastTs = LastTS, acc = Acc} = S) -> doExpInner({trace_ts, _Pid, out, MFA, TS}, #state{lastTs = LastTS, acc = Acc} = S) ->
try
%% Push a 0 usec item onto Acc.
%% The MFA reported here probably doesn't appear in the stacktrace
%% given to us by the last 'call', so add it here.
[{LastStack, LastTime} | Tail] = Acc,
MFA_bin = mfa_binify(MFA),
NewStack = [<<"SLEEP">>, MFA_bin | LastStack],
USec = TS - LastTS,
Acc2 = [{NewStack, 0},
{LastStack, LastTime + USec} | Tail],
S#state{lastTs = TS, acc = Acc2}
catch XX:YY:ZZ ->
io:format(user, "~p: ~p:~p @ ~p\n", [?LINE, XX, YY, ZZ]),
S
end;
try
%% Push a 0 usec item onto Acc.
%% The MFA reported here probably doesn't appear in the stacktrace
%% given to us by the last 'call', so add it here.
[{LastStack, LastTime} | Tail] = Acc,
MFA_bin = mfa_binify(MFA),
NewStack = [<<"SLEEP">>, MFA_bin | LastStack],
USec = TS - LastTS,
Acc2 = [{NewStack, 0},
{LastStack, LastTime + USec} | Tail],
S#state{lastTs = TS, acc = Acc2}
catch XX:YY:ZZ ->
io:format(user, "~p: ~p:~p @ ~p\n", [?LINE, XX, YY, ZZ]),
S
end;
doExpInner({trace_ts, _Pid, in, MFA, TS}, #state{lastTs = LastTS, acc = Acc} = S) -> doExpInner({trace_ts, _Pid, in, MFA, TS}, #state{lastTs = LastTS, acc = Acc} = S) ->
try
%% Push the Sleep time onto Acc, then push 0 usec item from last
%% exec stack onto Acc.
%% The MFA reported here probably doesn't appear in the stacktrace
%% given to us by the last 'call', so add it here.
MFA_bin = mfa_binify(MFA),
[{SleepStack, SleepTime}, {LastExecStack, _} | Tail] = Acc,
USec = TS - LastTS,
Acc2 = [{[MFA_bin | LastExecStack], 0}, {SleepStack, SleepTime + USec} | Tail],
S#state{lastTs = TS, acc = Acc2}
catch XX:YY:ZZ ->
io:format(user, "~p: ~p:~p @ ~p\n", [?LINE, XX, YY, ZZ]),
S
end;
try
%% Push the Sleep time onto Acc, then push 0 usec item from last
%% exec stack onto Acc.
%% The MFA reported here probably doesn't appear in the stacktrace
%% given to us by the last 'call', so add it here.
MFA_bin = mfa_binify(MFA),
[{SleepStack, SleepTime}, {LastExecStack, _} | Tail] = Acc,
USec = TS - LastTS,
Acc2 = [{[MFA_bin | LastExecStack], 0}, {SleepStack, SleepTime + USec} | Tail],
S#state{lastTs = TS, acc = Acc2}
catch XX:YY:ZZ ->
io:format(user, "~p: ~p:~p @ ~p\n", [?LINE, XX, YY, ZZ]),
S
end;
%exp1_inner(end_of_trace = _Else, #state{pid=Pid, output_path=OutputPath, acc=Acc} = S) -> %exp1_inner(end_of_trace = _Else, #state{pid=Pid, output_path=OutputPath, acc=Acc} = S) ->
% {ok, FH} = file:open(OutputPath, [write, raw, binary, delayed_write]), % {ok, FH} = file:open(OutputPath, [write, raw, binary, delayed_write]),
@ -182,22 +182,22 @@ doExpInner({trace_ts, _Pid, in, MFA, TS}, #state{lastTs = LastTS, acc = Acc} = S
% S; % S;
doExpInner(_Else, S) -> doExpInner(_Else, S) ->
% io:format("?? ~P\n", [_Else, 10]), % io:format("?? ~P\n", [_Else, 10]),
S.
S.
find_matching_stack(MFA_bin, [{H, _Time} | _] = Acc) -> find_matching_stack(MFA_bin, [{H, _Time} | _] = Acc) ->
case lists:member(MFA_bin, H) of
true ->
H;
false ->
find_matching_stack2(MFA_bin, Acc)
end.
case lists:member(MFA_bin, H) of
true ->
H;
false ->
find_matching_stack2(MFA_bin, Acc)
end.
find_matching_stack2(MFA_bin, [{[MFA_bin | _StackTail] = Stack, _Time} | _]) -> find_matching_stack2(MFA_bin, [{[MFA_bin | _StackTail] = Stack, _Time} | _]) ->
Stack;
Stack;
find_matching_stack2(MFA_bin, [_H | T]) -> find_matching_stack2(MFA_bin, [_H | T]) ->
find_matching_stack2(MFA_bin, T);
find_matching_stack2(MFA_bin, T);
find_matching_stack2(_MFA_bin, []) -> find_matching_stack2(_MFA_bin, []) ->
[<<"FIND-MATCHING-FAILED">>].
[<<"FIND-MATCHING-FAILED">>].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -206,63 +206,63 @@ intersperse(_, [X]) -> [X];
intersperse(Sep, [X | Xs]) -> [X, Sep | intersperse(Sep, Xs)]. intersperse(Sep, [X | Xs]) -> [X, Sep | intersperse(Sep, Xs)].
stak_trim([<<"proc_lib:init_p_do_apply/3">>, <<"gen_fsm:decode_msg/9">>, <<"gen_fsm:handle_msg/7">>, <<"gen_fsm:loop/7">> | T]) -> stak_trim([<<"proc_lib:init_p_do_apply/3">>, <<"gen_fsm:decode_msg/9">>, <<"gen_fsm:handle_msg/7">>, <<"gen_fsm:loop/7">> | T]) ->
stak_trim([<<"GEN-FSM">> | T]);
stak_trim([<<"GEN-FSM">> | T]);
stak_trim([<<"GEN-FSM">>, <<"gen_fsm:decode_msg/9">>, <<"gen_fsm:handle_msg/7">>, <<"gen_fsm:loop/7">> | T]) -> stak_trim([<<"GEN-FSM">>, <<"gen_fsm:decode_msg/9">>, <<"gen_fsm:handle_msg/7">>, <<"gen_fsm:loop/7">> | T]) ->
stak_trim([<<"GEN-FSM">> | T]);
stak_trim([<<"GEN-FSM">> | T]);
stak_trim(Else) -> stak_trim(Else) ->
Else.
Else.
stak_binify(Bin) when is_binary(Bin) -> stak_binify(Bin) when is_binary(Bin) ->
[list_to_binary(X) || X <- stak(Bin)];
[list_to_binary(X) || X <- stak(Bin)];
stak_binify(X) -> stak_binify(X) ->
list_to_binary(io_lib:format("~w", [X])).
list_to_binary(io_lib:format("~w", [X])).
mfa_binify({M, F, A}) -> mfa_binify({M, F, A}) ->
list_to_binary(io_lib:format("~w:~w/~w", [M, F, A]));
list_to_binary(io_lib:format("~w:~w/~w", [M, F, A]));
mfa_binify(X) -> mfa_binify(X) ->
list_to_binary(io_lib:format("~w", [X])).
list_to_binary(io_lib:format("~w", [X])).
%% Borrowed from redbug.erl %% Borrowed from redbug.erl
stak(Bin) -> stak(Bin) ->
lists:foldl(fun munge/2, [], string:tokens(binary_to_list(Bin), "\n")).
lists:foldl(fun munge/2, [], string:tokens(binary_to_list(Bin), "\n")).
munge(I, Out) -> munge(I, Out) ->
case I of %% lists:reverse(I) of
"..." ++ _ -> ["truncated!!!" | Out];
_ ->
case string:str(I, "Return addr") of
0 ->
case string:str(I, "cp = ") of
0 -> Out;
_ -> [mfaf(I) | Out]
end;
_ ->
case string:str(I, "erminate process normal") of
0 -> [mfaf(I) | Out];
_ -> Out
end
end
end.
case I of %% lists:reverse(I) of
"..." ++ _ -> ["truncated!!!" | Out];
_ ->
case string:str(I, "Return addr") of
0 ->
case string:str(I, "cp = ") of
0 -> Out;
_ -> [mfaf(I) | Out]
end;
_ ->
case string:str(I, "erminate process normal") of
0 -> [mfaf(I) | Out];
_ -> Out
end
end
end.
mfaf(I) -> mfaf(I) ->
[_, C | _] = string:tokens(I, "()+"),
string:strip(C).
[_, C | _] = string:tokens(I, "()+"),
string:strip(C).
flush(#state{outputPath = OutputPath}) -> flush(#state{outputPath = OutputPath}) ->
PidStates = get(),
{ok, FH} = file:open(OutputPath, [write, raw, binary, delayed_write]),
io:format("\n\nWriting to ~s for ~w processes... ", [OutputPath, length(PidStates)]),
_ = [
[begin
Pid_str0 = lists:flatten(io_lib:format("~w", [Pid])),
Size = length(Pid_str0),
Pid_str = [$(, lists:sublist(Pid_str0, 2, Size - 2), $)],
Time_str = integer_to_list(Time),
file:write(FH, [Pid_str, $;, intersperse($;, lists:reverse(Stack)), 32, Time_str, 10])
end || {Stack, Time} <- Acc]
|| {Pid, #state{acc = Acc} = _S} <- PidStates],
_ = file:close(FH),
io:format("finished!\n"),
ok.
PidStates = get(),
{ok, FH} = file:open(OutputPath, [write, raw, binary, delayed_write]),
io:format("\n\nWriting to ~s for ~w processes... ", [OutputPath, length(PidStates)]),
_ = [
[begin
Pid_str0 = lists:flatten(io_lib:format("~w", [Pid])),
Size = length(Pid_str0),
Pid_str = [$(, lists:sublist(Pid_str0, 2, Size - 2), $)],
Time_str = integer_to_list(Time),
file:write(FH, [Pid_str, $;, intersperse($;, lists:reverse(Stack)), 32, Time_str, 10])
end || {Stack, Time} <- Acc]
|| {Pid, #state{acc = Acc} = _S} <- PidStates],
_ = file:close(FH),
io:format("finished!\n"),
ok.

+ 5
- 5
src/tracer/tpTracerSocket.erl Datei anzeigen

@ -55,7 +55,7 @@ trace_loop(State = #state{parent = Parent, timerRef = TRef}, CSocket) ->
exit(Reason); exit(Reason);
{system, From, Request} -> {system, From, Request} ->
sys:handle_system_msg(Request, From, Parent, ?MODULE, [], {trace_loop, State, CSocket}); sys:handle_system_msg(Request, From, Parent, ?MODULE, [], {trace_loop, State, CSocket});
%% Reset the timeout when we receive data.
%% Reset the timeout when we receive data.
{tcp, CSocket, _} -> {tcp, CSocket, _} ->
trace_loop(reset_timeout(State), CSocket); trace_loop(reset_timeout(State), CSocket);
{tcp_closed, CSocket} -> {tcp_closed, CSocket} ->
@ -64,20 +64,20 @@ trace_loop(State = #state{parent = Parent, timerRef = TRef}, CSocket) ->
close(State, CSocket); close(State, CSocket);
{timeout, TRef, ?MODULE} -> {timeout, TRef, ?MODULE} ->
close(State, CSocket); close(State, CSocket);
%% Discard the non-blocking send reply when successful.
%% Discard the non-blocking send reply when successful.
{inet_reply, CSocket, ok} -> {inet_reply, CSocket, ok} ->
trace_loop(State, CSocket); trace_loop(State, CSocket);
%% And close the socket when an error occured.
%% And close the socket when an error occured.
{inet_reply, CSocket, _} -> {inet_reply, CSocket, _} ->
close(State, CSocket); close(State, CSocket);
%% Discard TCP messages from closed sockets.
%% Discard TCP messages from closed sockets.
{tcp, _, _} -> {tcp, _, _} ->
trace_loop(State, CSocket); trace_loop(State, CSocket);
{tcp_closed, _} -> {tcp_closed, _} ->
trace_loop(State, CSocket); trace_loop(State, CSocket);
{tcp_error, _, _} -> {tcp_error, _, _} ->
trace_loop(State, CSocket); trace_loop(State, CSocket);
%% Discard any previous timeout.
%% Discard any previous timeout.
{timeout, _, ?MODULE} -> {timeout, _, ?MODULE} ->
trace_loop(State, CSocket); trace_loop(State, CSocket);
Msg -> Msg ->

Laden…
Abbrechen
Speichern