EDN Admin
Well-known member
MSXML4 is causing a leak. Its a MultiThreaded Application which causes a leak after X no. of requests.
Below is the Code where the request is parsed.
void DataSetRequest::loadXML(const char* dataSetRequestXML)<br/>
{<br/>
_xmlSizeBytes = strlen(dataSetRequestXML) * sizeof(char); // store for stats logging<br/>
<br/>
if (_xmlSizeBytes == 0)<br/>
{<br/>
throw EngineException(DSEE_EMPTY_DATASETREQUEST_ERROR,<br/>
"DataSetRequest::loadXML()",__FILE__,__LINE__,<br/>
"Expected an XML DataSetRequest. Instead got zero length input");<br/>
}<br/>
<br/>
IXMLDOMDocument2Ptr pRequestDoc;<br/>
HRESULT _hr = pRequestDoc.CreateInstance("Msxml2.FreeThreadedDOMDocument.4.0");<br/>
if FAILED(_hr)<br/>
{<br/>
throw EngineException(DSEE_COM_ERROR,<br/>
"DataSetRequest::loadXML()",__FILE__,__LINE__,<br/>
"Failed COM result handle creating Msxml2.FreeThreadedDOMDocument.4.0 instance");<br/>
}<br/>
<br/>
pRequestDoc->PutvalidateOnParse(false);<br/>
<br/>
BSTR tempBstr;<br/>
<br/>
try<br/>
{<br/>
// parse the DataSetRequest<br/>
tempBstr = stringToBstr(dataSetRequestXML);<br/>
VARIANT_BOOL res = pRequestDoc->loadXML(tempBstr);<br/>
<br/>
if (res == FALSE)<br/>
{<br/>
::SysFreeString(tempBstr);<br/>
throw EngineException(DSEE_DATASETREQUEST_PARSE_ERROR,<br/>
"DataSetRequest::loadXML()",__FILE__,__LINE__,<br/>
"Error loading DataSetRequest XML",<br/>
pRequestDoc->GetparseError());<br/>
}<br/>
}<br/>
catch (_com_error &e)<br/>
{<br/>
::SysFreeString(tempBstr);<br/>
<br/>
throw EngineException(DSEE_DATASETREQUEST_PARSE_ERROR,<br/>
"DataSetRequest::loadXML()",__FILE__,__LINE__,<br/>
"COM Error loading DataSetRequest XML",<br/>
e);<br/>
}<br/>
<br/>
::SysFreeString(tempBstr);<br/>
<br/>
<br/>
// add DataSet namespace to document so selectSingleNode() works with prefixes<br/>
// NOTE: ds: prefix here must match select statement prefixes below<br/>
string namespaces = "xmlns:ds=" + (string) DATASET_NAMESPACE + "";<br/>
pRequestDoc->setProperty("SelectionNamespaces", namespaces.c_str() );<br/>
<br/>
// QueryRequest<br/>
_pQueryRequestNode = pRequestDoc->selectSingleNode("//ds:QueryRequest");<br/>
if (_pQueryRequestNode == NULL)<br/>
{<br/>
throw EngineException(DSEE_DATASETREQUEST_PARSE_ERROR,<br/>
"DataSetRequest::loadXML()",__FILE__,__LINE__,<br/>
"Could not extract QueryRequest element from DataSetRequest XML");<br/>
}<br/>
<br/>
char* tempStr;<br/>
<br/>
// requestId attribute<br/>
IXMLDOMNodePtr requestIdNode = pRequestDoc->selectSingleNode("//@requestId");<br/>
if (requestIdNode != NULL)<br/>
{<br/>
tempStr = bstrToString(requestIdNode->Gettext());<br/>
_requestId = std::string(tempStr);<br/>
delete [] tempStr;<br/>
<br/>
if (_requestId.length == 0)<br/>
{<br/>
_requestId = "EMPTY-STRING";<br/>
}<br/>
}<br/>
else<br/>
{<br/>
_requestId = "MISSING";<br/>
}<br/>
<br/>
// languageId node<br/>
IXMLDOMNodePtr langIdNode = pRequestDoc->selectSingleNode("//ds:LanguageID");<br/>
if (langIdNode != NULL)<br/>
{<br/>
string languageId;<br/>
tempStr = bstrToString(langIdNode->Gettext());<br/>
languageId = std::string(tempStr);<br/>
delete [] tempStr;<br/>
<br/>
sscanf(languageId.c_str(),"%d",& _dartLanguageId);<br/>
}<br/>
<br/>
// character encoding node<br/>
IXMLDOMNodePtr charEncodingNode = pRequestDoc->selectSingleNode("//ds:CharacterEncoding");<br/>
if (charEncodingNode != NULL)<br/>
{<br/>
tempStr = bstrToString(charEncodingNode->Gettext());<br/>
_characterEncoding = std::string(tempStr);<br/>
delete [] tempStr;<br/>
}<br/>
<br/>
// username node<br/>
IXMLDOMNodePtr usernameNode = pRequestDoc->selectSingleNode("//ds:UserName");<br/>
if (usernameNode != NULL)<br/>
{<br/>
tempStr = bstrToString(usernameNode->Gettext());<br/>
_username = std::string(tempStr);<br/>
delete [] tempStr;<br/>
}<br/>
<br/>
// rowStart node<br/>
IXMLDOMNodePtr rowStartNode = pRequestDoc->selectSingleNode("//ds:RowStart");<br/>
if (rowStartNode != NULL)<br/>
{<br/>
string rowStart;<br/>
tempStr = bstrToString(rowStartNode->Gettext());<br/>
rowStart = std::string(tempStr);<br/>
delete [] tempStr;<br/>
<br/>
sscanf(rowStart.c_str(),"%d",& _rowStart);<br/>
<br/>
if (_rowStart <=0)<br/>
{<br/>
std:stringstream msg;<br/>
msg << "RowStart is one based and must be greater than zero: rowStart=" << _rowStart;<br/>
<br/>
throw EngineException(DSEE_DATASETREQUEST_VALIDATION_ERROR,<br/>
"DataSetRequest::loadXML()",__FILE__,__LINE__,<br/>
msg.str().c_str());<br/>
}<br/>
}<br/>
<br/>
<br/>
// rowCount node<br/>
IXMLDOMNodePtr rowCountNode = pRequestDoc->selectSingleNode("//ds:RowCount");<br/>
if (rowCountNode != NULL)<br/>
{<br/>
string rowCount;<br/>
tempStr = bstrToString(rowCountNode->Gettext());<br/>
rowCount = std::string(tempStr);<br/>
delete [] tempStr;<br/>
<br/>
sscanf(rowCount.c_str(),"%d",& _rowCount);<br/>
<br/>
if (_rowCount <=0)<br/>
{<br/>
std:stringstream msg;<br/>
msg << "RowCount must be greater than zero: rowCount=" << _rowCount;<br/>
<br/>
throw EngineException(DSEE_DATASETREQUEST_VALIDATION_ERROR,<br/>
"DataSetRequest::loadXML()",__FILE__,__LINE__,<br/>
msg.str().c_str());<br/>
}<br/>
}<br/>
<br/>
IXMLDOMNodePtr dataViewNode = pRequestDoc->selectSingleNode("//ds:QueryRequest/@dataView");<br/>
// bstrToString returns a pointer to a string and needs to be deleted explicitly.<br/>
if (dataViewNode != NULL)<br/>
{<br/>
tempStr = bstrToString(dataViewNode->Gettext());<br/>
_dataViewName = std::string(tempStr);<br/>
delete [] tempStr;<br/>
if (_dataViewName.length()==0)<br/>
{<br/>
std:stringstream msg;<br/>
msg << "dataView attribute can not be empty";<br/>
<br/>
throw EngineException(DSEE_DATASETREQUEST_VALIDATION_ERROR,<br/>
"DataSetRequest::loadXML()",__FILE__,__LINE__,<br/>
msg.str().c_str());<br/>
}<br/>
_requestId += "/" + _username + "/" + _dataViewName;<br/>
}<br/>
<br/>
// PivotInMemory node<br/>
_bPivotInMemory = false;<br/>
IXMLDOMNodePtr pivInMemNode = pRequestDoc->selectSingleNode("//dsivotInMemory");<br/>
if (pivInMemNode != NULL)<br/>
{<br/>
string strPivInMem;<br/>
tempStr = bstrToString(pivInMemNode->Gettext());<br/>
strPivInMem = std::string(tempStr);<br/>
delete[] tempStr;<br/>
<br/>
if (!strPivInMem.compare("true") || !strPivInMem.compare("1"))<br/>
_bPivotInMemory = true;<br/>
else if (!strPivInMem.compare("false") || !strPivInMem.compare("0"))<br/>
; // already false<br/>
else<br/>
{<br/>
std:stringstream msg;<br/>
msg << "PivotInMemory must be true,false,1, or 0. Current value: "
<br/>
<< strPivInMem.c_str();<br/>
throw EngineException(DSEE_DATASETREQUEST_VALIDATION_ERROR,<br/>
"DataSetRequest::loadXML()",__FILE__,__LINE__,<br/>
msg.str().c_str());<br/>
}<br/>
}<br/>
}<br/>
<br/>
<br/>
<br/>
View the full article
Below is the Code where the request is parsed.
void DataSetRequest::loadXML(const char* dataSetRequestXML)<br/>
{<br/>
_xmlSizeBytes = strlen(dataSetRequestXML) * sizeof(char); // store for stats logging<br/>
<br/>
if (_xmlSizeBytes == 0)<br/>
{<br/>
throw EngineException(DSEE_EMPTY_DATASETREQUEST_ERROR,<br/>
"DataSetRequest::loadXML()",__FILE__,__LINE__,<br/>
"Expected an XML DataSetRequest. Instead got zero length input");<br/>
}<br/>
<br/>
IXMLDOMDocument2Ptr pRequestDoc;<br/>
HRESULT _hr = pRequestDoc.CreateInstance("Msxml2.FreeThreadedDOMDocument.4.0");<br/>
if FAILED(_hr)<br/>
{<br/>
throw EngineException(DSEE_COM_ERROR,<br/>
"DataSetRequest::loadXML()",__FILE__,__LINE__,<br/>
"Failed COM result handle creating Msxml2.FreeThreadedDOMDocument.4.0 instance");<br/>
}<br/>
<br/>
pRequestDoc->PutvalidateOnParse(false);<br/>
<br/>
BSTR tempBstr;<br/>
<br/>
try<br/>
{<br/>
// parse the DataSetRequest<br/>
tempBstr = stringToBstr(dataSetRequestXML);<br/>
VARIANT_BOOL res = pRequestDoc->loadXML(tempBstr);<br/>
<br/>
if (res == FALSE)<br/>
{<br/>
::SysFreeString(tempBstr);<br/>
throw EngineException(DSEE_DATASETREQUEST_PARSE_ERROR,<br/>
"DataSetRequest::loadXML()",__FILE__,__LINE__,<br/>
"Error loading DataSetRequest XML",<br/>
pRequestDoc->GetparseError());<br/>
}<br/>
}<br/>
catch (_com_error &e)<br/>
{<br/>
::SysFreeString(tempBstr);<br/>
<br/>
throw EngineException(DSEE_DATASETREQUEST_PARSE_ERROR,<br/>
"DataSetRequest::loadXML()",__FILE__,__LINE__,<br/>
"COM Error loading DataSetRequest XML",<br/>
e);<br/>
}<br/>
<br/>
::SysFreeString(tempBstr);<br/>
<br/>
<br/>
// add DataSet namespace to document so selectSingleNode() works with prefixes<br/>
// NOTE: ds: prefix here must match select statement prefixes below<br/>
string namespaces = "xmlns:ds=" + (string) DATASET_NAMESPACE + "";<br/>
pRequestDoc->setProperty("SelectionNamespaces", namespaces.c_str() );<br/>
<br/>
// QueryRequest<br/>
_pQueryRequestNode = pRequestDoc->selectSingleNode("//ds:QueryRequest");<br/>
if (_pQueryRequestNode == NULL)<br/>
{<br/>
throw EngineException(DSEE_DATASETREQUEST_PARSE_ERROR,<br/>
"DataSetRequest::loadXML()",__FILE__,__LINE__,<br/>
"Could not extract QueryRequest element from DataSetRequest XML");<br/>
}<br/>
<br/>
char* tempStr;<br/>
<br/>
// requestId attribute<br/>
IXMLDOMNodePtr requestIdNode = pRequestDoc->selectSingleNode("//@requestId");<br/>
if (requestIdNode != NULL)<br/>
{<br/>
tempStr = bstrToString(requestIdNode->Gettext());<br/>
_requestId = std::string(tempStr);<br/>
delete [] tempStr;<br/>
<br/>
if (_requestId.length == 0)<br/>
{<br/>
_requestId = "EMPTY-STRING";<br/>
}<br/>
}<br/>
else<br/>
{<br/>
_requestId = "MISSING";<br/>
}<br/>
<br/>
// languageId node<br/>
IXMLDOMNodePtr langIdNode = pRequestDoc->selectSingleNode("//ds:LanguageID");<br/>
if (langIdNode != NULL)<br/>
{<br/>
string languageId;<br/>
tempStr = bstrToString(langIdNode->Gettext());<br/>
languageId = std::string(tempStr);<br/>
delete [] tempStr;<br/>
<br/>
sscanf(languageId.c_str(),"%d",& _dartLanguageId);<br/>
}<br/>
<br/>
// character encoding node<br/>
IXMLDOMNodePtr charEncodingNode = pRequestDoc->selectSingleNode("//ds:CharacterEncoding");<br/>
if (charEncodingNode != NULL)<br/>
{<br/>
tempStr = bstrToString(charEncodingNode->Gettext());<br/>
_characterEncoding = std::string(tempStr);<br/>
delete [] tempStr;<br/>
}<br/>
<br/>
// username node<br/>
IXMLDOMNodePtr usernameNode = pRequestDoc->selectSingleNode("//ds:UserName");<br/>
if (usernameNode != NULL)<br/>
{<br/>
tempStr = bstrToString(usernameNode->Gettext());<br/>
_username = std::string(tempStr);<br/>
delete [] tempStr;<br/>
}<br/>
<br/>
// rowStart node<br/>
IXMLDOMNodePtr rowStartNode = pRequestDoc->selectSingleNode("//ds:RowStart");<br/>
if (rowStartNode != NULL)<br/>
{<br/>
string rowStart;<br/>
tempStr = bstrToString(rowStartNode->Gettext());<br/>
rowStart = std::string(tempStr);<br/>
delete [] tempStr;<br/>
<br/>
sscanf(rowStart.c_str(),"%d",& _rowStart);<br/>
<br/>
if (_rowStart <=0)<br/>
{<br/>
std:stringstream msg;<br/>
msg << "RowStart is one based and must be greater than zero: rowStart=" << _rowStart;<br/>
<br/>
throw EngineException(DSEE_DATASETREQUEST_VALIDATION_ERROR,<br/>
"DataSetRequest::loadXML()",__FILE__,__LINE__,<br/>
msg.str().c_str());<br/>
}<br/>
}<br/>
<br/>
<br/>
// rowCount node<br/>
IXMLDOMNodePtr rowCountNode = pRequestDoc->selectSingleNode("//ds:RowCount");<br/>
if (rowCountNode != NULL)<br/>
{<br/>
string rowCount;<br/>
tempStr = bstrToString(rowCountNode->Gettext());<br/>
rowCount = std::string(tempStr);<br/>
delete [] tempStr;<br/>
<br/>
sscanf(rowCount.c_str(),"%d",& _rowCount);<br/>
<br/>
if (_rowCount <=0)<br/>
{<br/>
std:stringstream msg;<br/>
msg << "RowCount must be greater than zero: rowCount=" << _rowCount;<br/>
<br/>
throw EngineException(DSEE_DATASETREQUEST_VALIDATION_ERROR,<br/>
"DataSetRequest::loadXML()",__FILE__,__LINE__,<br/>
msg.str().c_str());<br/>
}<br/>
}<br/>
<br/>
IXMLDOMNodePtr dataViewNode = pRequestDoc->selectSingleNode("//ds:QueryRequest/@dataView");<br/>
// bstrToString returns a pointer to a string and needs to be deleted explicitly.<br/>
if (dataViewNode != NULL)<br/>
{<br/>
tempStr = bstrToString(dataViewNode->Gettext());<br/>
_dataViewName = std::string(tempStr);<br/>
delete [] tempStr;<br/>
if (_dataViewName.length()==0)<br/>
{<br/>
std:stringstream msg;<br/>
msg << "dataView attribute can not be empty";<br/>
<br/>
throw EngineException(DSEE_DATASETREQUEST_VALIDATION_ERROR,<br/>
"DataSetRequest::loadXML()",__FILE__,__LINE__,<br/>
msg.str().c_str());<br/>
}<br/>
_requestId += "/" + _username + "/" + _dataViewName;<br/>
}<br/>
<br/>
// PivotInMemory node<br/>
_bPivotInMemory = false;<br/>
IXMLDOMNodePtr pivInMemNode = pRequestDoc->selectSingleNode("//dsivotInMemory");<br/>
if (pivInMemNode != NULL)<br/>
{<br/>
string strPivInMem;<br/>
tempStr = bstrToString(pivInMemNode->Gettext());<br/>
strPivInMem = std::string(tempStr);<br/>
delete[] tempStr;<br/>
<br/>
if (!strPivInMem.compare("true") || !strPivInMem.compare("1"))<br/>
_bPivotInMemory = true;<br/>
else if (!strPivInMem.compare("false") || !strPivInMem.compare("0"))<br/>
; // already false<br/>
else<br/>
{<br/>
std:stringstream msg;<br/>
msg << "PivotInMemory must be true,false,1, or 0. Current value: "
<br/>
<< strPivInMem.c_str();<br/>
throw EngineException(DSEE_DATASETREQUEST_VALIDATION_ERROR,<br/>
"DataSetRequest::loadXML()",__FILE__,__LINE__,<br/>
msg.str().c_str());<br/>
}<br/>
}<br/>
}<br/>
<br/>
<br/>
<br/>
View the full article