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.
*/
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;
}

View File

@ -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;
};

View File

@ -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) {

View File

@ -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