mayaprogs: Resolve Maya conversion server memory leak by storing managers on the heap

This commit is contained in:
Disyer 2022-03-01 23:07:20 +02:00
parent aaa51df759
commit 7da3395a8a
4 changed files with 38 additions and 56 deletions

View File

@ -19,11 +19,8 @@
* Initializes the Maya conversion client. * Initializes the Maya conversion client.
*/ */
MayaConversionClient:: 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) { connect(NetAddress server) {
if (_conn) { if (_conn) {
// Remove this connection from the readers list // Remove this connection from the readers list
_qReader->remove_connection(_conn); _qReader.remove_connection(_conn);
_conn = nullptr; _conn = nullptr;
} }
// Attempt to open a connection // 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()) { if (!_conn || _conn.is_null()) {
// This connection could not be opened // This connection could not be opened
@ -57,7 +54,7 @@ connect(NetAddress server) {
} }
// Add this connection to the readers list // Add this connection to the readers list
_qReader->add_connection(_conn); _qReader.add_connection(_conn);
return true; return true;
} }
@ -94,17 +91,17 @@ queue(Filename working_directory, int argc, char *argv[], MayaConversionServer::
datagram.add_uint8(conversion_type); datagram.add_uint8(conversion_type);
// Send the conversion request // 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"; nout << "Failed to send workload to server process.\n";
return false; return false;
} }
// Wait for a response // Wait for a response
while (_conn->get_socket()->Active() && !_qReader->data_available()) { while (_conn->get_socket()->Active() && !_qReader.data_available()) {
_qReader->poll(); _qReader.poll();
} }
if (!_qReader->data_available()) { if (!_qReader.data_available()) {
// No response has been given by the server. // No response has been given by the server.
nout << "No response has been given by the conversion server.\n"; nout << "No response has been given by the conversion server.\n";
return false; return false;
@ -113,7 +110,7 @@ queue(Filename working_directory, int argc, char *argv[], MayaConversionServer::
NetDatagram response; NetDatagram response;
// Let's read the response now! // 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"; nout << "The conversion response could not be read.\n";
return false; return false;
} }
@ -147,13 +144,13 @@ close() {
} }
while (true) { while (true) {
_qReader->data_available(); _qReader.data_available();
if (_qManager->reset_connection_available()) { if (_qManager.reset_connection_available()) {
PT(Connection) connection; PT(Connection) connection;
if (_qManager->get_reset_connection(connection)) { if (_qManager.get_reset_connection(connection)) {
_qManager->close_connection(_conn); _qManager.close_connection(_conn);
_conn = nullptr; _conn = nullptr;
return; return;
} }

View File

@ -44,9 +44,9 @@ public:
int main(int argc, char *argv[], MayaConversionServer::ConversionType conversion_type); int main(int argc, char *argv[], MayaConversionServer::ConversionType conversion_type);
private: private:
QueuedConnectionManager *_qManager; QueuedConnectionManager _qManager;
QueuedConnectionReader *_qReader; QueuedConnectionReader _qReader;
ConnectionWriter *_cWriter; ConnectionWriter _cWriter;
PT(Connection) _conn; PT(Connection) _conn;
}; };

View File

@ -26,22 +26,8 @@
* Initializes the Maya conversion server. * Initializes the Maya conversion server.
*/ */
MayaConversionServer:: MayaConversionServer::
MayaConversionServer() { MayaConversionServer() : _qListener(&_qManager, 0), _qReader(&_qManager, 0),
_qManager = new QueuedConnectionManager(); _cWriter(&_qManager, 0) {
_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;
} }
/** /**
@ -51,39 +37,39 @@ MayaConversionServer::
void MayaConversionServer:: void MayaConversionServer::
poll() { poll() {
// Listen for new connections // Listen for new connections
_qListener->poll(); _qListener.poll();
// If we have a new connection from a client create a new connection pointer // If we have a new connection from a client create a new connection pointer
// and add it to the reader list // and add it to the reader list
if (_qListener->new_connection_available()) { if (_qListener.new_connection_available()) {
PT(Connection) rendezvous; PT(Connection) rendezvous;
PT(Connection) connection; PT(Connection) connection;
NetAddress address; NetAddress address;
if (_qListener->get_new_connection(rendezvous, address, connection)) { if (_qListener.get_new_connection(rendezvous, address, connection)) {
_qReader->add_connection(connection); _qReader.add_connection(connection);
_clients.insert(connection); _clients.insert(connection);
} }
} }
// Check for reset clients // Check for reset clients
if (_qManager->reset_connection_available()) { if (_qManager.reset_connection_available()) {
PT(Connection) connection; PT(Connection) connection;
if (_qManager->get_reset_connection(connection)) { if (_qManager.get_reset_connection(connection)) {
_clients.erase(connection); _clients.erase(connection);
_qManager->close_connection(connection); _qManager.close_connection(connection);
} }
} }
// Poll the readers (created above) and if they have data process it // 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 // Grab the incoming data and unpack it
NetDatagram datagram; NetDatagram datagram;
if (_qReader->get_data(datagram)) { if (_qReader.get_data(datagram)) {
DatagramIterator data(datagram); DatagramIterator data(datagram);
// First data should be the "argc" (argument count) from the client // First data should be the "argc" (argument count) from the client
@ -182,7 +168,7 @@ poll() {
response.add_bool(converted); response.add_bool(converted);
// Send the response // 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 // Looks like we couldn't send the response
nout << "Could not send response to the client.\n"; nout << "Could not send response to the client.\n";
} }
@ -199,13 +185,13 @@ poll() {
} }
// Clean up the malloc'd pointer pointer // Clean up the malloc'd pointer pointer
free(cargv); free(cargv);
} // qReader->get_data } // qReader.get_data
Clients::iterator ci; Clients::iterator ci;
for (ci = _clients.begin(); ci != _clients.end(); ++ci) { for (ci = _clients.begin(); ci != _clients.end(); ++ci) {
_qManager->close_connection(*ci); _qManager.close_connection(*ci);
} }
} // qReader->data_available } // qReader.data_available
} // poll } // poll
/** /**
@ -214,7 +200,7 @@ poll() {
void MayaConversionServer:: void MayaConversionServer::
listen() { listen() {
// Open a rendezvous port for receiving new connections from the client // 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()) { if (rend.is_null()) {
nout << "Port opening failed!\n"; nout << "Port opening failed!\n";
@ -224,7 +210,7 @@ listen() {
nout << "Server opened on port 4242, waiting for requests...\n"; nout << "Server opened on port 4242, waiting for requests...\n";
// Add this connection to the listeners list // 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. // Main loop. Keep polling for connections, but don't eat up all the CPU.
while (true) { while (true) {

View File

@ -40,7 +40,6 @@ public:
}; };
MayaConversionServer(); MayaConversionServer();
~MayaConversionServer();
void listen(); void listen();
void poll(); void poll();
@ -49,10 +48,10 @@ protected:
typedef pset< PT(Connection) > Clients; typedef pset< PT(Connection) > Clients;
Clients _clients; Clients _clients;
QueuedConnectionManager *_qManager; QueuedConnectionManager _qManager;
QueuedConnectionListener *_qListener; QueuedConnectionListener _qListener;
QueuedConnectionReader *_qReader; QueuedConnectionReader _qReader;
ConnectionWriter *_cWriter; ConnectionWriter _cWriter;
}; };
#endif #endif