MSXML, deadlock in multithreading application

질문 MSXML, deadlock in multithreading application

  • 2012년 2월 15일 수요일 오전 3:13
     
      코드 있음

    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월 16일 목요일 오전 6:07
    중재자
     
     

    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월 22일 수요일 오후 5:21
     
     

    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