Fixed a few memory leaks

This commit is contained in:
Zane U. Ji 2012-08-27 20:25:08 +08:00
parent 0e3bfd65e5
commit 8df6cd065b
9 changed files with 166 additions and 29 deletions

61
src/threadreaper.cpp Normal file
View File

@ -0,0 +1,61 @@
/*
* Copyright 2012 Zane U. Ji.
*
* This file is part of Xml Copy Editor.
*
* Xml Copy Editor is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* Xml Copy Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Xml Copy Editor; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "threadreaper.h"
extern wxCriticalSection xmlcopyeditorCriticalSection;
ThreadReaper::ThreadReaper ()
{
}
ThreadReaper::~ThreadReaper ()
{
//wxCriticalSectionLocker lock ( xmlcopyeditorCriticalSection );
std::vector<boost::shared_ptr<wxThread> >::iterator itr;
for ( itr = mList.begin(); itr != mList.end(); itr++)
{
(**itr).Kill();
}
}
ThreadReaper &ThreadReaper::get()
{
static ThreadReaper reaper;
return reaper;
}
void ThreadReaper::add ( wxThread *thread )
{
// Make sure everything is valid when wxPostMessage is called
// and protect mList
wxCriticalSectionLocker lock ( xmlcopyeditorCriticalSection );
mList.push_back ( boost::shared_ptr<wxThread> ( thread ) );
std::vector<boost::shared_ptr<wxThread> >::iterator itr;
for ( itr = mList.begin(); itr != mList.end(); )
{
if ( (**itr).IsAlive() )
itr++;
else
itr = mList.erase ( itr );
}
}

42
src/threadreaper.h Normal file
View File

@ -0,0 +1,42 @@
/*
* Copyright 2012 Zane U. Ji.
*
* This file is part of Xml Copy Editor.
*
* Xml Copy Editor is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* Xml Copy Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Xml Copy Editor; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef THREADREAPER_H_
#define THREADREAPER_H_
#include <wx/wx.h>
#include <vector>
#include <boost/shared_ptr.hpp>
class ThreadReaper
{
protected:
ThreadReaper();
virtual ~ThreadReaper();
public:
static ThreadReaper &get();
void add ( wxThread *thread );
protected:
std::vector<boost::shared_ptr<wxThread> > mList;
};
#endif /* THREADREAPER_H_ */

View File

@ -4,7 +4,9 @@
#include "wrapxerces.h"
#include <stdexcept>
#include <memory>
#include "threadreaper.h"
extern wxCriticalSection xmlcopyeditorCriticalSection;
DEFINE_EVENT_TYPE(wxEVT_COMMAND_VALIDATION_COMPLETED);
@ -15,6 +17,7 @@ ValidationThread::ValidationThread (
const char *catalogPath,
const char *catalogUtilityPath )
: wxThread ( wxTHREAD_JOINABLE )
, mStopping ( false )
{
if ( buffer == NULL )
{
@ -35,25 +38,22 @@ void *ValidationThread::Entry()
myCatalogPath,
myCatalogUtilityPath ) );
{
//wxCriticalSectionLocker locker ( xmlcopyeditorCriticalSection );
if ( TestDestroy() )
{
return NULL;
}
}
myIsSucceeded = validator->validateMemory (
myBuffer.c_str(),
myBuffer.size(),
mySystem.c_str(),
myBuffer.size() );
this );
if ( TestDestroy() )
{
return NULL;
}
extern wxCriticalSection xmlcopyeditorCriticalSection;
wxCriticalSectionLocker locker ( xmlcopyeditorCriticalSection );
if ( myIsSucceeded )
@ -67,8 +67,18 @@ void *ValidationThread::Entry()
myMessage = validator->getLastError();
}
if ( !TestDestroy() )
{
wxCommandEvent event ( wxEVT_COMMAND_VALIDATION_COMPLETED );
wxPostEvent ( myEventHandler, event );
}
return NULL;
}
void ValidationThread::PendingDelete ()
{
Cancel();
ThreadReaper::get().add ( this );
}

View File

@ -22,12 +22,21 @@ public:
bool isSucceeded () { return myIsSucceeded; }
const std::pair<int, int> &getPosition() { return myPosition; }
const wxString &getMessage() { return myMessage; }
private:
void PendingDelete();
// Since we can't call wxThread::m_internal->Cancel(), the original
// TestDestroy() is useless. Here is the work around.
virtual void Cancel() { mStopping = true; }
virtual bool TestDestroy() { return mStopping || wxThread::TestDestroy(); }
protected:
wxEvtHandler *myEventHandler;
std::string myBuffer, mySystem, myCatalogPath, myCatalogUtilityPath;
bool myIsSucceeded;
std::pair<int, int> myPosition;
wxString myMessage;
bool mStopping;
};
#endif

View File

@ -113,8 +113,9 @@ bool WrapXerces::validate ( const std::string& fileName )
// tbd: cache grammar
bool WrapXerces::validateMemory (
const char *buffer,
size_t len,
const char *system,
unsigned len )
wxThread *thread /*= NULL*/ )
{
std::auto_ptr<SAX2XMLReader> parser ( XMLReaderFactory::createXMLReader() );
@ -137,9 +138,19 @@ bool WrapXerces::validateMemory (
MemBufInputSource source ( xmlBuffer, len, system );
try
{
if ( thread == NULL )
{
parser->parse ( source );
}
else if ( !thread->TestDestroy() )
{
XMLPScanToken token;
if ( parser->parseFirst ( source, token ) )
while ( (!thread->TestDestroy()) && parser->parseNext ( token ) )
continue;
}
}
catch ( XMLException& e )
{
lastError = wxEmptyString;

View File

@ -41,7 +41,8 @@ class WrapXerces
std::string catalogUtilityPath = "" );
~WrapXerces();
bool validate ( const std::string& fileName );
bool validateMemory ( const char *buffer, const char *system, unsigned len );
bool validateMemory ( const char *buffer, size_t len,
const char *system, wxThread *thread = NULL );
const wxString &getLastError();
std::pair<int, int> getErrorPosition();
static wxString toString ( const XMLCh *str );

View File

@ -3123,7 +3123,7 @@ bool MyFrame::openFile ( wxString& fileName, bool largeFile )
statusProgress ( wxEmptyString );
char *iconvBuffer = 0;
wxCharBuffer iconvBuffer;
size_t iconvBufferLen = 0;
char *finalBuffer;
@ -3230,21 +3230,21 @@ bool MyFrame::openFile ( wxString& fileName, bool largeFile )
iconvLenMultiplier = 1;
}
size_t nconv;
char *buffer;
size_t iconvBufferLeft, docBufferLeft;
iconvBufferLen = iconvBufferLeft = (docBufferLen - nBOM) * iconvLenMultiplier + 1;
docBufferLeft = docBufferLen;
iconvBuffer = new char[iconvBufferLen];
finalBuffer = iconvBuffer; // iconvBuffer will be incremented by iconv
size_t nconv;
iconvBuffer.extend ( iconvBufferLen );
finalBuffer = buffer = iconvBuffer.data(); // buffer will be incremented by iconv
nconv = reinterpret_cast < universal_iconv & > ( iconv ) (
cd,
&docBuffer,
&docBufferLeft,
&iconvBuffer,
&buffer,
&iconvBufferLeft );
*iconvBuffer = '\0';
*buffer = '\0';
iconv_close ( cd );
@ -3255,7 +3255,6 @@ bool MyFrame::openFile ( wxString& fileName, bool largeFile )
fileName.c_str(),
wideEncoding.c_str() );
messagePane ( message, CONST_STOP );
delete[] finalBuffer;
delete binaryfile; //delete memorymap;
return false;
}

View File

@ -138,8 +138,7 @@ XmlCtrl::~XmlCtrl()
if ( validationThread != NULL )
{
validationThread->Kill();
delete validationThread;
validationThread->PendingDelete();
}
}

View File

@ -299,6 +299,7 @@ int XMLCALL XmlPromptGenerator::externalentityrefhandler (
PromptGeneratorData *d;
d = ( PromptGeneratorData * ) p; // arg is set to user data in c'tor
int ret;
std::string buffer;
// auxPath req'd?
@ -307,15 +308,17 @@ int XMLCALL XmlPromptGenerator::externalentityrefhandler (
ReadFile::run ( d->auxPath, buffer );
if ( buffer.empty() )
{
return false;
return XML_STATUS_ERROR;
}
std::string encoding = XmlEncodingHandler::get ( buffer );
XML_Parser dtdParser = XML_ExternalEntityParserCreate ( d->p, context, encoding.c_str() );
if ( !dtdParser )
return false;
return XML_STATUS_ERROR;
XML_SetBase ( dtdParser, d->auxPath.c_str() );
return XML_Parse ( dtdParser, buffer.c_str(), buffer.size(), true );
ret = XML_Parse ( dtdParser, buffer.c_str(), buffer.size(), true );
XML_ParserFree ( dtdParser );
return ret;
}
std::string stdPublicId;
@ -358,7 +361,7 @@ int XMLCALL XmlPromptGenerator::externalentityrefhandler (
std::string encoding = XmlEncodingHandler::get ( buffer );
XML_Parser dtdParser = XML_ExternalEntityParserCreate ( d->p, context, encoding.c_str() );
if ( !dtdParser )
return false;
return XML_STATUS_ERROR;
wxString wideName, wideDir;
wideName = wxString ( stdSystemId.c_str(), wxConvUTF8, stdSystemId.size() );
@ -366,7 +369,9 @@ int XMLCALL XmlPromptGenerator::externalentityrefhandler (
wideDir = fn.GetPath();
XML_SetBase ( dtdParser, wideName.mb_str ( wxConvUTF8 ) );
return XML_Parse ( dtdParser, buffer.c_str(), buffer.size(), true );
ret = XML_Parse ( dtdParser, buffer.c_str(), buffer.size(), true );
XML_ParserFree ( dtdParser );
return ret;
}
void XMLCALL XmlPromptGenerator::entitydeclhandler (