none
MSXML, deadlock in multithreading application

    질문

  • Hello,

    I try to use msxml in multithreading application: one thread read value and another thread write value (I work with different subnodes). But I get a deadlock in application.

    I create a simple example for demonstrait it:

    // MSXMLMultithreadingTest.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    #include <msxml6.h>
    #include <comutil.h>
    
    // Macro that calls a COM method returning HRESULT value.
    #define CHK_HR(stmt)        do { hr=(stmt); if (FAILED(hr)) goto CleanUp; } while(0)
    
    // Macro to verify memory allcation.
    #define CHK_ALLOC(p)        do { if (!(p)) { hr = E_OUTOFMEMORY; goto CleanUp; } } while(0)
    
    // Macro that releases a COM object if not NULL.
    #define SAFE_RELEASE(p)     do { if ((p)) { (p)->Release(); (p) = NULL; } } while(0)\
    
    // Helper function to create a VT_BSTR variant from a null terminated string. 
    HRESULT VariantFromString(PCWSTR wszValue, VARIANT &Variant)
    {
        HRESULT hr = S_OK;
        BSTR bstr = SysAllocString(wszValue);
        CHK_ALLOC(bstr);
    
        V_VT(&Variant)   = VT_BSTR;
        V_BSTR(&Variant) = bstr;
    
    CleanUp:
        return hr;
    }
    
    DWORD WINAPI SetAttributeThreadFunction( LPVOID lpParam ) 
    {
        auto pXMLDom = reinterpret_cast<IXMLDOMDocument *>(lpParam);
        BSTR queryString = L"/portfolio";
        IXMLDOMNode* tmp;
        if( FAILED(pXMLDom->selectSingleNode(queryString, &tmp)) )
        {
            OutputDebugString(L"FAILED(pXMLDom->selectSingleNode(queryString, &tmp))");
        }
        IXMLDOMElement* root;
        if( FAILED(tmp->QueryInterface(IID_IXMLDOMElement, (void **)&root)) )
        {
            OutputDebugString(L"FAILED(tmp->QueryInterface(IID_IXMLDOMElement, (void **)&root))");
        }
        BSTR attrName = L"TestAttribute";
        _variant_t value = 10;
        while(true)
        {
            root->setAttribute(attrName, value);
            OutputDebugString(L"setAttribute - Ok\n");
        }
    }
    
    DWORD WINAPI GetNodeTypedValueThreadFunction( LPVOID lpParam ) 
    {
        auto pXMLDom = reinterpret_cast<IXMLDOMDocument *>(lpParam);
        BSTR queryString = L"/";
        IXMLDOMNode* tmp;
        if( FAILED(pXMLDom->selectSingleNode(queryString, &tmp)) )
        {
            OutputDebugString(L"FAILED(pXMLDom->selectSingleNode(queryString, &tmp))");
        }
        VARIANT _result;
        VariantInit(&_result);
    
        while(true)
        {
            tmp->get_nodeTypedValue(&_result);
            OutputDebugString(L"get_nodeTypedValue - Ok\n");
        }
    }
    
    // Helper function to create a DOM instance. 
    HRESULT CreateAndInitDOM(IXMLDOMDocument **ppDoc)
    {
        HRESULT hr = CoCreateInstance(__uuidof(FreeThreadedDOMDocument60), NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(ppDoc));
        if (SUCCEEDED(hr))
        {
            // these methods should not fail so don't inspect result
            (*ppDoc)->put_async(VARIANT_FALSE);  
            (*ppDoc)->put_validateOnParse(VARIANT_FALSE);
            (*ppDoc)->put_resolveExternals(VARIANT_FALSE);
        }
        return hr;
    }
    
    void loadDOMRaw()
    {
        HRESULT hr = S_OK;
        IXMLDOMDocument *pXMLDom = NULL;
        IXMLDOMParseError *pXMLErr = NULL;
    
        BSTR bstrXML = L"<portfolio xmlns:dt=\"urn:schemas-microsoft-com:datatypes\"></portfolio>";
        BSTR bstrErr = NULL;
        VARIANT_BOOL varStatus;
        VARIANT varFileName;
        VariantInit(&varFileName);
    
        CHK_HR(CreateAndInitDOM(&pXMLDom));
    
        // XML file name to load
        CHK_HR(pXMLDom->loadXML(bstrXML, &varStatus));
        if (varStatus == VARIANT_TRUE)
        {
            CHK_HR(pXMLDom->get_xml(&bstrXML));
            printf("XML DOM loaded from stocks.xml:\n%S\n", bstrXML);
        }
        else
        {
            // Failed to load xml, get last parsing error
            CHK_HR(pXMLDom->get_parseError(&pXMLErr));
            CHK_HR(pXMLErr->get_reason(&bstrErr));
            printf("Failed to load DOM from stocks.xml. %S\n", bstrErr);
        }
        auto handle1 = CreateThread( 
                NULL,                   // default security attributes
                0,                      // use default stack size  
                SetAttributeThreadFunction,       // thread function name
                pXMLDom,          // argument to thread function 
                0,                      // use default creation flags 
                NULL);   // returns the thread identifier
        auto handle2 = CreateThread( 
                NULL,                   // default security attributes
                0,                      // use default stack size  
                GetNodeTypedValueThreadFunction,       // thread function name
                pXMLDom,          // argument to thread function 
                0,                      // use default creation flags 
                NULL);   // returns the thread identifier 
    
        Sleep(1000 * 300);
    
        TerminateThread(handle1, 0);
        TerminateThread(handle2, 0);
    
    CleanUp:
        SAFE_RELEASE(pXMLDom);
        SAFE_RELEASE(pXMLErr);
        SysFreeString(bstrXML);
        SysFreeString(bstrErr);
        VariantClear(&varFileName);
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
         HRESULT hr = CoInitialize(NULL);
        if(SUCCEEDED(hr))
        {
            loadDOMRaw();
            CoUninitialize();
        }
        return 0;
    }
    

    What I am doing wrong?


    2012년 2월 15일 수요일 오전 3:13

모든 응답

  • Hi Evgeniy Mironov,

    Welcome!
    We will do some more pending research  about your problem and come back as soon as possible, Thanks for understanding.

    Have a nice day.



    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2012년 2월 16일 목요일 오전 6:07
    중재자
  • Hi Evgeniy,

    While I would like to help you this particular question falls into the paid support category which requires a more in-depth level of support. Please visit the below link to see the various paid support options that are available to better meet your needs. http://support.microsoft.com/default.aspx?id=fh;en-us;offerprophone

    Provide the sample code and the xml files it is parsing. We would try to create a repro at our end and find the cause of the multi-threading issue with the resolution.

    Regards,

    Angshuman Nayak

    2012년 2월 22일 수요일 오후 5:21