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