From 7da3395a8a654932adece1f9338359bc24c6b8dd Mon Sep 17 00:00:00 2001 From: Disyer Date: Tue, 1 Mar 2022 23:07:20 +0200 Subject: [PATCH] mayaprogs: Resolve Maya conversion server memory leak by storing managers on the heap --- .../src/mayaprogs/mayaConversionClient.cxx | 29 +++++------ .../src/mayaprogs/mayaConversionClient.h | 6 +-- .../src/mayaprogs/mayaConversionServer.cxx | 50 +++++++------------ .../src/mayaprogs/mayaConversionServer.h | 9 ++-- 4 files changed, 38 insertions(+), 56 deletions(-) diff --git a/pandatool/src/mayaprogs/mayaConversionClient.cxx b/pandatool/src/mayaprogs/mayaConversionClient.cxx index 900b7ca0d4..553e473ee0 100644 --- a/pandatool/src/mayaprogs/mayaConversionClient.cxx +++ b/pandatool/src/mayaprogs/mayaConversionClient.cxx @@ -19,11 +19,8 @@ * Initializes the Maya conversion client. */ MayaConversionClient:: -MayaConversionClient() +MayaConversionClient() : _qReader(&_qManager, 0), _cWriter(&_qManager, 0) { - _qManager = new QueuedConnectionManager(); - _qReader = new QueuedConnectionReader(_qManager, 0); - _cWriter = new ConnectionWriter(_qManager, 0); } /** @@ -44,12 +41,12 @@ bool MayaConversionClient:: connect(NetAddress server) { if (_conn) { // Remove this connection from the readers list - _qReader->remove_connection(_conn); + _qReader.remove_connection(_conn); _conn = nullptr; } // Attempt to open a connection - _conn = _qManager->open_TCP_client_connection(server, 0); + _conn = _qManager.open_TCP_client_connection(server, 0); if (!_conn || _conn.is_null()) { // This connection could not be opened @@ -57,7 +54,7 @@ connect(NetAddress server) { } // Add this connection to the readers list - _qReader->add_connection(_conn); + _qReader.add_connection(_conn); return true; } @@ -94,17 +91,17 @@ queue(Filename working_directory, int argc, char *argv[], MayaConversionServer:: datagram.add_uint8(conversion_type); // Send the conversion request - if (!_cWriter->send(datagram, _conn) || !_conn->flush()) { + if (!_cWriter.send(datagram, _conn) || !_conn->flush()) { nout << "Failed to send workload to server process.\n"; return false; } // Wait for a response - while (_conn->get_socket()->Active() && !_qReader->data_available()) { - _qReader->poll(); + while (_conn->get_socket()->Active() && !_qReader.data_available()) { + _qReader.poll(); } - if (!_qReader->data_available()) { + if (!_qReader.data_available()) { // No response has been given by the server. nout << "No response has been given by the conversion server.\n"; return false; @@ -113,7 +110,7 @@ queue(Filename working_directory, int argc, char *argv[], MayaConversionServer:: NetDatagram response; // Let's read the response now! - if (!_qReader->get_data(response)) { + if (!_qReader.get_data(response)) { nout << "The conversion response could not be read.\n"; return false; } @@ -147,13 +144,13 @@ close() { } while (true) { - _qReader->data_available(); + _qReader.data_available(); - if (_qManager->reset_connection_available()) { + if (_qManager.reset_connection_available()) { PT(Connection) connection; - if (_qManager->get_reset_connection(connection)) { - _qManager->close_connection(_conn); + if (_qManager.get_reset_connection(connection)) { + _qManager.close_connection(_conn); _conn = nullptr; return; } diff --git a/pandatool/src/mayaprogs/mayaConversionClient.h b/pandatool/src/mayaprogs/mayaConversionClient.h index bd524a07eb..90afe037d1 100644 --- a/pandatool/src/mayaprogs/mayaConversionClient.h +++ b/pandatool/src/mayaprogs/mayaConversionClient.h @@ -44,9 +44,9 @@ public: int main(int argc, char *argv[], MayaConversionServer::ConversionType conversion_type); private: - QueuedConnectionManager *_qManager; - QueuedConnectionReader *_qReader; - ConnectionWriter *_cWriter; + QueuedConnectionManager _qManager; + QueuedConnectionReader _qReader; + ConnectionWriter _cWriter; PT(Connection) _conn; }; diff --git a/pandatool/src/mayaprogs/mayaConversionServer.cxx b/pandatool/src/mayaprogs/mayaConversionServer.cxx index 0d6b7e8056..757070ff73 100644 --- a/pandatool/src/mayaprogs/mayaConversionServer.cxx +++ b/pandatool/src/mayaprogs/mayaConversionServer.cxx @@ -26,22 +26,8 @@ * Initializes the Maya conversion server. */ MayaConversionServer:: -MayaConversionServer() { - _qManager = new QueuedConnectionManager(); - _qListener = new QueuedConnectionListener(_qManager, 0); - _qReader = new QueuedConnectionReader(_qManager, 0); - _cWriter = new ConnectionWriter(_qManager, 0); -} - -/** - * Cleans up the connection managers for the Maya conversion server. - */ -MayaConversionServer:: -~MayaConversionServer() { - delete _qManager; - delete _qReader; - delete _qListener; - delete _cWriter; +MayaConversionServer() : _qListener(&_qManager, 0), _qReader(&_qManager, 0), + _cWriter(&_qManager, 0) { } /** @@ -51,39 +37,39 @@ MayaConversionServer:: void MayaConversionServer:: poll() { // Listen for new connections - _qListener->poll(); + _qListener.poll(); // If we have a new connection from a client create a new connection pointer // and add it to the reader list - if (_qListener->new_connection_available()) { + if (_qListener.new_connection_available()) { PT(Connection) rendezvous; PT(Connection) connection; NetAddress address; - if (_qListener->get_new_connection(rendezvous, address, connection)) { - _qReader->add_connection(connection); + if (_qListener.get_new_connection(rendezvous, address, connection)) { + _qReader.add_connection(connection); _clients.insert(connection); } } // Check for reset clients - if (_qManager->reset_connection_available()) { + if (_qManager.reset_connection_available()) { PT(Connection) connection; - if (_qManager->get_reset_connection(connection)) { + if (_qManager.get_reset_connection(connection)) { _clients.erase(connection); - _qManager->close_connection(connection); + _qManager.close_connection(connection); } } // Poll the readers (created above) and if they have data process it - _qReader->poll(); + _qReader.poll(); - if (_qReader->data_available()) { + if (_qReader.data_available()) { // Grab the incoming data and unpack it NetDatagram datagram; - if (_qReader->get_data(datagram)) { + if (_qReader.get_data(datagram)) { DatagramIterator data(datagram); // First data should be the "argc" (argument count) from the client @@ -182,7 +168,7 @@ poll() { response.add_bool(converted); // Send the response - if (!_cWriter->send(response, datagram.get_connection())) { + if (!_cWriter.send(response, datagram.get_connection())) { // Looks like we couldn't send the response nout << "Could not send response to the client.\n"; } @@ -199,13 +185,13 @@ poll() { } // Clean up the malloc'd pointer pointer free(cargv); - } // qReader->get_data + } // qReader.get_data Clients::iterator ci; for (ci = _clients.begin(); ci != _clients.end(); ++ci) { - _qManager->close_connection(*ci); + _qManager.close_connection(*ci); } - } // qReader->data_available + } // qReader.data_available } // poll /** @@ -214,7 +200,7 @@ poll() { void MayaConversionServer:: listen() { // Open a rendezvous port for receiving new connections from the client - PT(Connection) rend = _qManager->open_TCP_server_rendezvous(4242, 100); + PT(Connection) rend = _qManager.open_TCP_server_rendezvous(4242, 100); if (rend.is_null()) { nout << "Port opening failed!\n"; @@ -224,7 +210,7 @@ listen() { nout << "Server opened on port 4242, waiting for requests...\n"; // Add this connection to the listeners list - _qListener->add_connection(rend); + _qListener.add_connection(rend); // Main loop. Keep polling for connections, but don't eat up all the CPU. while (true) { diff --git a/pandatool/src/mayaprogs/mayaConversionServer.h b/pandatool/src/mayaprogs/mayaConversionServer.h index 10212676a8..3b933ae16e 100644 --- a/pandatool/src/mayaprogs/mayaConversionServer.h +++ b/pandatool/src/mayaprogs/mayaConversionServer.h @@ -40,7 +40,6 @@ public: }; MayaConversionServer(); - ~MayaConversionServer(); void listen(); void poll(); @@ -49,10 +48,10 @@ protected: typedef pset< PT(Connection) > Clients; Clients _clients; - QueuedConnectionManager *_qManager; - QueuedConnectionListener *_qListener; - QueuedConnectionReader *_qReader; - ConnectionWriter *_cWriter; + QueuedConnectionManager _qManager; + QueuedConnectionListener _qListener; + QueuedConnectionReader _qReader; + ConnectionWriter _cWriter; }; #endif