Hello Kevin,

I think you're right. It's a "thread safety" problem. In COM we have to use proxies to send (with data marshalling) events to objects on others threads, so I think XPCOM have something like COM. For now, I have only a glue:

nsIProxyObjectManager

  Anyone know nsIProxyObjectManager and how to use it?


Kevin Strong wrote:
Those look like the EXACT same errors I am getting in my own component! In
mine, nsIDOMHTMLInputElement::Click and nsIWebNavigation::LoadURI are
crashing in the same way. I have spent days debugging and searching for
answers, and I am pretty much 99.9% certain that the reason for these errors
is that none of the XPCOM components are thread-safe (and that fact that
both of us are getting similar crashes from XPCOM components called from
worker threads proves this is a serious issue).
So, basically the only solution I know of to this is to not call the
functions that are crashing in your thread. I know it sucks, but that is
what you will have to do. I recommend finding some way to call all the
non-thread safe methods of your components (i.e. the ones crashing when you
call them from your worker thread) in the main thread. A possible solution I
looked into was having my worker thread use the nsIObserverService to tell
the main component to do what it needs to do, however,
nsIObserverService::NotifyObservers is also not thread safe (and crashed in
the same way)! I'm not to sure if there are any other workarounds, at the
moment the best option I see is a dirty hack using a timer that checks a
global variable to see when the worker threads needs something to be done,
however in my eyes this is a less than ideal solution. Anyone else have any
ideas?

-----Original Message-----
From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On Behalf Of Maciste
Sent: Thursday, August 25, 2005 11:08 AM
To: [email protected]
Subject: nsIChannel::Open access violation

Hi,

     I'm getting an "access violation" erro calling nsIChannel::Open:

First-chance exception at 0x00455eb7 in firefox.exe: 0xC0000005: Access violation reading location 0x00000000. Unhandled exception at 0x00455eb7 in firefox.exe: 0xC0000005: Access violation reading location 0x00000000.

     Details:

1) It's C++ component, called from javascript
2) When called, the component starts a background task using PR_CreateThread passing its reference ("this" pointer)
3) The thread uses the received reference to call a component's method
4) This method uses nsIChannel::Open to download some data. At this moment I receive an "access violation".

     Obs:

1) I get the same error with nsIChannel::AsyncOpen
2) If I call nsIChannel::Open on the same thread, there is no problem.

     Is there any restrictions on using nsIChannel::AsyncOpen/OPen
on differents threads ? Is there any workaround ?

Thanks,

Maciste


PS.: Callstack and code snipet:

=================================================
        firefox.exe!00455eb7()  
        firefox.exe!00455e78()  
        firefox.exe!004438eb()  
        firefox.exe!004ab26f()  
        xpcom.dll!6030d246()    
        firefox.exe!004536bc()  
        firefox.exe!0047db77()  
        firefox.exe!004823e0()  
        firefox.exe!00478f53()  
        firefox.exe!0049801e()  
> XPComRssReader.dll!CRssHttp::Get(std::basic_string<char,std::char_traits<cha r>,std::allocator<char> > sUrl={...}, std::basic_string<char,std::char_traits<char>,std::allocator<char> > & sData={...}) Line 304 + 0x3b C++ XPComRssReader.dll!CFeeder::LoadFromUrl(std::basic_string<char,std::char_tra its<char>,std::allocator<char> > sUrl={...}, std::basic_string<char,std::char_traits<char>,std::allocator<char> > sCookie={...}) Line 375 + 0x28 C++
        XPComRssReader.dll!CFeeder::Refresh()  Line 458 + 0x50  C++
        XPComRssReader.dll!CRssReader::Refresh(int nBatch=5)  Line 987 + 0x8
C++
XPComRssReader.dll!CRssReaderWrapper::WorkThread(void * param=0x027d5df8) Line 972 C++
        nspr4.dll!60144c21()    
        ntdll.dll!7c96e0d4()    
        nspr4.dll!60146d4b()    
        msvcrt.dll!77c3a3b0()   
        ntdll.dll!7c96e0d4()    
        kernel32.dll!7c80b50b()         
        ntdll.dll!7c96e0d4()    
        kernel32.dll!7c8399f3()         
================================================

        nsCOMPtr<nsIServiceManager> servMan;
        nsCOMPtr<nsIComponentManager> compMan;
        nsCOMPtr<nsIIOService> ioService;

        nsCOMPtr<nsIInputStream> inputStream;
        nsCOMPtr<nsIChannel> channel;
        nsCOMPtr<nsIHttpChannel> http_channel;
        nsEmbedCString sRequestMethod("GET");
        nsCOMPtr<nsIURI> ext_uri;
        nsEmbedCString uri_str(sUrl.c_str());
        nsEmbedCString asScheme;
        string  sScheme;

        nsCOMPtr<nsIStreamListener> streamListener;
        nsCOMPtr<nsIXMLHttpRequest> xmlRequest;
        nsEmbedString asData;
        nsEmbedCString ascData;

        nsresult rv = NS_GetServiceManager(getter_AddRefs(servMan));
        if (NS_FAILED(rv))
        {
                lRet = ERR_CONNECTION_FAILED;
                goto final;
        }

        
        rv = NS_GetComponentManager(getter_AddRefs(compMan));
        if (NS_FAILED(rv))
        {
                lRet = ERR_CONNECTION_FAILED;
                goto final;
        }


rv = servMan->GetServiceByContractID("@mozilla.org/network/io-service;1", NS_GET_IID(nsIIOService), getter_AddRefs(ioService));
        if (NS_FAILED(rv))
        {
                lRet = ERR_CONNECTION_FAILED;
                goto final;
        }

        rv = ioService->NewURI(uri_str, nsnull,  nsnull,
getter_AddRefs(ext_uri));
        if (NS_FAILED(rv))
        {
                lRet = ERR_CONNECTION_FAILED;
                goto final;
        }

        PRBool bIsHttp, bIsHttps;
        rv = ext_uri->SchemeIs("http", &bIsHttp);
        if (NS_FAILED(rv))
        {
                lRet = ERR_CONNECTION_FAILED;
                goto final;
        }
        rv = ext_uri->SchemeIs("https", &bIsHttps);
        if (NS_FAILED(rv))
        {
                lRet = ERR_CONNECTION_FAILED;
                goto final;
        }

        if(!bIsHttp && !bIsHttps)
        {
                lRet = ERR_INVALID_PROTOCOL;
                goto final;
        }

        rv = ioService->NewChannelFromURI(ext_uri, getter_AddRefs(channel));
        if (NS_FAILED(rv))
        {
                lRet = ERR_CONNECTION_FAILED;
                goto final;
        }

        http_channel = do_QueryInterface(channel);

        http_channel->SetRedirectionLimit(0);
        
        http_channel->SetRequestMethod(sRequestMethod);


//HERE, ACCESS VIOLATION
rv = channel->Open(getter_AddRefs(inputStream));//AsyncOpen(static_cast< nsIStreamListener* >(this), static_cast< nsISupports* >(this));
        if (NS_FAILED(rv))
        {
                lRet = ERR_CONNECTION_FAILED;
                goto final;
        }





_______________________________________________
Mozilla-xpcom mailing list
[email protected]
http://mail.mozilla.org/listinfo/mozilla-xpcom


_______________________________________________
Mozilla-xpcom mailing list
[email protected]
http://mail.mozilla.org/listinfo/mozilla-xpcom

Reply via email to