diff options
author | Micael Karlberg <[email protected]> | 2019-03-29 12:45:27 +0100 |
---|---|---|
committer | Micael Karlberg <[email protected]> | 2019-04-17 16:56:33 +0200 |
commit | 4db60424c21ee767ad78be14edd94dd7ab3a1884 (patch) | |
tree | 73c9de66ec4b2eb2c8b1959bfb0498f92d3afcf0 /erts/emulator | |
parent | 8f4db4b202b59d5b1b1e9ec5c2e2967bf91211b3 (diff) | |
download | otp-4db60424c21ee767ad78be14edd94dd7ab3a1884.tar.gz otp-4db60424c21ee767ad78be14edd94dd7ab3a1884.tar.bz2 otp-4db60424c21ee767ad78be14edd94dd7ab3a1884.zip |
[socket] Fixed acceptor environment leak
Did the free and assign new acceptor in the wrong order,
thereby causing an (acceptor) environment leak.
OTP-15496
Diffstat (limited to 'erts/emulator')
-rw-r--r-- | erts/emulator/nifs/common/socket_nif.c | 58 |
1 files changed, 47 insertions, 11 deletions
diff --git a/erts/emulator/nifs/common/socket_nif.c b/erts/emulator/nifs/common/socket_nif.c index c2dddf8aa4..0f1b11f428 100644 --- a/erts/emulator/nifs/common/socket_nif.c +++ b/erts/emulator/nifs/common/socket_nif.c @@ -32,7 +32,7 @@ * * esock_dbg_printf("DEMONP", "[%d] %s: %T\r\n", * descP->sock, slogan, - * MON2T(env, &monP->mon)); + * esock_make_monitor_term(env, &mon)); * */ @@ -2479,6 +2479,9 @@ static int esock_demonitor(const char* slogan, ESockDescriptor* descP, ESockMonitor* monP); static void esock_monitor_init(ESockMonitor* mon); +static ERL_NIF_TERM esock_make_monitor_term(ErlNifEnv* env, + const ESockMonitor* monP); + #endif // if defined(__WIN32__) @@ -2913,6 +2916,7 @@ static ESockData data; static ESOCK_INLINE void esock_free_env(const char* slogan, ErlNifEnv* env) { SGDBG( ("SOCKET", "env free - %s: 0x%lX\r\n", slogan, env) ); + // esock_dbg_printf("SOCK ENV", "free - %s: 0x%lX\r\n", slogan, env); if (env != NULL) enif_free_env(env); } @@ -2923,6 +2927,7 @@ static ESOCK_INLINE ErlNifEnv* esock_alloc_env(const char* slogan) ErlNifEnv* env = enif_alloc_env(); SGDBG( ("SOCKET", "env alloc - %s: 0x%lX\r\n", slogan, env) ); + // esock_dbg_printf("SOCK ENV", "alloc - %s: 0x%lX\r\n", slogan, env); return env; } @@ -5097,13 +5102,29 @@ ERL_NIF_TERM nif_accept(ErlNifEnv* env, } ref = argv[1]; + MLOCK(descP->accMtx); + SSDBG( descP, ("SOCKET", "nif_accept -> args when sock = %d:" - "\r\n Socket: %T" - "\r\n ReqRef: %T" - "\r\n", descP->sock, argv[0], ref) ); - - MLOCK(descP->accMtx); + "\r\n Socket: %T" + "\r\n ReqRef: %T" + "\r\nwhen" + "\r\n State: %s" + "\r\n Current Acceptor Addr: 0x%lX" + "\r\n Current Acceptor pid: %T" + "\r\n Current Acceptor mon: %T" + "\r\n Current Acceptor env: 0x%lX" + "\r\n Current Acceptor ref: %T" + "\r\n", + descP->sock, + sockRef, ref, + ((descP->state == SOCKET_STATE_LISTENING) ? "listening" : + ((descP->state == SOCKET_STATE_ACCEPTING) ? "accepting" : "other")), + descP->currentAcceptorP, + descP->currentAcceptor.pid, + esock_make_monitor_term(env, &descP->currentAcceptor.mon), + descP->currentAcceptor.env, + descP->currentAcceptor.ref) ); res = naccept(env, descP, sockRef, ref); @@ -5383,6 +5404,14 @@ ERL_NIF_TERM naccept_accepting_current_accept(ErlNifEnv* env, if (naccept_accepted(env, descP, accSock, descP->currentAcceptor.pid, remote, &res)) { + /* Clean out the old cobweb's before trying to invite a new spider */ + + descP->currentAcceptor.ref = esock_atom_undefined; + enif_set_pid_undefined(&descP->currentAcceptor.pid); + esock_free_env("naccept_accepting_current_accept - " + "current-accept-env", + descP->currentAcceptor.env); + if (!activate_next_acceptor(env, descP, sockRef)) { SSDBG( descP, @@ -5393,11 +5422,6 @@ ERL_NIF_TERM naccept_accepting_current_accept(ErlNifEnv* env, descP->state = SOCKET_STATE_LISTENING; descP->currentAcceptorP = NULL; - descP->currentAcceptor.ref = esock_atom_undefined; - enif_set_pid_undefined(&descP->currentAcceptor.pid); - esock_free_env("naccept_accepting_current_accept - " - "current-accept-env", - descP->currentAcceptor.env); descP->currentAcceptor.env = NULL; MON_INIT(&descP->currentAcceptor.mon); } @@ -18005,6 +18029,18 @@ void esock_monitor_init(ESockMonitor* monP) monP->isActive = FALSE; } + +static +ERL_NIF_TERM esock_make_monitor_term(ErlNifEnv* env, const ESockMonitor* monP) +{ + if (monP->isActive) + return enif_make_monitor_term(env, &monP->mon); + else + return esock_atom_undefined; +} + + + #endif // if !defined(__WIN32__) |