44 * Implementation file for the TCP connection
55 *
66 * @author Emiel Bruijntjes <[email protected] > 7- * @copyright 2015 - 2018 Copernica BV
7+ * @copyright 2015 - 2020 Copernica BV
88 */
99
1010/* *
@@ -36,7 +36,16 @@ TcpConnection::TcpConnection(TcpHandler *handler, const Address &address) :
3636/* *
3737 * Destructor
3838 */
39- TcpConnection::~TcpConnection () noexcept = default ;
39+ TcpConnection::~TcpConnection () noexcept
40+ {
41+ // When the object is destructed, the _state-pointer will also destruct, resulting
42+ // in some final calls back to us to inform that the connection has indeed been closed.
43+ // This normally results in calls back to user-space (via the _handler pointer) but
44+ // since user-space is apparently no longer interested in the TcpConnection (why would
45+ // it otherwise prematurely destruct the object?) we reset the handler-pointer to
46+ // prevent that such calls back to userspace take place
47+ _handler = nullptr ;
48+ }
4049
4150/* *
4251 * The filedescriptor that is used for this connection
@@ -121,7 +130,7 @@ bool TcpConnection::close(bool immediate)
121130 if (!monitor.valid ()) return true ;
122131
123132 // tell the handler that the connection was closed
124- if (failed) _handler->onError (this , " connection prematurely closed by client" );
133+ if (failed && _handler ) _handler->onError (this , " connection prematurely closed by client" );
125134
126135 // stop if object was destructed
127136 if (!monitor.valid ()) return true ;
@@ -143,7 +152,7 @@ bool TcpConnection::close(bool immediate)
143152void TcpConnection::onProperties (Connection *connection, const Table &server, Table &client)
144153{
145154 // tell the handler
146- return _handler->onProperties (this , server, client);
155+ if (_handler) _handler->onProperties (this , server, client);
147156}
148157
149158/* *
@@ -158,7 +167,7 @@ uint16_t TcpConnection::onNegotiate(Connection *connection, uint16_t interval)
158167 _state->maxframe (connection->maxFrame ());
159168
160169 // tell the handler
161- return _handler->onNegotiate (this , interval);
170+ return _handler ? _handler ->onNegotiate (this , interval) : interval ;
162171}
163172
164173/* *
@@ -184,7 +193,7 @@ void TcpConnection::onError(Connection *connection, const char *message)
184193 Monitor monitor (this );
185194
186195 // tell this to the user
187- _handler->onError (this , message);
196+ if (_handler) _handler->onError (this , message);
188197
189198 // object could be destructed by user-space
190199 if (!monitor.valid ()) return ;
@@ -214,6 +223,9 @@ void TcpConnection::onClosed(Connection *connection)
214223 */
215224void TcpConnection::onError (TcpState *state, const char *message, bool connected)
216225{
226+ // if user-space is no longer interested in this object, the rest of the code is pointless here
227+ if (_handler == nullptr ) return ;
228+
217229 // monitor to check if all operations are active
218230 Monitor monitor (this );
219231
@@ -240,6 +252,9 @@ void TcpConnection::onError(TcpState *state, const char *message, bool connected
240252 */
241253void TcpConnection::onLost (TcpState *state)
242254{
255+ // if user-space is no longer interested in this object, the rest of the code is pointless here
256+ if (_handler == nullptr ) return ;
257+
243258 // monitor to check if "this" is destructed
244259 Monitor monitor (this );
245260
0 commit comments