From 3cf37fe21c7b9247c6c5f2c5a93f5480b2ad4f7c Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Fri, 6 Jul 2012 08:13:13 -0400 Subject: [PATCH] Attempt at fixing a possible process leak Yoshihiro Tanaka found that when lhttpc:request closes a worker due to a timeout, it's possible that it happens after the port is unlinked in prim_inet:close, but before it is properly closed. This results in orphaned sockets/ports being left hanging in the ether. This fix attempts to wrap lhttpc_sock:close commands around a safe build that should resolve it. A potential fix would have been to have the manager monitor the sockets itself, but this wouldn't have worked if the socket is new and the manager has never seen it before, hence the current fix. --- src/lhttpc.app.src | 2 +- src/lhttpc_sock.erl | 26 ++++++++++++++++++++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/lhttpc.app.src b/src/lhttpc.app.src index 0603b2bd..75f17ef8 100644 --- a/src/lhttpc.app.src +++ b/src/lhttpc.app.src @@ -29,7 +29,7 @@ %%% @end {application, lhttpc, [{description, "Lightweight HTTP Client"}, - {vsn, "1.2.7"}, + {vsn, "1.2.8"}, {modules, [lhttpc,lhttpc_sup,lhttpc_client,lhttpc_sock,lhttp_lb]}, {registered, [lhttpc_sup]}, {applications, [kernel, stdlib, ssl, crypto]}, diff --git a/src/lhttpc_sock.erl b/src/lhttpc_sock.erl index 63c3124b..429517c3 100644 --- a/src/lhttpc_sock.erl +++ b/src/lhttpc_sock.erl @@ -154,6 +154,28 @@ setopts(Socket, Options, false) -> %% @end -spec close(socket(), boolean()) -> ok | {error, atom()}. close(Socket, true) -> - ssl:close(Socket); + %% Safer exiting. Yoshihiro Tanaka from OpenX figured out + %% that we had potential race conditions while closing the + %% socket and timing out. This process flagging aims to + %% wrap some safety around this in case of a timeout + Flag = process_flag(trap_exit, true), + Res = ssl:close(Socket), + receive + {'EXIT',_Pid,timeout} -> exit(timeout) + after 0 -> + process_flag(trap_exit, Flag), + Res + end; close(Socket, false) -> - gen_tcp:close(Socket). + %% Safer exiting. Yoshihiro Tanaka from OpenX figured out + %% that we had potential race conditions while closing the + %% socket and timing out. This process flagging aims to + %% wrap some safety around this in case of a timeout + Flag = process_flag(trap_exit, true), + Res = gen_tcp:close(Socket), + receive + {'EXIT',_Pid,timeout} -> exit(timeout) + after 0 -> + process_flag(trap_exit, Flag), + Res + end.