From 7737917886db51d74d5a9336e3893d05baa15454 Mon Sep 17 00:00:00 2001 From: xqing2003 Date: Fri, 1 Jun 2018 23:30:30 +0800 Subject: [PATCH 1/3] solve memory leak --- src/linux_tcp/tcpconnection.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/linux_tcp/tcpconnection.cpp b/src/linux_tcp/tcpconnection.cpp index b8f0cd1..184dabf 100644 --- a/src/linux_tcp/tcpconnection.cpp +++ b/src/linux_tcp/tcpconnection.cpp @@ -70,13 +70,20 @@ void TcpConnection::process(int fd, int flags) auto *result = _state->process(monitor, fd, flags); // are we still valid - if (!monitor.valid()) return; + if (!monitor.valid()) + { + delete result; + return; + } // skip if the same state is continued to be used, or when the process() // method returns nullptr (which only happens when the object is destructed, // and "this" is no longer valid) - if (!result || result == _state.get()) return; - + if (!result || result == _state.get()) + { + delete result; + return; + } // replace it with the new implementation _state.reset(result); } From e40006058ed06bfb643a76718734d4d486f00411 Mon Sep 17 00:00:00 2001 From: xqing2003 Date: Wed, 6 Jun 2018 22:11:55 +0800 Subject: [PATCH 2/3] fix memory leak fix memory leak when channel error --- src/linux_tcp/tcpconnection.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/linux_tcp/tcpconnection.cpp b/src/linux_tcp/tcpconnection.cpp index 184dabf..8513de7 100644 --- a/src/linux_tcp/tcpconnection.cpp +++ b/src/linux_tcp/tcpconnection.cpp @@ -70,7 +70,7 @@ void TcpConnection::process(int fd, int flags) auto *result = _state->process(monitor, fd, flags); // are we still valid - if (!monitor.valid()) + if (!monitor.valid() && result != _state.get()) { delete result; return; @@ -79,11 +79,7 @@ void TcpConnection::process(int fd, int flags) // skip if the same state is continued to be used, or when the process() // method returns nullptr (which only happens when the object is destructed, // and "this" is no longer valid) - if (!result || result == _state.get()) - { - delete result; - return; - } + if (!result || result == _state.get()) return; // replace it with the new implementation _state.reset(result); } From 2430da76c3b29b2c785ec07a02079022561e62b0 Mon Sep 17 00:00:00 2001 From: Emiel Bruijntjes Date: Sun, 10 Jun 2018 20:46:11 +0200 Subject: [PATCH 3/3] refactored code --- src/linux_tcp/tcpconnection.cpp | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/linux_tcp/tcpconnection.cpp b/src/linux_tcp/tcpconnection.cpp index 8513de7..80e2430 100644 --- a/src/linux_tcp/tcpconnection.cpp +++ b/src/linux_tcp/tcpconnection.cpp @@ -66,22 +66,29 @@ void TcpConnection::process(int fd, int flags) // monitor the object for destruction, because you never know what the user Monitor monitor(this); + // store the old state + auto *oldstate = _state.get(); + // pass on the the state, that returns a new impl - auto *result = _state->process(monitor, fd, flags); + auto *newstate = _state->process(monitor, fd, flags); - // are we still valid - if (!monitor.valid() && result != _state.get()) + // if the state did not change, we do not have to update a member, + // when the newstate is nullptr, the object is (being) destructed + // and we do not have to do anything else either + if (oldstate == newstate || newstate == nullptr) return; + + // in a bizarre set of circumstances, the user may have implemented the + // handler in such a way that the connection object was destructed + if (!monitor.valid()) { - delete result; - return; + // ok, user code is weird, connection object no longer exist, get rid of the state too + delete newstate; + } + else + { + // replace it with the new implementation + _state.reset(newstate); } - - // skip if the same state is continued to be used, or when the process() - // method returns nullptr (which only happens when the object is destructed, - // and "this" is no longer valid) - if (!result || result == _state.get()) return; - // replace it with the new implementation - _state.reset(result); } /**