Skip to content

Commit

Permalink
MythZMServer: close the map files when a connection to the server closes
Browse files Browse the repository at this point in the history
Make sure any mmap files opened for a connection are closed when the connection
using them closes. Also make sure all ZMServers  are cleaned up properly before
exiting the server now the server can be asked to quit.

This fixes Coverity ID 703768 Resource leak
  • Loading branch information
Paul Harrison committed Jun 9, 2013
1 parent 9f900fc commit 8c84d00
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 24 deletions.
7 changes: 7 additions & 0 deletions mythplugins/mythzoneminder/mythzmserver/main.cpp
Expand Up @@ -350,6 +350,13 @@ int main(int argc, char **argv)
}
}

// cleanly remove all the ZMServer's
for (std::map<int, ZMServer*>::iterator it = serverList.begin();
it != serverList.end(); ++it)
{
delete it->second;
}

mysql_close(&g_dbConn);

return EXIT_OK;
Expand Down
67 changes: 43 additions & 24 deletions mythplugins/mythzoneminder/mythzmserver/zmserver.cpp
Expand Up @@ -260,6 +260,23 @@ ZMServer::ZMServer(int sock, bool debug)

ZMServer::~ZMServer()
{
for (std::map<int, MONITOR*>::iterator it = m_monitors.begin(); it != m_monitors.end(); ++it)
{
MONITOR *mon = it->second;
if (mon->mapFile != -1)
{
if (close(mon->mapFile) == -1)
cout << "Failed to close mapFile" << endl;
else
if (m_debug)
cout << "Closed mapFile for monitor: " << mon->name << endl;
}

delete mon;
}

m_monitors.clear();

if (m_debug)
cout << "ZMServer destroyed\n";
}
Expand Down Expand Up @@ -1350,8 +1367,8 @@ void ZMServer::getMonitorList(void)

void ZMServer::initMonitor(MONITOR *monitor)
{
void *shm_ptr = NULL;

monitor->shm_ptr = NULL;
monitor->mapFile = -1;
monitor->shared_data = NULL;
monitor->shared_images = NULL;

Expand Down Expand Up @@ -1382,22 +1399,27 @@ void ZMServer::initMonitor(MONITOR *monitor)
stringstream mmap_filename;
mmap_filename << m_mmapPath << "/zm.mmap." << monitor->mon_id;

int mapFile = open(mmap_filename.str().c_str(), O_RDONLY, 0x0);
if (mapFile >= 0)
monitor->mapFile = open(mmap_filename.str().c_str(), O_RDONLY, 0x0);
if (monitor->mapFile >= 0)
{
if (m_debug)
cout << "Opened mmap file: " << mmap_filename << endl;

shm_ptr = mmap(NULL, shared_data_size, PROT_READ,
MAP_SHARED, mapFile, 0x0);
if (shm_ptr == MAP_FAILED)
monitor->shm_ptr = mmap(NULL, shared_data_size, PROT_READ,
MAP_SHARED, monitor->mapFile, 0x0);
if (monitor->shm_ptr == MAP_FAILED)
{
cout << "Failed to map shared memory from file [" <<
mmap_filename << "] " <<
"for monitor: " <<
monitor->mon_id <<
endl;
cout << "Failed to map shared memory from file ["
<< mmap_filename << "] " << "for monitor: "
<< monitor->mon_id << endl;
monitor->status = "Error";

if (close(monitor->mapFile) == -1)
cout << "Failed to close mmap file" << endl;

monitor->mapFile = -1;
monitor->shm_ptr = NULL;

return;
}
}
Expand All @@ -1407,18 +1429,15 @@ void ZMServer::initMonitor(MONITOR *monitor)
// using the legacy shared memory support
if (m_debug)
{
cout << "Failed to open mmap file [" <<
mmap_filename << "] " <<
"for monitor: " <<
monitor->mon_id <<
" : " << strerror(errno) <<
endl;
cout << "Failed to open mmap file [" << mmap_filename << "] "
<< "for monitor: " << monitor->mon_id
<< " : " << strerror(errno) << endl;
cout << "Falling back to the legacy shared memory method" << endl;
}
}
#endif

if (shm_ptr == NULL)
if (monitor->shm_ptr == NULL)
{
// fail back to shmget() functionality if mapping memory above failed.
int shmid;
Expand All @@ -1442,26 +1461,26 @@ void ZMServer::initMonitor(MONITOR *monitor)
return;
}

shm_ptr = shmat(shmid, 0, SHM_RDONLY);
monitor->shm_ptr = shmat(shmid, 0, SHM_RDONLY);


if (shm_ptr == NULL)
if (monitor->shm_ptr == NULL)
{
cout << "Failed to shmat for monitor: " << monitor->mon_id << endl;
monitor->status = "Error";
return;
}
}

monitor->shared_data = (SharedData*)shm_ptr;
monitor->shared_data = (SharedData*)monitor->shm_ptr;

if (g_zmversion == "1.22.2")
monitor->shared_images = (unsigned char*) shm_ptr +
monitor->shared_images = (unsigned char*) monitor->shm_ptr +
sizeof(SharedData) +
sizeof(TriggerData_old) +
((monitor->image_buffer_count) * sizeof(struct timeval));
else
monitor->shared_images = (unsigned char*) shm_ptr +
monitor->shared_images = (unsigned char*) monitor->shm_ptr +
sizeof(SharedData) +
sizeof(TriggerData) +
((monitor->image_buffer_count) * sizeof(struct timeval));
Expand Down
2 changes: 2 additions & 0 deletions mythplugins/mythzoneminder/mythzmserver/zmserver.h
Expand Up @@ -129,6 +129,8 @@ typedef struct
int palette;
int controllable;
int trackMotion;
int mapFile;
void *shm_ptr;

string getIdStr()
{
Expand Down

0 comments on commit 8c84d00

Please sign in to comment.