diff --git a/mozilla/chrome/src/nsChromeProtocolHandler.cpp b/mozilla/chrome/src/nsChromeProtocolHandler.cpp index 2242568732e..4018105609a 100644 --- a/mozilla/chrome/src/nsChromeProtocolHandler.cpp +++ b/mozilla/chrome/src/nsChromeProtocolHandler.cpp @@ -47,12 +47,10 @@ #include "nsCOMPtr.h" #include "nsContentCID.h" #include "nsCRT.h" -#include "nsEventQueueUtils.h" +#include "nsThreadUtils.h" #include "nsIChannel.h" #include "nsIChromeRegistry.h" #include "nsIComponentManager.h" -#include "nsIEventQueue.h" -#include "nsIEventQueueService.h" #include "nsIFastLoadService.h" #include "nsIFile.h" #include "nsIFileURL.h" @@ -103,7 +101,7 @@ static NS_DEFINE_CID(kXULPrototypeCacheCID, NS_XULPROTOTYPECACHE_CID); // #define LOG(args) PR_LOG(gLog, PR_LOG_DEBUG, args) -class nsCachedChromeChannel : public nsIChannel +class nsCachedChromeChannel : public nsIChannel, public nsIRunnable { protected: ~nsCachedChromeChannel(); @@ -116,12 +114,6 @@ protected: nsCOMPtr mOwner; nsresult mStatus; - static NS_HIDDEN_(nsresult) - PostLoadEvent(nsCachedChromeChannel* aChannel, PLHandleEventProc aHandler); - - static void* PR_CALLBACK HandleLoadEvent(PLEvent* aEvent); - static void PR_CALLBACK DestroyLoadEvent(PLEvent* aEvent); - #ifdef PR_LOGGING static PRLogModuleInfo* gLog; #endif @@ -143,18 +135,21 @@ public: NS_IMETHOD GetLoadFlags(nsLoadFlags *); NS_IMETHOD SetLoadFlags(nsLoadFlags); -// nsIChannel + // nsIChannel NS_DECL_NSICHANNEL + // nsIRunnable + NS_DECL_NSIRUNNABLE }; #ifdef PR_LOGGING PRLogModuleInfo* nsCachedChromeChannel::gLog; #endif -NS_IMPL_ISUPPORTS2(nsCachedChromeChannel, +NS_IMPL_ISUPPORTS3(nsCachedChromeChannel, nsIChannel, - nsIRequest) + nsIRequest, + nsIRunnable) nsCachedChromeChannel::nsCachedChromeChannel(nsIURI* aURI) : mURI(aURI) @@ -226,7 +221,7 @@ nsCachedChromeChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctxt) // Queue an event to ourselves to let the stack unwind before // calling OnStartRequest(). This allows embedding to occur // before we fire OnStopRequest(). - rv = PostLoadEvent(this, HandleLoadEvent); + rv = NS_DispatchToCurrentThread(this); if (NS_FAILED(rv)) return rv; @@ -350,78 +345,44 @@ nsCachedChromeChannel::SetContentLength(PRInt32 aContentLength) return NS_ERROR_NOT_IMPLEMENTED; } -nsresult -nsCachedChromeChannel::PostLoadEvent(nsCachedChromeChannel* aChannel, - PLHandleEventProc aHandler) -{ - nsCOMPtr queue; - nsresult rv = NS_GetCurrentEventQ(getter_AddRefs(queue)); - if (NS_FAILED(rv)) - return rv; - - PLEvent* event = new PLEvent; - if (! event) - return NS_ERROR_OUT_OF_MEMORY; - - PL_InitEvent(event, - aChannel, - aHandler, - DestroyLoadEvent); - NS_ADDREF(aChannel); - - rv = queue->PostEvent(event); - if (NS_FAILED(rv)) - PL_DestroyEvent(event); - return rv; -} - -void* PR_CALLBACK -nsCachedChromeChannel::HandleLoadEvent(PLEvent* aEvent) +NS_IMETHODIMP +nsCachedChromeChannel::Run() { // Fire the OnStartRequest() for the cached chrome channel, then - // queue another event to trigger the OnStopRequest()... - nsCachedChromeChannel* channel = (nsCachedChromeChannel*) aEvent->owner; + // trigger the OnStopRequest()... // If the load has been cancelled, then just bail now. We won't // send On[Start|Stop]Request(). - if (NS_FAILED(channel->mStatus)) + if (NS_FAILED(mStatus)) return nsnull; LOG(("nsCachedChromeChannel[%p]: firing OnStartRequest for %p", - channel, channel->mListener.get())); + this, mListener.get())); - (void) channel->mListener->OnStartRequest(channel, channel->mContext); + (void) mListener->OnStartRequest(this, mContext); LOG(("nsCachedChromeChannel[%p]: firing OnStopRequest for %p", - channel, channel->mListener.get())); + this, mListener.get())); - (void) channel->mListener->OnStopRequest(channel, channel->mContext, - channel->mStatus); + (void) mListener->OnStopRequest(this, mContext, mStatus); - if (channel->mLoadGroup) { + if (mLoadGroup) { LOG(("nsCachedChromeChannel[%p]: removing self from load group %p", - channel, channel->mLoadGroup.get())); + this, mLoadGroup.get())); - (void) channel->mLoadGroup->RemoveRequest(channel, nsnull, channel->mStatus); + (void) mLoadGroup->RemoveRequest(this, nsnull, mStatus); } - channel->mListener = nsnull; - channel->mContext = nsnull; + mListener = nsnull; + mContext = nsnull; return nsnull; } -void PR_CALLBACK -nsCachedChromeChannel::DestroyLoadEvent(PLEvent* aEvent) -{ - nsCachedChromeChannel* channel = (nsCachedChromeChannel*) aEvent->owner; - NS_RELEASE(channel); - delete aEvent; -} - //////////////////////////////////////////////////////////////////////////////// -NS_IMPL_THREADSAFE_ISUPPORTS2(nsChromeProtocolHandler, nsIProtocolHandler, nsISupportsWeakReference) +NS_IMPL_THREADSAFE_ISUPPORTS2(nsChromeProtocolHandler, nsIProtocolHandler, + nsISupportsWeakReference) //////////////////////////////////////////////////////////////////////////////// // nsIProtocolHandler methods: diff --git a/mozilla/content/base/public/nsContentUtils.h b/mozilla/content/base/public/nsContentUtils.h index c8a1f0cbf1a..2bc7fab74ed 100644 --- a/mozilla/content/base/public/nsContentUtils.h +++ b/mozilla/content/base/public/nsContentUtils.h @@ -80,7 +80,6 @@ class nsIStringBundle; class nsIContentPolicy; class nsILineBreaker; class nsIWordBreaker; -class nsIEventQueueService; class nsIJSRuntimeService; class nsIEventListenerManager; struct JSRuntime; @@ -649,14 +648,6 @@ public: */ static nsIContentPolicy *GetContentPolicy(); - /** - * Return the event queue service - */ - static nsIEventQueueService* EventQueueService() - { - return sEventQueueService; - } - /** * Make sure that whatever value *aPtr contains at any given moment is * protected from JS GC until we remove the GC root. A call to this that @@ -822,8 +813,6 @@ private: static nsILineBreaker* sLineBreaker; static nsIWordBreaker* sWordBreaker; - static nsIEventQueueService* sEventQueueService; - // Holds pointers to nsISupports* that should be released at shutdown static nsVoidArray* sPtrsToPtrsToRelease; diff --git a/mozilla/content/base/src/nsContentUtils.cpp b/mozilla/content/base/src/nsContentUtils.cpp index 1e435522ec1..2a3fbf76375 100644 --- a/mozilla/content/base/src/nsContentUtils.cpp +++ b/mozilla/content/base/src/nsContentUtils.cpp @@ -115,7 +115,6 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID); #include "nsLWBrkCIID.h" #include "nsILineBreaker.h" #include "nsIWordBreaker.h" -#include "nsIEventQueueService.h" #include "jsdbgapi.h" #include "nsIJSRuntimeService.h" #include "nsIDOMDocumentXBL.h" @@ -157,7 +156,6 @@ nsIContentPolicy *nsContentUtils::sContentPolicyService; PRBool nsContentUtils::sTriedToGetContentPolicy = PR_FALSE; nsILineBreaker *nsContentUtils::sLineBreaker; nsIWordBreaker *nsContentUtils::sWordBreaker; -nsIEventQueueService *nsContentUtils::sEventQueueService; nsVoidArray *nsContentUtils::sPtrsToPtrsToRelease; nsIJSRuntimeService *nsContentUtils::sJSRuntimeService; JSRuntime *nsContentUtils::sScriptRuntime; @@ -300,9 +298,6 @@ nsContentUtils::Init() rv = CallGetService(NS_WBRK_CONTRACTID, &sWordBreaker); NS_ENSURE_SUCCESS(rv, rv); - rv = CallGetService(NS_EVENTQUEUESERVICE_CONTRACTID, &sEventQueueService); - NS_ENSURE_SUCCESS(rv, rv); - // Ignore failure and just don't load images rv = CallGetService("@mozilla.org/image/loader;1", &sImgLoader); if (NS_FAILED(rv)) { @@ -593,7 +588,6 @@ nsContentUtils::Shutdown() NS_IF_RELEASE(sIOService); NS_IF_RELEASE(sLineBreaker); NS_IF_RELEASE(sWordBreaker); - NS_IF_RELEASE(sEventQueueService); #ifdef MOZ_XTF NS_IF_RELEASE(sXTFService); #endif diff --git a/mozilla/content/base/src/nsDocument.cpp b/mozilla/content/base/src/nsDocument.cpp index 37e17a3d026..f32e16a5b4b 100644 --- a/mozilla/content/base/src/nsDocument.cpp +++ b/mozilla/content/base/src/nsDocument.cpp @@ -82,6 +82,7 @@ #include "nsIPresShell.h" #include "nsPresContext.h" #include "nsContentUtils.h" +#include "nsThreadUtils.h" #include "nsNodeInfoManager.h" #include "nsIXBLService.h" #include "nsIXPointer.h" @@ -128,9 +129,6 @@ static NS_DEFINE_CID(kDOMEventGroupCID, NS_DOMEVENTGROUP_CID); #include "nsIDOMHTMLFormElement.h" #include "nsIRequest.h" #include "nsILink.h" -#include "plevent.h" -#include "nsIEventQueueService.h" -#include "nsIEventQueue.h" #include "nsICharsetAlias.h" #include "nsIParser.h" @@ -5215,55 +5213,30 @@ nsDocument::UnblockOnload(PRBool aFireSync) } } +class nsUnblockOnloadEvent : public nsRunnable { +public: + nsUnblockOnloadEvent(nsDocument *doc) : mDoc(doc) {} + NS_IMETHOD Run() { + mDoc->DoUnblockOnload(); + return NS_OK; + } +private: + nsRefPtr mDoc; +}; + void nsDocument::PostUnblockOnloadEvent() { - nsCOMPtr eventQ; - nsContentUtils::EventQueueService()-> - GetSpecialEventQueue(nsIEventQueueService::UI_THREAD_EVENT_QUEUE, - getter_AddRefs(eventQ)); - if (!eventQ) { - return; - } - - PLEvent* evt = new PLEvent(); - if (!evt) { - return; - } - - PL_InitEvent(evt, this, nsDocument::HandleOnloadBlockerEvent, - nsDocument::DestroyOnloadBlockerEvent); - - // After this point, event destruction will release |this| - NS_ADDREF_THIS(); - - nsresult rv = eventQ->PostEvent(evt); - if (NS_FAILED(rv)) { - PL_DestroyEvent(evt); - } else { + nsCOMPtr evt = new nsUnblockOnloadEvent(this); + nsresult rv = NS_DispatchToCurrentThread(evt); + if (NS_SUCCEEDED(rv)) { // Stabilize block count so we don't post more events while this one is up ++mOnloadBlockCount; + } else { + NS_WARNING("failed to dispatch nsUnblockOnloadEvent"); } } -// static -void* PR_CALLBACK -nsDocument::HandleOnloadBlockerEvent(PLEvent* aEvent) -{ - nsDocument* doc = NS_STATIC_CAST(nsDocument*, aEvent->owner); - doc->DoUnblockOnload(); - return nsnull; -} - -// static -void PR_CALLBACK -nsDocument::DestroyOnloadBlockerEvent(PLEvent* aEvent) -{ - nsDocument* doc = NS_STATIC_CAST(nsDocument*, aEvent->owner); - NS_RELEASE(doc); - delete aEvent; -} - void nsDocument::DoUnblockOnload() { diff --git a/mozilla/content/base/src/nsDocument.h b/mozilla/content/base/src/nsDocument.h index a173e70919a..ae0378ce7d3 100644 --- a/mozilla/content/base/src/nsDocument.h +++ b/mozilla/content/base/src/nsDocument.h @@ -774,9 +774,9 @@ protected: private: nsresult IsAllowedAsChild(PRUint16 aNodeType, nsIContent* aRefContent); + friend class nsUnblockOnloadEvent; + void PostUnblockOnloadEvent(); - static EventHandlerFunc HandleOnloadBlockerEvent; - static EventDestructorFunc DestroyOnloadBlockerEvent; void DoUnblockOnload(); // These are not implemented and not supported. diff --git a/mozilla/content/base/src/nsImageLoadingContent.cpp b/mozilla/content/base/src/nsImageLoadingContent.cpp index fd906cdeaff..313790606e5 100644 --- a/mozilla/content/base/src/nsImageLoadingContent.cpp +++ b/mozilla/content/base/src/nsImageLoadingContent.cpp @@ -50,9 +50,7 @@ #include "imgIContainer.h" #include "gfxIImageFrame.h" #include "imgILoader.h" -#include "plevent.h" -#include "nsIEventQueueService.h" -#include "nsIEventQueue.h" +#include "nsThreadUtils.h" #include "nsNetUtil.h" #include "nsPresContext.h" @@ -713,7 +711,7 @@ nsImageLoadingContent::StringToURI(const nsAString& aSpec, */ MOZ_DECL_CTOR_COUNTER(ImageEvent) -class ImageEvent : public PLEvent +class ImageEvent : public nsRunnable { public: ImageEvent(nsPresContext* aPresContext, nsIContent* aContent, @@ -727,8 +725,11 @@ public: } ~ImageEvent() { + mDocument->UnblockOnload(PR_TRUE); MOZ_COUNT_DTOR(ImageEvent); } + + NS_IMETHOD Run(); nsCOMPtr mPresContext; nsCOMPtr mContent; @@ -739,13 +740,12 @@ public: nsCOMPtr mDocument; }; -PR_STATIC_CALLBACK(void*) -HandleImagePLEvent(PLEvent* aEvent) +NS_IMETHODIMP +ImageEvent::Run() { - ImageEvent* evt = NS_STATIC_CAST(ImageEvent*, aEvent); PRUint32 eventMsg; - if (evt->mMessage.EqualsLiteral("load")) { + if (mMessage.EqualsLiteral("load")) { eventMsg = NS_IMAGE_LOAD; } else { eventMsg = NS_IMAGE_ERROR; @@ -753,18 +753,9 @@ HandleImagePLEvent(PLEvent* aEvent) nsEvent event(PR_TRUE, eventMsg); event.flags |= NS_EVENT_FLAG_CANT_BUBBLE; - nsEventDispatcher::Dispatch(evt->mContent, evt->mPresContext, &event); + nsEventDispatcher::Dispatch(mContent, mPresContext, &event); - return nsnull; -} - -PR_STATIC_CALLBACK(void) -DestroyImagePLEvent(PLEvent* aEvent) -{ - ImageEvent* evt = NS_STATIC_CAST(ImageEvent*, aEvent); - evt->mDocument->UnblockOnload(PR_TRUE); - - delete evt; + return NS_OK; } nsresult @@ -779,13 +770,9 @@ nsImageLoadingContent::FireEvent(const nsAString& aEventType) // no use to fire events if there is no document.... return NS_OK; } - nsCOMPtr eventQ; - // Use the UI thread event queue (though we should not be getting called from - // off the UI thread in any case....) - nsresult rv = nsContentUtils::EventQueueService()-> - GetSpecialEventQueue(nsIEventQueueService::UI_THREAD_EVENT_QUEUE, - getter_AddRefs(eventQ)); - NS_ENSURE_TRUE(eventQ, rv); + + // We should not be getting called from off the UI thread... + NS_ASSERTION(NS_IsMainThread(), "should be on the main thread"); nsIPresShell *shell = document->GetShellAt(0); NS_ENSURE_TRUE(shell, NS_ERROR_FAILURE); @@ -795,21 +782,13 @@ nsImageLoadingContent::FireEvent(const nsAString& aEventType) nsCOMPtr ourContent = do_QueryInterface(this); - ImageEvent* evt = new ImageEvent(presContext, ourContent, aEventType, document); - + nsCOMPtr evt = + new ImageEvent(presContext, ourContent, aEventType, document); NS_ENSURE_TRUE(evt, NS_ERROR_OUT_OF_MEMORY); - PL_InitEvent(evt, this, ::HandleImagePLEvent, ::DestroyImagePLEvent); - // Block onload for our event. Since we unblock in the event destructor, we // want to block now, even if posting will fail. document->BlockOnload(); - rv = eventQ->PostEvent(evt); - - if (NS_FAILED(rv)) { - PL_DestroyEvent(evt); - } - - return rv; + return NS_DispatchToCurrentThread(evt); } diff --git a/mozilla/content/base/src/nsObjectLoadingContent.cpp b/mozilla/content/base/src/nsObjectLoadingContent.cpp index 25a6851d8f9..83507621594 100644 --- a/mozilla/content/base/src/nsObjectLoadingContent.cpp +++ b/mozilla/content/base/src/nsObjectLoadingContent.cpp @@ -55,7 +55,6 @@ #include "nsIWebNavigationInfo.h" // Util headers -#include "plevent.h" #include "prlog.h" #include "nsAutoPtr.h" @@ -63,9 +62,9 @@ #include "nsContentPolicyUtils.h" #include "nsContentUtils.h" #include "nsDocShellCID.h" -#include "nsEventQueueUtils.h" #include "nsHTMLAtoms.h" #include "nsLayoutAtoms.h" +#include "nsThreadUtils.h" #include "nsNetUtil.h" // Concrete classes @@ -82,20 +81,12 @@ static PRLogModuleInfo* gObjectLog = PR_NewLogModule("objlc"); #define LOG(args) PR_LOG(gObjectLog, PR_LOG_DEBUG, args) #define LOG_ENABLED() PR_LOG_TEST(gObjectLog, PR_LOG_DEBUG) -PR_BEGIN_EXTERN_C -/* Note that these typedefs declare functions, not pointer to - functions. That's the only way in which they differ from - PLHandleEventProc and PLDestroyEventProc. */ -typedef void* -(PR_CALLBACK EventHandlerFunc)(PLEvent* self); -typedef void -(PR_CALLBACK EventDestructorFunc)(PLEvent* self); -PR_END_EXTERN_C - -struct nsAsyncInstantiateEvent : public PLEvent { +class nsAsyncInstantiateEvent : public nsRunnable { +public: // This stores both the content and the frame so that Instantiate calls can be // avoided if the frame changed in the meantime. // (the content is stored implicitly as the owner) + nsObjectLoadingContent *mContent; nsIObjectFrame* mFrame; nsCString mContentType; nsCOMPtr mURI; @@ -104,107 +95,81 @@ struct nsAsyncInstantiateEvent : public PLEvent { nsIObjectFrame* aFrame, const nsCString& aType, nsIURI* aURI) - : mFrame(aFrame), mContentType(aType), mURI(aURI) + : mContent(aContent), mFrame(aFrame), mContentType(aType), mURI(aURI) { - NS_ADDREF(NS_STATIC_CAST(nsIObjectLoadingContent*, aContent)); - PL_InitEvent(this, aContent, nsAsyncInstantiateEvent::HandleEvent, - nsAsyncInstantiateEvent::CleanupEvent); + NS_STATIC_CAST(nsIObjectLoadingContent *, mContent)->AddRef(); } ~nsAsyncInstantiateEvent() { - nsIObjectLoadingContent* con = NS_STATIC_CAST(nsIObjectLoadingContent*, - PL_GetEventOwner(this)); - NS_RELEASE(con); + NS_STATIC_CAST(nsIObjectLoadingContent *, mContent)->Release(); } - static EventHandlerFunc HandleEvent; - static EventDestructorFunc CleanupEvent; + NS_IMETHOD Run(); }; -/* static */ void* PR_CALLBACK -nsAsyncInstantiateEvent::HandleEvent(PLEvent* event) +NS_IMETHODIMP +nsAsyncInstantiateEvent::Run() { - nsAsyncInstantiateEvent* ev = NS_STATIC_CAST(nsAsyncInstantiateEvent*, - event); - nsObjectLoadingContent* con = NS_STATIC_CAST(nsObjectLoadingContent*, - PL_GetEventOwner(event)); + // Check if we've been "revoked" + if (mContent->mPendingInstantiateEvent != this) + return NS_OK; + mContent->mPendingInstantiateEvent = nsnull; + // Make sure that we still have the right frame (NOTE: we don't need to check // the type here - GetFrame() only returns object frames, and that means we're // a plugin) // Also make sure that we still refer to the same data. - if (con->GetFrame() == ev->mFrame && - con->mURI == ev->mURI && - con->mContentType.Equals(ev->mContentType)) { + if (mContent->GetFrame() == mFrame && + mContent->mURI == mURI && + mContent->mContentType.Equals(mContentType)) { if (LOG_ENABLED()) { nsCAutoString spec; - if (ev->mURI) { - ev->mURI->GetSpec(spec); + if (mURI) { + mURI->GetSpec(spec); } LOG(("OBJLC [%p]: Handling Instantiate event: Type=<%s> URI=%p<%s>\n", - con, ev->mContentType.get(), ev->mURI.get(), spec.get())); + mContent, mContentType.get(), mURI.get(), spec.get())); } - nsresult rv = con->Instantiate(ev->mContentType, ev->mURI); + nsresult rv = mContent->Instantiate(mContentType, mURI); if (NS_FAILED(rv)) { - con->Fallback(PR_TRUE); + mContent->Fallback(PR_TRUE); } } else { - LOG(("OBJLC [%p]: Discarding event, data changed\n", con)); + LOG(("OBJLC [%p]: Discarding event, data changed\n", mContent)); } - return nsnull; -} -/* static */ void PR_CALLBACK -nsAsyncInstantiateEvent::CleanupEvent(PLEvent* event) -{ - nsAsyncInstantiateEvent* ev = NS_STATIC_CAST(nsAsyncInstantiateEvent*, - event); - delete ev; + return NS_OK; } /** - * A PLEvent for firing PluginNotFound DOM Events. + * A task for firing PluginNotFound DOM Events. */ -struct nsPluginNotFoundEvent : public PLEvent { +class nsPluginNotFoundEvent : public nsRunnable { +public: + nsCOMPtr mContent; + nsPluginNotFoundEvent(nsIContent* aContent) - { - NS_ADDREF(aContent); - PL_InitEvent(this, aContent, nsPluginNotFoundEvent::HandleEvent, - nsPluginNotFoundEvent::CleanupEvent); - } + : mContent(aContent) + {} - ~nsPluginNotFoundEvent() - { - nsIContent* con = NS_STATIC_CAST(nsIContent*, PL_GetEventOwner(this)); - NS_RELEASE(con); - } + ~nsPluginNotFoundEvent() {} - static EventHandlerFunc HandleEvent; - static EventDestructorFunc CleanupEvent; + NS_IMETHOD Run(); }; -/* static */ void* PR_CALLBACK -nsPluginNotFoundEvent::HandleEvent(PLEvent* event) +NS_IMETHODIMP +nsPluginNotFoundEvent::Run() { - nsIContent* con = NS_STATIC_CAST(nsIContent*, PL_GetEventOwner(event)); - - LOG(("OBJLC []: Firing plugin not found event for content %p\n", con)); - nsContentUtils::DispatchTrustedEvent(con->GetDocument(), con, + LOG(("OBJLC []: Firing plugin not found event for content %p\n", + mContent.get())); + nsContentUtils::DispatchTrustedEvent(mContent->GetDocument(), mContent, NS_LITERAL_STRING("PluginNotFound"), PR_TRUE, PR_TRUE); - return nsnull; + return NS_OK; } -/* static */ void PR_CALLBACK -nsPluginNotFoundEvent::CleanupEvent(PLEvent* event) -{ - nsPluginNotFoundEvent* ev = NS_STATIC_CAST(nsPluginNotFoundEvent*, - event); - delete ev; -} - - class AutoNotifier { public: AutoNotifier(nsObjectLoadingContent* aContent, PRBool aNotify) : @@ -542,11 +507,9 @@ nsObjectLoadingContent::EnsureInstantiation(nsIPluginInstance** aInstance) if (frame) { // If we have a frame, we may have pending instantiate events; revoke // them. - nsCOMPtr eventQ; - NS_GetCurrentEventQ(getter_AddRefs(eventQ)); - if (eventQ) { - LOG(("OBJLC [%p]: Revoking events\n", this)); - eventQ->RevokeEvents(this); + if (mPendingInstantiateEvent) { + LOG(("OBJLC [%p]: Revoking pending instantiate event\n", this)); + mPendingInstantiateEvent = nsnull; } } else { // mInstantiating is true if we're in LoadObject; we shouldn't @@ -600,7 +563,8 @@ nsObjectLoadingContent::HasNewFrame(nsIObjectFrame* aFrame) { LOG(("OBJLC [%p]: Got frame %p (mInstantiating=%i)\n", this, aFrame, mInstantiating)); - if (!mInstantiating && aFrame && mType == eType_Plugin) { + if (!mInstantiating && aFrame && mType == eType_Plugin && + !mPendingInstantiateEvent) { // Asynchronously call Instantiate // This can go away once plugin loading moves to content // This must be done asynchronously to ensure that the frame is correctly @@ -613,23 +577,17 @@ nsObjectLoadingContent::HasNewFrame(nsIObjectFrame* aFrame) return NS_OK; } - nsCOMPtr eventQ; - NS_GetCurrentEventQ(getter_AddRefs(eventQ)); - if (!eventQ) { - return NS_ERROR_UNEXPECTED; - } - - nsAsyncInstantiateEvent* ev = new nsAsyncInstantiateEvent(this, aFrame, - mContentType, - mURI); - if (!ev) { + mPendingInstantiateEvent = new nsAsyncInstantiateEvent(this, aFrame, + mContentType, mURI); + if (!mPendingInstantiateEvent) { return NS_ERROR_OUT_OF_MEMORY; } - LOG((" posting event\n")); - nsresult rv = eventQ->PostEvent(ev); + LOG((" dispatching event\n")); + nsresult rv = NS_DispatchToCurrentThread(mPendingInstantiateEvent); if (NS_FAILED(rv)) { - PL_DestroyEvent(ev); + NS_NOTREACHED("failed to dispatch nsAsyncInstantiateEvent"); + mPendingInstantiateEvent = nsnull; // break cycle } } return NS_OK; @@ -751,13 +709,9 @@ nsObjectLoadingContent::LoadObject(nsIURI* aURI, } // Need to revoke any potentially pending instantiate events - if (mType == eType_Plugin) { - nsCOMPtr eventQ; - NS_GetCurrentEventQ(getter_AddRefs(eventQ)); - if (eventQ) { - LOG(("OBJLC [%p]: Revoking events\n", this)); - eventQ->RevokeEvents(this); - } + if (mType == eType_Plugin && mPendingInstantiateEvent) { + LOG(("OBJLC [%p]: Revoking pending instantiate event\n", this)); + mPendingInstantiateEvent = nsnull; } AutoNotifier notifier(this, aNotify); @@ -1195,22 +1149,13 @@ nsObjectLoadingContent::NotifyStateChanged(ObjectType aOldType, /* static */ void nsObjectLoadingContent::FirePluginNotFound(nsIContent* thisContent) { - nsCOMPtr eventQ; - NS_GetCurrentEventQ(getter_AddRefs(eventQ)); - if (!eventQ) { - return; - } - - nsPluginNotFoundEvent* ev = new nsPluginNotFoundEvent(thisContent); - if (!ev) { - return; - } - - LOG(("OBJLC []: Posting PluginNotFound event for content %p\n", + LOG(("OBJLC []: Dispatching PluginNotFound event for content %p\n", thisContent)); - nsresult rv = eventQ->PostEvent(ev); + + nsCOMPtr ev = new nsPluginNotFoundEvent(thisContent); + nsresult rv = NS_DispatchToCurrentThread(ev); if (NS_FAILED(rv)) { - PL_DestroyEvent(ev); + NS_WARNING("failed to dispatch nsPluginNotFoundEvent"); } } @@ -1223,8 +1168,8 @@ nsObjectLoadingContent::GetTypeOfContent(const nsCString& aMIMEType) return eType_Image; } - PRBool isSVG = aMIMEType.LowerCaseEqualsLiteral("image/svg+xml"); #ifdef MOZ_SVG + PRBool isSVG = aMIMEType.LowerCaseEqualsLiteral("image/svg+xml"); PRBool supportedSVG = isSVG && (caps & eSupportSVG); #else PRBool supportedSVG = PR_FALSE; diff --git a/mozilla/content/base/src/nsObjectLoadingContent.h b/mozilla/content/base/src/nsObjectLoadingContent.h index b20a0a32dd5..42b947dce0d 100644 --- a/mozilla/content/base/src/nsObjectLoadingContent.h +++ b/mozilla/content/base/src/nsObjectLoadingContent.h @@ -45,6 +45,7 @@ #include "nsIInterfaceRequestor.h" #include "nsIChannelEventSink.h" #include "nsIObjectLoadingContent.h" +#include "nsIRunnable.h" #include "nsWeakReference.h" @@ -301,6 +302,11 @@ class nsObjectLoadingContent : public nsImageLoadingContent */ nsCOMPtr mFrameLoader; + /** + * A pending nsAsyncInstantiateEvent (may be null). + */ + nsCOMPtr mPendingInstantiateEvent; + /** * The content type of the resource we were last asked to load. */ diff --git a/mozilla/content/base/src/nsSyncLoadService.cpp b/mozilla/content/base/src/nsSyncLoadService.cpp index 7f1f6367550..0095a2cb184 100644 --- a/mozilla/content/base/src/nsSyncLoadService.cpp +++ b/mozilla/content/base/src/nsSyncLoadService.cpp @@ -51,13 +51,13 @@ #include "nsIDOMElement.h" #include "nsIDOMDOMImplementation.h" #include "nsIDOMEventReceiver.h" -#include "nsIEventQueueService.h" #include "nsIJSContextStack.h" #include "nsIPrivateDOMImplementation.h" #include "nsIScriptGlobalObject.h" #include "nsIScriptSecurityManager.h" #include "nsContentCID.h" #include "nsContentUtils.h" +#include "nsThreadUtils.h" #include "nsNetUtil.h" #include "nsIHttpChannel.h" #include "nsIScriptLoader.h" @@ -409,42 +409,24 @@ nsSyncLoader::LoadDocument(nsIChannel* aChannel, nsresult nsSyncLoader::PushAsyncStream(nsIStreamListener* aListener) { - nsresult rv = NS_OK; - - // Set up a new eventqueue - nsCOMPtr service = - do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr currentThreadQ; - rv = service->PushThreadEventQueue(getter_AddRefs(currentThreadQ)); - NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr thread = do_GetCurrentThread(); + NS_ENSURE_STATE(thread); // Hook us up to listen to redirects and the like mChannel->SetNotificationCallbacks(this); // Start reading from the channel - rv = mChannel->AsyncOpen(aListener, nsnull); + nsresult rv = mChannel->AsyncOpen(aListener, nsnull); if (NS_SUCCEEDED(rv)) { - mLoading = PR_TRUE; - // process events until we're finished. - PLEvent *event; - while (mLoading && NS_SUCCEEDED(rv)) { - rv = currentThreadQ->WaitForEvent(&event); - NS_ASSERTION(NS_SUCCEEDED(rv), ": currentThreadQ->WaitForEvent failed...\n"); - if (NS_SUCCEEDED(rv)) { - rv = currentThreadQ->HandleEvent(event); - NS_ASSERTION(NS_SUCCEEDED(rv), ": currentThreadQ->HandleEvent failed...\n"); - } - } + mLoading = PR_TRUE; + while (mLoading && NS_SUCCEEDED(rv)) + rv = thread->ProcessNextEvent(); } // Note that if AsyncOpen failed that's ok -- the only caller of // this method nulls out mChannel immediately after we return. - - service->PopThreadEventQueue(currentThreadQ); return rv; } diff --git a/mozilla/content/events/public/nsPLDOMEvent.h b/mozilla/content/events/public/nsPLDOMEvent.h index ce4c58a348a..0d3c855536c 100644 --- a/mozilla/content/events/public/nsPLDOMEvent.h +++ b/mozilla/content/events/public/nsPLDOMEvent.h @@ -39,7 +39,7 @@ #define nsPLDOMEvent_h___ #include "nsCOMPtr.h" -#include "plevent.h" +#include "nsThreadUtils.h" #include "nsIDOMNode.h" #include "nsString.h" /** @@ -49,19 +49,17 @@ * the wrong time, in order to avoid resulting instability. */ -struct nsPLDOMEvent : public PLEvent { +class nsPLDOMEvent : public nsRunnable { +public: nsPLDOMEvent (nsIDOMNode *aEventNode, const nsAString& aEventType) : mEventNode(aEventNode), mEventType(aEventType) { } - void HandleEvent(); + NS_IMETHOD Run(); nsresult PostDOMEvent(); nsCOMPtr mEventNode; nsString mEventType; }; -static void* PR_CALLBACK HandlePLDOMEvent(PLEvent* aEvent); -static void PR_CALLBACK DestroyPLDOMEvent(PLEvent* aEvent); - #endif diff --git a/mozilla/content/events/src/nsPLDOMEvent.cpp b/mozilla/content/events/src/nsPLDOMEvent.cpp index 2615c435aa3..1ecf0acf018 100644 --- a/mozilla/content/events/src/nsPLDOMEvent.cpp +++ b/mozilla/content/events/src/nsPLDOMEvent.cpp @@ -36,17 +36,16 @@ * ***** END LICENSE BLOCK ***** */ #include "nsPLDOMEvent.h" -#include "nsEventQueueUtils.h" #include "nsIDOMEvent.h" #include "nsIPrivateDOMEvent.h" #include "nsIDOMDocument.h" #include "nsIDOMDocumentEvent.h" #include "nsIDOMEventTarget.h" -void nsPLDOMEvent::HandleEvent() +NS_IMETHODIMP nsPLDOMEvent::Run() { if (!mEventNode) { - return; + return NS_OK; } nsCOMPtr domDoc; @@ -66,29 +65,11 @@ void nsPLDOMEvent::HandleEvent() target->DispatchEvent(domEvent, &defaultActionEnabled); } } + + return NS_OK; } nsresult nsPLDOMEvent::PostDOMEvent() { - nsCOMPtr eventQueue; - nsresult rv = NS_GetCurrentEventQ(getter_AddRefs(eventQueue)); - if (NS_SUCCEEDED(rv)) { - PL_InitEvent(this, nsnull, ::HandlePLDOMEvent, ::DestroyPLDOMEvent); - rv = eventQueue->PostEvent(this); - } - - return rv; -} - -static void* PR_CALLBACK HandlePLDOMEvent(PLEvent* aEvent) -{ - nsPLDOMEvent* event = NS_STATIC_CAST(nsPLDOMEvent*, aEvent); - event->HandleEvent(); - return nsnull; -} - -static void PR_CALLBACK DestroyPLDOMEvent(PLEvent* aEvent) -{ - nsPLDOMEvent* event = NS_STATIC_CAST(nsPLDOMEvent*, aEvent); - delete event; + return NS_DispatchToCurrentThread(this); } diff --git a/mozilla/content/html/document/src/nsHTMLContentSink.cpp b/mozilla/content/html/document/src/nsHTMLContentSink.cpp index a2c7344c90c..e8b3c8ff689 100644 --- a/mozilla/content/html/document/src/nsHTMLContentSink.cpp +++ b/mozilla/content/html/document/src/nsHTMLContentSink.cpp @@ -58,6 +58,8 @@ #include "nsIMarkupDocumentViewer.h" #include "nsINodeInfo.h" #include "nsHTMLTokens.h" +#include "nsIAppShell.h" +#include "nsWidgetsCID.h" #include "nsCRT.h" #include "prtime.h" #include "prlog.h" @@ -118,7 +120,6 @@ #include "nsIPrompt.h" #include "nsLayoutCID.h" #include "nsIDocShellTreeItem.h" -#include "plevent.h" #include "nsEscape.h" #include "nsIElementObserver.h" @@ -127,6 +128,17 @@ //---------------------------------------------------------------------- +static void +FavorPerformanceHint(PRBool perfOverStarvation, PRUint32 starvationDelay) +{ + static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID); + nsCOMPtr appShell = do_GetService(kAppShellCID); + if (appShell) + appShell->FavorPerformanceHint(perfOverStarvation, starvationDelay); +} + +//---------------------------------------------------------------------- + #ifdef NS_DEBUG static PRLogModuleInfo* gSinkLogModuleInfo; @@ -2311,7 +2323,7 @@ HTMLContentSink::DidBuildModel(void) if (mFlags & NS_SINK_FLAG_DYNAMIC_LOWER_VALUE) { // Reset the performance hint which was set to FALSE // when NS_SINK_FLAG_DYNAMIC_LOWER_VALUE was set. - PL_FavorPerformanceHint(PR_TRUE , 0); + FavorPerformanceHint(PR_TRUE , 0); } if (mFlags & NS_SINK_FLAG_CAN_INTERRUPT_PARSER) { @@ -3433,7 +3445,7 @@ HTMLContentSink::DidProcessAToken(void) // Set the performance hint to prevent event starvation when // dispatching PLEvents. This improves application responsiveness // during page loads. - PL_FavorPerformanceHint(PR_FALSE, 0); + FavorPerformanceHint(PR_FALSE, 0); } } else { @@ -3443,7 +3455,7 @@ HTMLContentSink::DidProcessAToken(void) // to favor overall page load speed over responsiveness. mFlags &= ~NS_SINK_FLAG_DYNAMIC_LOWER_VALUE; // Reset the hint that to favoring performance for PLEvent dispatch. - PL_FavorPerformanceHint(PR_TRUE, 0); + FavorPerformanceHint(PR_TRUE, 0); } } diff --git a/mozilla/content/xml/document/src/nsXMLDocument.cpp b/mozilla/content/xml/document/src/nsXMLDocument.cpp index f002e112198..48268d55c81 100644 --- a/mozilla/content/xml/document/src/nsXMLDocument.cpp +++ b/mozilla/content/xml/document/src/nsXMLDocument.cpp @@ -81,6 +81,7 @@ #include "nsMimeTypes.h" #include "nsIEventListenerManager.h" #include "nsContentUtils.h" +#include "nsThreadUtils.h" #include "nsJSUtils.h" #include "nsCRT.h" #include "nsIWindowWatcher.h" @@ -96,7 +97,6 @@ static const char kLoadAsData[] = "loadAsData"; -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); static NS_DEFINE_CID(kCharsetAliasCID, NS_CHARSETALIAS_CID); @@ -217,8 +217,6 @@ nsXMLDocument::Init() nsresult rv = nsDocument::Init(); NS_ENSURE_SUCCESS(rv, rv); - mEventQService = do_GetService(kEventQueueServiceCID, &rv); - return rv; } @@ -499,17 +497,6 @@ nsXMLDocument::Load(const nsAString& aUrl, PRBool *aReturn) SetPrincipal(principal); - nsCOMPtr modalEventQueue; - - if(!mAsync) { - NS_ENSURE_TRUE(mEventQService, NS_ERROR_FAILURE); - - rv = mEventQService->PushThreadEventQueue(getter_AddRefs(modalEventQueue)); - if (NS_FAILED(rv)) { - return rv; - } - } - // Prepare for loading the XML document "into oneself" nsCOMPtr listener; if (NS_FAILED(rv = StartDocumentLoad(kLoadAsData, channel, @@ -517,9 +504,6 @@ nsXMLDocument::Load(const nsAString& aUrl, PRBool *aReturn) getter_AddRefs(listener), PR_FALSE))) { NS_ERROR("nsXMLDocument::Load: Failed to start the document load."); - if (modalEventQueue) { - mEventQService->PopThreadEventQueue(modalEventQueue); - } return rv; } @@ -530,21 +514,17 @@ nsXMLDocument::Load(const nsAString& aUrl, PRBool *aReturn) rv = channel->AsyncOpen(listener, nsnull); if (NS_FAILED(rv)) { mChannelIsPending = PR_FALSE; - if (modalEventQueue) { - mEventQService->PopThreadEventQueue(modalEventQueue); - } return rv; } if (!mAsync) { + nsCOMPtr thread = do_GetCurrentThread(); + mLoopingForSyncLoad = PR_TRUE; - - while (mLoopingForSyncLoad) { - modalEventQueue->ProcessPendingEvents(); + while (mLoopingForSyncLoad && NS_SUCCEEDED(rv)) { + rv = thread->ProcessNextEvent(); } - mEventQService->PopThreadEventQueue(modalEventQueue); - // We set return to true unless there was a parsing error nsCOMPtr node = do_QueryInterface(mRootContent); if (node) { diff --git a/mozilla/content/xml/document/src/nsXMLDocument.h b/mozilla/content/xml/document/src/nsXMLDocument.h index 1bbdb80f19e..1c328b44a96 100644 --- a/mozilla/content/xml/document/src/nsXMLDocument.h +++ b/mozilla/content/xml/document/src/nsXMLDocument.h @@ -46,7 +46,6 @@ #include "nsIScriptContext.h" #include "nsHTMLStyleSheet.h" #include "nsIHTMLCSSStyleSheet.h" -#include "nsIEventQueueService.h" class nsIParser; class nsIDOMNode; @@ -98,8 +97,6 @@ public: protected: virtual nsresult GetLoadGroup(nsILoadGroup **aLoadGroup); - nsCOMPtr mEventQService; - nsCOMPtr mScriptContext; // mChannelIsPending indicates whether we're currently asynchronously loading diff --git a/mozilla/content/xslt/src/xslt/txMozillaXSLTProcessor.cpp b/mozilla/content/xslt/src/xslt/txMozillaXSLTProcessor.cpp index 0ef37df35e0..2e4c8e33a64 100644 --- a/mozilla/content/xslt/src/xslt/txMozillaXSLTProcessor.cpp +++ b/mozilla/content/xslt/src/xslt/txMozillaXSLTProcessor.cpp @@ -63,8 +63,8 @@ #include "txUnknownHandler.h" #include "txXSLTProcessor.h" #include "nsIPrincipal.h" +#include "nsThreadUtils.h" #include "jsapi.h" -#include "nsIEventQueueService.h" static NS_DEFINE_CID(kXMLDocumentCID, NS_XMLDOCUMENT_CID); @@ -323,30 +323,27 @@ txMozillaXSLTProcessor::SetSourceContentModel(nsIDOMNode* aSourceDOM) return NS_OK; } -PR_BEGIN_EXTERN_C -void* PR_CALLBACK -HandleTransformBlockerEvent(PLEvent *aEvent) -{ - txMozillaXSLTProcessor *processor = - NS_STATIC_CAST(txMozillaXSLTProcessor*, aEvent->owner); - processor->TransformToDoc(nsnull, nsnull); +class nsTransformBlockerEvent : public nsRunnable { +public: + nsRefPtr mProcessor; - return nsnull; -} + nsTransformBlockerEvent(txMozillaXSLTProcessor *processor) + : mProcessor(processor) + {} -void PR_CALLBACK -DestroyTransformBlockerEvent(PLEvent *aEvent) -{ - txMozillaXSLTProcessor *processor = - NS_STATIC_CAST(txMozillaXSLTProcessor*, aEvent->owner); + ~nsTransformBlockerEvent() + { nsCOMPtr document = - do_QueryInterface(processor->GetSourceContentModel()); + do_QueryInterface(mProcessor->GetSourceContentModel()); document->UnblockOnload(PR_TRUE); + } - NS_RELEASE(processor); - delete aEvent; -} -PR_END_EXTERN_C + NS_IMETHOD Run() + { + mProcessor->TransformToDoc(nsnull, nsnull); + return NS_OK; + } +}; nsresult txMozillaXSLTProcessor::DoTransform() @@ -354,39 +351,24 @@ txMozillaXSLTProcessor::DoTransform() NS_ENSURE_TRUE(mSource, NS_ERROR_UNEXPECTED); NS_ENSURE_TRUE(mStylesheet, NS_ERROR_UNEXPECTED); NS_ASSERTION(mObserver, "no observer"); + NS_ASSERTION(NS_IsMainThread(), "should only be on main thread"); nsresult rv; nsCOMPtr document = do_QueryInterface(mSource, &rv); NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr service = - do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr eventQ; - rv = service->GetSpecialEventQueue(nsIEventQueueService::UI_THREAD_EVENT_QUEUE, - getter_AddRefs(eventQ)); - NS_ENSURE_SUCCESS(rv, rv); - - PLEvent* event = new PLEvent(); + nsCOMPtr event = new nsTransformBlockerEvent(this); if (!event) { return NS_ERROR_OUT_OF_MEMORY; } - PL_InitEvent(event, this, HandleTransformBlockerEvent, - DestroyTransformBlockerEvent); - document->BlockOnload(); - // After this point, event destruction will release |this| (in - // DestroyTransformBlockerEvent) - NS_ADDREF_THIS(); - - rv = eventQ->PostEvent(event); + rv = NS_DispatchToCurrentThread(event); if (NS_FAILED(rv)) { // XXX Maybe we should just display the source document in this case? // Also, set up context information, see bug 204655. reportError(rv, nsnull, nsnull); - PL_DestroyEvent(event); } return rv; diff --git a/mozilla/directory/xpcom/base/src/nsLDAPConnection.cpp b/mozilla/directory/xpcom/base/src/nsLDAPConnection.cpp index dd83cbcff83..8d3af07c8a0 100644 --- a/mozilla/directory/xpcom/base/src/nsLDAPConnection.cpp +++ b/mozilla/directory/xpcom/base/src/nsLDAPConnection.cpp @@ -49,13 +49,12 @@ #include "nsIComponentManager.h" #include "nsLDAPConnection.h" #include "nsLDAPMessage.h" -#include "nsIEventQueueService.h" +#include "nsThreadUtils.h" #include "nsIConsoleService.h" #include "nsIDNSService.h" #include "nsIDNSRecord.h" #include "nsIRequestObserver.h" #include "nsIProxyObjectManager.h" -#include "nsEventQueueUtils.h" #include "nsNetError.h" #include "nsLDAPOperation.h" #include "nsILDAPErrors.h" @@ -193,11 +192,10 @@ nsLDAPConnection::Init(const char *aHost, PRInt32 aPort, PRBool aSSL, return NS_ERROR_FAILURE; } - nsCOMPtr curEventQ; - rv = NS_GetCurrentEventQ(getter_AddRefs(curEventQ)); - if (NS_FAILED(rv)) { + nsCOMPtr curThread = do_GetCurrentThread(); + if (!curThread) { NS_ERROR("nsLDAPConnection::Init(): couldn't " - "get current event queue"); + "get current thread"); return NS_ERROR_FAILURE; } // Do the pre-resolve of the hostname, using the DNS service. This @@ -229,7 +227,7 @@ nsLDAPConnection::Init(const char *aHost, PRInt32 aPort, PRBool aSSL, if (spacePos != kNotFound) mDNSHost.Truncate(spacePos); - rv = pDNSService->AsyncResolve(mDNSHost, 0, this, curEventQ, + rv = pDNSService->AsyncResolve(mDNSHost, 0, this, curThread, getter_AddRefs(mDNSRequest)); if (NS_FAILED(rv)) { @@ -1023,13 +1021,13 @@ nsLDAPConnection::OnLookupComplete(nsICancelable *aRequest, mRunnable->mWeakConn = do_GetWeakReference(conn); // kick off a thread for result listening and marshalling - // XXXdmose - should this be JOINABLE? // - rv = NS_NewThread(getter_AddRefs(mThread), mRunnable, 0, - PR_UNJOINABLE_THREAD); + rv = NS_NewThread(getter_AddRefs(mThread), mRunnable); if (NS_FAILED(rv)) { rv = NS_ERROR_NOT_AVAILABLE; } + // XXX(darin): We need to shutdown this thread at some point. + // Otherwise, it will stick around until shutdown. } } diff --git a/mozilla/docshell/base/nsDocShell.cpp b/mozilla/docshell/base/nsDocShell.cpp index 966e03718b6..ceca59f619f 100644 --- a/mozilla/docshell/base/nsDocShell.cpp +++ b/mozilla/docshell/base/nsDocShell.cpp @@ -93,6 +93,8 @@ #include "nsIPrefBranch.h" #include "nsIPrefBranch2.h" #include "nsIWritablePropertyBag2.h" +#include "nsIAppShell.h" +#include "nsWidgetsCID.h" // we want to explore making the document own the load group // so we can associate the document URI with the load group. @@ -174,15 +176,14 @@ static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID); static NS_DEFINE_CID(kDocumentCharsetInfoCID, NS_DOCUMENTCHARSETINFO_CID); static NS_DEFINE_CID(kDOMScriptObjectFactoryCID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID); +static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID); #if defined(DEBUG_bryner) || defined(DEBUG_chb) //#define DEBUG_DOCSHELL_FOCUS #define DEBUG_PAGE_CACHE #endif -#include "plevent.h" -#include "nsGUIEvent.h" -#include "nsEventQueueUtils.h" +#include "nsThreadUtils.h" // Number of documents currently loading static PRInt32 gNumberOfDocumentsLoading = 0; @@ -198,7 +199,7 @@ nsIURIFixup *nsDocShell::sURIFixup = 0; // the pref on the creation of the first docshell. static PRBool gValidateOrigin = (PRBool)0xffffffff; -// Hint for native dispatch of plevents on how long to delay after +// Hint for native dispatch of events on how long to delay after // all documents have loaded in milliseconds before favoring normal // native event dispatch priorites over performance #define NS_EVENT_STARVATION_DELAY_HINT 2000 @@ -216,6 +217,14 @@ static PRLogModuleInfo* gDocShellLog; static PRLogModuleInfo* gDocShellLeakLog; #endif +static void +FavorPerformanceHint(PRBool perfOverStarvation, PRUint32 starvationDelay) +{ + nsCOMPtr appShell = do_GetService(kAppShellCID); + if (appShell) + appShell->FavorPerformanceHint(perfOverStarvation, starvationDelay); +} + //***************************************************************************** //*** nsDocShellFocusController //***************************************************************************** @@ -3173,10 +3182,7 @@ nsDocShell::Stop(PRUint32 aStopFlags) { if (nsIWebNavigation::STOP_CONTENT & aStopFlags) { // Revoke any pending plevents related to content viewer restoration - nsCOMPtr uiThreadQueue; - NS_GetMainEventQ(getter_AddRefs(uiThreadQueue)); - if (uiThreadQueue) - uiThreadQueue->RevokeEvents(this); + mWeakSelf.forget(); // Stop the document loading if (mContentViewer) @@ -4748,7 +4754,7 @@ nsDocShell::EndPageLoad(nsIWebProgress * aProgress, // over performance if (--gNumberOfDocumentsLoading == 0) { // Hint to use normal native event dispatch priorities - PL_FavorPerformanceHint(PR_FALSE, NS_EVENT_STARVATION_DELAY_HINT); + FavorPerformanceHint(PR_FALSE, NS_EVENT_STARVATION_DELAY_HINT); } } /* Check if the httpChannel has any cache-control related response headers, @@ -5033,41 +5039,22 @@ nsDocShell::CaptureState() return NS_OK; } -class RestorePresentationEvent : public PLEvent +class RestorePresentationEvent : public nsRunnable { public: - RestorePresentationEvent(nsDocShell *aShell); + RestorePresentationEvent(const nsDocShellWeakRef &aShell) + : mDocShell(aShell) + {} - nsRefPtr mDocShell; + NS_IMETHOD Run() { + if (mDocShell && NS_FAILED(mDocShell->RestoreFromHistory())) + NS_NOTREACHED("RestoreFromHistory failed"); + return NS_OK; + } + + nsDocShellWeakRef mDocShell; }; -PR_STATIC_CALLBACK(void*) -HandleRestorePresentationEvent(PLEvent *aEvent) -{ - RestorePresentationEvent *event = - NS_STATIC_CAST(RestorePresentationEvent*, aEvent); - -#ifdef NS_DEBUG - nsresult rv = -#endif - event->mDocShell->RestoreFromHistory(); - NS_ASSERTION(NS_SUCCEEDED(rv), "RestoreFromHistory failed"); - return nsnull; -} - -PR_STATIC_CALLBACK(void) -DestroyRestorePresentationEvent(PLEvent *aEvent) -{ - delete NS_STATIC_CAST(RestorePresentationEvent*, aEvent); -} - -RestorePresentationEvent::RestorePresentationEvent(nsDocShell *aShell) - : mDocShell(aShell) -{ - PL_InitEvent(this, mDocShell, ::HandleRestorePresentationEvent, - ::DestroyRestorePresentationEvent); -} - NS_IMETHODIMP nsDocShell::BeginRestore(nsIContentViewer *aContentViewer, PRBool aTop) { @@ -5229,23 +5216,20 @@ nsDocShell::RestorePresentation(nsISHEntry *aSHEntry, PRBool *aRestoring) // to the event loop. This mimics the way it is called by nsIChannel // implementations. - nsCOMPtr uiThreadQueue; - NS_GetMainEventQ(getter_AddRefs(uiThreadQueue)); - NS_ENSURE_TRUE(uiThreadQueue, NS_ERROR_UNEXPECTED); + if (!mWeakSelf) { + mWeakSelf = this; + NS_ENSURE_TRUE(mWeakSelf, NS_ERROR_OUT_OF_MEMORY); + } - PLEvent *evt = new RestorePresentationEvent(this); - NS_ENSURE_TRUE(evt, NS_ERROR_OUT_OF_MEMORY); - - nsresult rv = uiThreadQueue->PostEvent(evt); + nsCOMPtr evt = new RestorePresentationEvent(mWeakSelf); + nsresult rv = NS_DispatchToCurrentThread(evt); if (NS_SUCCEEDED(rv)) { // The rest of the restore processing will happen on our PLEvent // callback. *aRestoring = PR_TRUE; - } else { - PL_DestroyEvent(evt); } - return NS_OK; + return rv; } nsresult @@ -5454,7 +5438,7 @@ nsDocShell::RestoreFromHistory() // Tell the event loop to favor plevents over user events, see comments // in CreateContentViewer. if (++gNumberOfDocumentsLoading == 1) - PL_FavorPerformanceHint(PR_TRUE, NS_EVENT_STARVATION_DELAY_HINT); + FavorPerformanceHint(PR_TRUE, NS_EVENT_STARVATION_DELAY_HINT); if (oldMUDV && newMUDV) @@ -5697,7 +5681,7 @@ nsDocShell::CreateContentViewer(const char *aContentType, // Hint to favor performance for the plevent notification mechanism. // We want the pages to load as fast as possible even if its means // native messages might be starved. - PL_FavorPerformanceHint(PR_TRUE, NS_EVENT_STARVATION_DELAY_HINT); + FavorPerformanceHint(PR_TRUE, NS_EVENT_STARVATION_DELAY_HINT); } if (onLocationChangeNeeded) { diff --git a/mozilla/docshell/base/nsDocShell.h b/mozilla/docshell/base/nsDocShell.h index 23afe758f5d..18466dfc7e6 100644 --- a/mozilla/docshell/base/nsDocShell.h +++ b/mozilla/docshell/base/nsDocShell.h @@ -72,6 +72,7 @@ #include "nsPoint.h" // mCurrent/mDefaultScrollbarPreferences #include "nsString.h" #include "nsAutoPtr.h" +#include "nsTWeakRef.h" // Threshold value in ms for META refresh based redirects #define REFRESH_REDIRECT_TIMER 15000 @@ -105,6 +106,8 @@ #include "nsIObserver.h" #include "nsDocShellLoadTypes.h" +typedef nsTWeakRef nsDocShellWeakRef; + /* load commands were moved to nsIDocShell.h */ /* load types were moved to nsDocShellLoadTypes.h */ @@ -542,6 +545,11 @@ protected: // Somebody give me better name nsCOMPtr mLSHE; + // Holds a weak reference to ourselves that RestorePresentationEvent objects + // will use to reference us. We can sever this weak ref at any time to + // effectively "revoke" any pending RestorePresentationEvent objects. + nsDocShellWeakRef mWeakSelf; + // Index into the SHTransaction list, indicating the previous and current // transaction at the time that this DocShell begins to load PRInt32 mPreviousTransIndex; diff --git a/mozilla/docshell/base/nsWebShell.cpp b/mozilla/docshell/base/nsWebShell.cpp index 90e019ff7f9..b07324a8c0e 100644 --- a/mozilla/docshell/base/nsWebShell.cpp +++ b/mozilla/docshell/base/nsWebShell.cpp @@ -56,12 +56,10 @@ #include "nsIDOMEvent.h" #include "nsPresContext.h" #include "nsIComponentManager.h" -#include "nsIEventQueueService.h" #include "nsCRT.h" #include "nsVoidArray.h" #include "nsString.h" #include "nsReadableUtils.h" -#include "plevent.h" #include "prprf.h" #include "nsIPluginHost.h" #include "nsplugin.h" @@ -105,6 +103,7 @@ #include "nsIUploadChannel.h" #include "nsISeekableStream.h" #include "nsStreamUtils.h" +#include "nsThreadUtils.h" #include "nsILocaleService.h" #include "nsIStringBundle.h" @@ -407,7 +406,6 @@ nsWebShell::nsWebShell() : nsDocShell() printf("++WEBSHELL %p == %ld\n", this, gNumberOfWebShells); #endif - mThread = nsnull; InitFrameData(); mItemType = typeContent; mCharsetReloadState = eCharsetReloadInit; @@ -565,14 +563,14 @@ nsWebShell::SetRendering(PRBool aRender) // WebShell link handling -struct OnLinkClickEvent : public PLEvent { +struct OnLinkClickEvent : public nsRunnable { OnLinkClickEvent(nsWebShell* aHandler, nsIContent* aContent, nsLinkVerb aVerb, nsIURI* aURI, - const PRUnichar* aTargetSpec, nsIInputStream* aPostDataStream = 0, + const PRUnichar* aTargetSpec, + nsIInputStream* aPostDataStream = 0, nsIInputStream* aHeadersDataStream = 0); - ~OnLinkClickEvent(); - void HandleEvent() { + NS_IMETHOD Run() { nsCOMPtr window(do_QueryInterface(mHandler->mScriptGlobal)); nsAutoPopupStatePusher popupStatePusher(window, mPopupState); @@ -580,9 +578,10 @@ struct OnLinkClickEvent : public PLEvent { mTargetSpec.get(), mPostDataStream, mHeadersDataStream, nsnull, nsnull); + return NS_OK; } - nsWebShell* mHandler; + nsRefPtr mHandler; nsCOMPtr mURI; nsString mTargetSpec; nsCOMPtr mPostDataStream; @@ -592,19 +591,6 @@ struct OnLinkClickEvent : public PLEvent { PopupControlState mPopupState; }; -static void* PR_CALLBACK HandlePLEvent(PLEvent* aEvent) -{ - OnLinkClickEvent* event = NS_STATIC_CAST(OnLinkClickEvent*, aEvent); - event->HandleEvent(); - return nsnull; -} - -static void PR_CALLBACK DestroyPLEvent(PLEvent* aEvent) -{ - OnLinkClickEvent* event = NS_STATIC_CAST(OnLinkClickEvent*, aEvent); - delete event; -} - OnLinkClickEvent::OnLinkClickEvent(nsWebShell* aHandler, nsIContent *aContent, nsLinkVerb aVerb, @@ -612,32 +598,17 @@ OnLinkClickEvent::OnLinkClickEvent(nsWebShell* aHandler, const PRUnichar* aTargetSpec, nsIInputStream* aPostDataStream, nsIInputStream* aHeadersDataStream) + : mHandler(aHandler) + , mURI(aURI) + , mTargetSpec(aTargetSpec) + , mPostDataStream(aPostDataStream) + , mHeadersDataStream(aHeadersDataStream) + , mContent(aContent) + , mVerb(aVerb) { - mHandler = aHandler; - NS_ADDREF(aHandler); - mURI = aURI; - mTargetSpec.Assign(aTargetSpec); - mPostDataStream = aPostDataStream; - mHeadersDataStream = aHeadersDataStream; - mContent = aContent; - mVerb = aVerb; - nsCOMPtr window(do_QueryInterface(mHandler->mScriptGlobal)); mPopupState = window->GetPopupControlState(); - - PL_InitEvent(this, nsnull, ::HandlePLEvent, ::DestroyPLEvent); - - nsCOMPtr eventQueue; - aHandler->GetEventQueue(getter_AddRefs(eventQueue)); - NS_ASSERTION(eventQueue, "no event queue"); - if (eventQueue) - eventQueue->PostEvent(this); -} - -OnLinkClickEvent::~OnLinkClickEvent() -{ - NS_IF_RELEASE(mHandler); } //---------------------------------------- @@ -650,26 +621,10 @@ nsWebShell::OnLinkClick(nsIContent* aContent, nsIInputStream* aPostDataStream, nsIInputStream* aHeadersDataStream) { - OnLinkClickEvent* ev; - - ev = new OnLinkClickEvent(this, aContent, aVerb, aURI, - aTargetSpec, aPostDataStream, aHeadersDataStream); - if (!ev) { - return NS_ERROR_OUT_OF_MEMORY; - } - return NS_OK; -} - -nsresult -nsWebShell::GetEventQueue(nsIEventQueue **aQueue) -{ - NS_ENSURE_ARG_POINTER(aQueue); - *aQueue = 0; - - nsCOMPtr eventService(do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID)); - if (eventService) - eventService->GetThreadEventQueue(mThread, aQueue); - return *aQueue ? NS_OK : NS_ERROR_FAILURE; + nsCOMPtr ev = + new OnLinkClickEvent(this, aContent, aVerb, aURI, aTargetSpec, + aPostDataStream, aHeadersDataStream); + return NS_DispatchToCurrentThread(ev); } NS_IMETHODIMP @@ -1391,14 +1346,6 @@ NS_IMETHODIMP nsWebShell::Create() return NS_OK; } - // Remember the current thread (in current and forseeable implementations, - // it'll just be the unique UI thread) - // - // Since this call must be made on the UI thread, we know the Event Queue - // will be associated with the current thread... - // - mThread = PR_GetCurrentThread(); - WEB_TRACE(WEB_TRACE_CALLS, ("nsWebShell::Init: this=%p", this)); diff --git a/mozilla/docshell/base/nsWebShell.h b/mozilla/docshell/base/nsWebShell.h index ab07eced579..97a98397880 100644 --- a/mozilla/docshell/base/nsWebShell.h +++ b/mozilla/docshell/base/nsWebShell.h @@ -47,7 +47,6 @@ #include "nsIIOService.h" #include "nsCRT.h" -class nsIEventQueue; class nsIController; struct PRThread; struct OnLinkClickEvent; @@ -103,9 +102,6 @@ public: NS_IMETHOD Create(); - // nsWebShell - nsresult GetEventQueue(nsIEventQueue **aQueue); - static nsEventStatus PR_CALLBACK HandleEvent(nsGUIEvent *aEvent); // NS_IMETHOD SetURL(const PRUnichar* aURL); @@ -129,8 +125,6 @@ protected: nsIChannel* channel, nsresult aStatus); - PRThread *mThread; - eCharsetReloadState mCharsetReloadState; nsresult CreateViewer(nsIRequest* request, diff --git a/mozilla/docshell/shistory/src/nsSHEntry.cpp b/mozilla/docshell/shistory/src/nsSHEntry.cpp index 3f6741ce367..f86ed837798 100644 --- a/mozilla/docshell/shistory/src/nsSHEntry.cpp +++ b/mozilla/docshell/shistory/src/nsSHEntry.cpp @@ -49,10 +49,8 @@ #include "nsIDocShellTreeItem.h" #include "nsIDocument.h" #include "nsIDOMDocument.h" -#include "plevent.h" #include "nsAutoPtr.h" -#include "nsIEventQueue.h" -#include "nsEventQueueUtils.h" +#include "nsThreadUtils.h" static PRUint32 gEntryID = 0; @@ -686,63 +684,39 @@ nsSHEntry::ContentRemoved(nsIDocument* aDocument, DocumentMutated(); } -class DestroyViewerEvent : public PLEvent +class DestroyViewerEvent : public nsRunnable { public: - DestroyViewerEvent(nsIContentViewer* aViewer, nsIDocument* aDocument); + DestroyViewerEvent(nsIContentViewer* aViewer, nsIDocument* aDocument) + : mViewer(aViewer), + mDocument(aDocument) + {} + + NS_IMETHOD Run() + { + if (mViewer) + mViewer->Destroy(); + return NS_OK; + } nsCOMPtr mViewer; nsCOMPtr mDocument; }; -PR_STATIC_CALLBACK(void*) -HandleDestroyViewerEvent(PLEvent *aEvent) -{ - nsIContentViewer* viewer = NS_STATIC_CAST(DestroyViewerEvent*, aEvent)->mViewer; - if (viewer) { - viewer->Destroy(); - } - - return nsnull; -} - -PR_STATIC_CALLBACK(void) -DestroyDestroyViewerEvent(PLEvent *aEvent) -{ - delete NS_STATIC_CAST(DestroyViewerEvent*, aEvent); -} - -DestroyViewerEvent::DestroyViewerEvent(nsIContentViewer* aViewer, - nsIDocument* aDocument) - : mViewer(aViewer), - mDocument(aDocument) -{ - PL_InitEvent(this, mViewer, ::HandleDestroyViewerEvent, - ::DestroyDestroyViewerEvent); -} - void nsSHEntry::DocumentMutated() { NS_ASSERTION(mContentViewer && mDocument, "we shouldn't still be observing the doc"); - // Release the reference to the contentviewer asynconously so that the + // Release the reference to the contentviewer asynchronously so that the // document doesn't get nuked mid-mutation. - nsCOMPtr uiThreadQueue; - NS_GetMainEventQ(getter_AddRefs(uiThreadQueue)); - if (!uiThreadQueue) { - return; - } - PLEvent *evt = new DestroyViewerEvent(mContentViewer, mDocument); - if (!evt) { - return; - } - - nsresult rv = uiThreadQueue->PostEvent(evt); + nsCOMPtr evt = + new DestroyViewerEvent(mContentViewer, mDocument); + nsresult rv = NS_DispatchToCurrentThread(evt); if (NS_FAILED(rv)) { - PL_DestroyEvent(evt); + NS_WARNING("failed to dispatch DestroyViewerEvent"); } else { // Drop presentation. Also ensures that we don't post more then one diff --git a/mozilla/dom/src/base/nsGlobalWindow.cpp b/mozilla/dom/src/base/nsGlobalWindow.cpp index 4d966a32dd2..0ecb2067fb8 100644 --- a/mozilla/dom/src/base/nsGlobalWindow.cpp +++ b/mozilla/dom/src/base/nsGlobalWindow.cpp @@ -94,7 +94,7 @@ #include "nsIDOMPkcs11.h" #include "nsDOMString.h" #include "nsIEmbeddingSiteWindow2.h" -#include "nsIEventQueueService.h" +#include "nsThreadUtils.h" #include "nsIEventStateManager.h" #include "nsIHttpProtocolHandler.h" #include "nsIJSContextStack.h" @@ -280,7 +280,6 @@ PRInt32 gTimeoutCnt = 0; PR_END_MACRO // CIDs -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); #ifdef OJI static NS_DEFINE_CID(kJVMServiceCID, NS_JVMMANAGER_CID); #endif @@ -4207,51 +4206,22 @@ nsGlobalWindow::GetFrames(nsIDOMWindow** aFrames) return NS_OK; } -struct nsCloseEvent : public PLEvent { +class nsCloseEvent : public nsRunnable { +public: nsCloseEvent (nsGlobalWindow *aWindow) : mWindow(aWindow) { } - void HandleEvent() { + NS_IMETHOD Run() { if (mWindow) mWindow->ReallyCloseWindow(); + return NS_OK; } - nsresult PostCloseEvent(); - nsRefPtr mWindow; }; -static void* PR_CALLBACK HandleCloseEvent(PLEvent* aEvent) -{ - nsCloseEvent *event = NS_STATIC_CAST(nsCloseEvent*, aEvent); - event->HandleEvent(); - return nsnull; -} -static void PR_CALLBACK DestroyCloseEvent(PLEvent* aEvent) -{ - nsCloseEvent *event = NS_STATIC_CAST(nsCloseEvent*, aEvent); - delete event; -} - -nsresult -nsCloseEvent::PostCloseEvent() -{ - nsCOMPtr eventService(do_GetService(kEventQueueServiceCID)); - if (eventService) { - nsCOMPtr eventQueue; - eventService->GetThreadEventQueue(PR_GetCurrentThread(), getter_AddRefs(eventQueue)); - if (eventQueue) { - - PL_InitEvent(this, nsnull, ::HandleCloseEvent, ::DestroyCloseEvent); - return eventQueue->PostEvent(this); - } - } - - return NS_ERROR_FAILURE; -} - NS_IMETHODIMP nsGlobalWindow::Close() { @@ -4377,15 +4347,8 @@ nsGlobalWindow::Close() // to really close the window. rv = NS_ERROR_FAILURE; if (!IsCallerChrome()) { - nsCloseEvent *ev = new nsCloseEvent(this); - - if (ev) { - rv = ev->PostCloseEvent(); - - if (NS_FAILED(rv)) { - PL_DestroyEvent(ev); - } - } else rv = NS_ERROR_OUT_OF_MEMORY; + nsRefPtr ev = new nsCloseEvent(this); + rv = NS_DispatchToCurrentThread(ev); } if (NS_FAILED(rv)) { diff --git a/mozilla/dom/src/base/nsJSEnvironment.cpp b/mozilla/dom/src/base/nsJSEnvironment.cpp index 75dab77db89..fff38990a88 100644 --- a/mozilla/dom/src/base/nsJSEnvironment.cpp +++ b/mozilla/dom/src/base/nsJSEnvironment.cpp @@ -72,7 +72,7 @@ #include "nsIObserverService.h" #include "nsGUIEvent.h" #include "nsScriptNameSpaceManager.h" -#include "nsIThread.h" +#include "nsThreadUtils.h" #include "nsITimer.h" #include "nsDOMClassInfo.h" #include "nsIAtom.h" @@ -143,8 +143,6 @@ static const char kJSRuntimeServiceContractID[] = static const char kDOMStringBundleURL[] = "chrome://global/locale/dom/dom.properties"; -static PRThread *gDOMThread; - static JSGCCallback gOldJSGCCallback; static PRBool sIsInitialized; @@ -2203,7 +2201,7 @@ DOMGCCallback(JSContext *cx, JSGCStatus status) { JSBool result = gOldJSGCCallback ? gOldJSGCCallback(cx, status) : JS_TRUE; - if (status == JSGC_BEGIN && PR_GetCurrentThread() != gDOMThread) + if (status == JSGC_BEGIN && !NS_IsMainThread()) return JS_FALSE; // XPCJSRuntime::GCCallback does marking from the JSGC_MARK_END callback. @@ -2227,7 +2225,6 @@ nsJSEnvironment::Startup() gNameSpaceManager = nsnull; sRuntimeService = nsnull; sRuntime = nsnull; - gDOMThread = nsnull; gOldJSGCCallback = nsnull; sIsInitialized = PR_FALSE; sDidShutdown = PR_FALSE; @@ -2298,18 +2295,9 @@ nsJSEnvironment::Init() rv = sRuntimeService->GetRuntime(&sRuntime); NS_ENSURE_SUCCESS(rv, rv); - gDOMThread = PR_GetCurrentThread(); - #ifdef DEBUG // Let's make sure that our main thread is the same as the xpcom main thread. - { - nsCOMPtr t; - PRThread* mainThread; - rv = nsIThread::GetMainThread(getter_AddRefs(t)); - NS_ASSERTION(NS_SUCCEEDED(rv) && t, "bad"); - rv = t->GetPRThread(&mainThread); - NS_ASSERTION(NS_SUCCEEDED(rv) && mainThread == gDOMThread, "bad"); - } + NS_ASSERTION(NS_IsMainThread(), "bad"); #endif NS_ASSERTION(!gOldJSGCCallback, diff --git a/mozilla/embedding/browser/activex/src/common/StdAfx.h b/mozilla/embedding/browser/activex/src/common/StdAfx.h index 56d2396f17b..17230438a40 100644 --- a/mozilla/embedding/browser/activex/src/common/StdAfx.h +++ b/mozilla/embedding/browser/activex/src/common/StdAfx.h @@ -61,10 +61,8 @@ #include "prthread.h" #include "prprf.h" -#include "plevent.h" #include "nsIComponentManager.h" #include "nsIServiceManager.h" -#include "nsIEventQueueService.h" #include "nsStringAPI.h" #include "nsCOMPtr.h" #include "nsComponentManagerUtils.h" @@ -80,6 +78,7 @@ #include "nsIDOMDocumentType.h" #include "nsIDOMElement.h" +#undef _WIN32_WINNT #define _WIN32_WINNT 0x0400 #define _ATL_APARTMENT_THREADED #define _ATL_STATIC_REGISTRY diff --git a/mozilla/embedding/browser/activex/src/control/StdAfx.h b/mozilla/embedding/browser/activex/src/control/StdAfx.h index 9d503010ed5..262e63510d8 100644 --- a/mozilla/embedding/browser/activex/src/control/StdAfx.h +++ b/mozilla/embedding/browser/activex/src/control/StdAfx.h @@ -61,7 +61,6 @@ #include "prthread.h" #include "prprf.h" -#include "plevent.h" #include "nsIComponentManager.h" #include "nsIServiceManager.h" #include "nsWidgetsCID.h" @@ -114,6 +113,7 @@ #include "nsIDOMMouseEvent.h" #include "nsIDOMEventReceiver.h" +#undef _WIN32_WINNT #define _WIN32_WINNT 0x0400 #define _ATL_APARTMENT_THREADED #define _ATL_STATIC_REGISTRY diff --git a/mozilla/embedding/browser/activex/src/plugin/StdAfx.h b/mozilla/embedding/browser/activex/src/plugin/StdAfx.h index 81dcc13b78b..7f66d61a90b 100644 --- a/mozilla/embedding/browser/activex/src/plugin/StdAfx.h +++ b/mozilla/embedding/browser/activex/src/plugin/StdAfx.h @@ -49,6 +49,7 @@ #define STRICT +#undef _WIN32_WINNT #define _WIN32_WINNT 0x0400 #define _ATL_APARTMENT_THREADED #define _ATL_STATIC_REGISTRY diff --git a/mozilla/embedding/browser/gtk/src/EmbedPrivate.cpp b/mozilla/embedding/browser/gtk/src/EmbedPrivate.cpp index 1bdda9fba58..78199f09e28 100644 --- a/mozilla/embedding/browser/gtk/src/EmbedPrivate.cpp +++ b/mozilla/embedding/browser/gtk/src/EmbedPrivate.cpp @@ -573,16 +573,14 @@ EmbedPrivate::PushStartup(void) // XXX create offscreen window for appshell service? // XXX remove X prop from offscreen window? - nsCOMPtr appShell; - appShell = do_CreateInstance(kAppShellCID); + nsCOMPtr appShell = do_GetService(kAppShellCID); if (!appShell) { NS_WARNING("Failed to create appshell in EmbedPrivate::PushStartup!\n"); return; } sAppShell = appShell.get(); NS_ADDREF(sAppShell); - sAppShell->Create(0, nsnull); - sAppShell->Spinup(); + sAppShell->Init(0, nsnull); } } @@ -604,7 +602,6 @@ EmbedPrivate::PopStartup(void) if (sAppShell) { // Shutdown the appshell service. - sAppShell->Spindown(); NS_RELEASE(sAppShell); sAppShell = 0; } diff --git a/mozilla/embedding/components/windowwatcher/src/nsWindowWatcher.cpp b/mozilla/embedding/components/windowwatcher/src/nsWindowWatcher.cpp index 6f87fb24f04..ca0c2ec4b09 100644 --- a/mozilla/embedding/components/windowwatcher/src/nsWindowWatcher.cpp +++ b/mozilla/embedding/components/windowwatcher/src/nsWindowWatcher.cpp @@ -61,8 +61,6 @@ #include "nsIScreen.h" #include "nsIScreenManager.h" #include "nsIScriptContext.h" -#include "nsIEventQueue.h" -#include "nsIEventQueueService.h" #include "nsIGenericFactory.h" #include "nsIJSContextStack.h" #include "nsIObserverService.h" @@ -89,25 +87,10 @@ #include "jsinterp.h" // for js_AllocStack() and js_FreeStack() -#ifdef XP_UNIX -// please see bug 78421 for the eventual "right" fix for this -#define HAVE_LAME_APPSHELL -#endif - -#ifdef HAVE_LAME_APPSHELL -#include "nsIAppShell.h" -// for NS_APPSHELL_CID -#include -#endif - #ifdef USEWEAKREFS #include "nsIWeakReference.h" #endif -#ifdef HAVE_LAME_APPSHELL -static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID); -#endif - static const char *sJSStackContractID="@mozilla.org/js/xpc/ContextStack;1"; /**************************************************************** @@ -277,74 +260,6 @@ void nsWatcherWindowEnumerator::WindowRemoved(nsWatcherWindowEntry *inInfo) { inInfo->mYounger : 0; } -/**************************************************************** - ********************* EventQueueAutoPopper ********************* - ****************************************************************/ - -class EventQueueAutoPopper { -public: - EventQueueAutoPopper(); - ~EventQueueAutoPopper(); - - nsresult Push(); - -protected: - nsCOMPtr mService; - nsCOMPtr mQueue; -#ifdef HAVE_LAME_APPSHELL - nsCOMPtr mAppShell; -#endif -}; - -EventQueueAutoPopper::EventQueueAutoPopper() : mQueue(nsnull) -{ -} - -EventQueueAutoPopper::~EventQueueAutoPopper() -{ -#ifdef HAVE_LAME_APPSHELL - if (mAppShell) { - if (mQueue) - mAppShell->ListenToEventQueue(mQueue, PR_FALSE); - mAppShell->Spindown(); - mAppShell = nsnull; - } -#endif - - if(mQueue) - mService->PopThreadEventQueue(mQueue); -} - -nsresult EventQueueAutoPopper::Push() -{ - if (mQueue) // only once - return NS_ERROR_FAILURE; - - mService = do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID); - if (!mService) - return NS_ERROR_FAILURE; - - // push a new queue onto it - mService->PushThreadEventQueue(getter_AddRefs(mQueue)); - if (!mQueue) - return NS_ERROR_FAILURE; - -#ifdef HAVE_LAME_APPSHELL - // listen to the event queue - mAppShell = do_CreateInstance(kAppShellCID); - if (!mAppShell) - return NS_ERROR_FAILURE; - - mAppShell->Create(0, nsnull); - mAppShell->Spinup(); - - // listen to the new queue - mAppShell->ListenToEventQueue(mQueue, PR_TRUE); -#endif - - return NS_OK; -} - /**************************************************************** ********************** JSContextAutoPopper ********************* ****************************************************************/ @@ -568,7 +483,6 @@ nsWindowWatcher::OpenWindowJSInternal(nsIDOMWindow *aParent, nsCOMPtr uriToLoad; // from aUrl, if any nsCOMPtr parentTreeOwner; // from the parent window, if any nsCOMPtr newDocShellItem; // from the new window - EventQueueAutoPopper queueGuard; JSContextAutoPopper callerContextGuard; NS_ENSURE_ARG_POINTER(_retval); @@ -681,13 +595,10 @@ nsWindowWatcher::OpenWindowJSInternal(nsIDOMWindow *aParent, parentChrome->IsWindowModal(&weAreModal); if (weAreModal) { - rv = queueGuard.Push(); - if (NS_SUCCEEDED(rv)) { - windowIsModal = PR_TRUE; - // in case we added this because weAreModal - chromeFlags |= nsIWebBrowserChrome::CHROME_MODAL | - nsIWebBrowserChrome::CHROME_DEPENDENT; - } + windowIsModal = PR_TRUE; + // in case we added this because weAreModal + chromeFlags |= nsIWebBrowserChrome::CHROME_MODAL | + nsIWebBrowserChrome::CHROME_DEPENDENT; } NS_ASSERTION(mWindowCreator, diff --git a/mozilla/embedding/tests/mfcembed/components/PrintingPromptService.cpp b/mozilla/embedding/tests/mfcembed/components/PrintingPromptService.cpp index eeb94b82018..20f3fd1c061 100644 --- a/mozilla/embedding/tests/mfcembed/components/PrintingPromptService.cpp +++ b/mozilla/embedding/tests/mfcembed/components/PrintingPromptService.cpp @@ -41,6 +41,9 @@ #include "nsMemory.h" #include "nsString.h" #include "nsReadableUtils.h" +#include "nsIRunnable.h" +#include "nsIThread.h" +#include "nsIThreadManager.h" #include "nsIDOMWindow.h" #include "nsIEmbeddingSiteWindow.h" #include "nsIFactory.h" @@ -53,10 +56,6 @@ #include "nsPrintDialogUtil.h" #include "PrintProgressDialog.h" -// For PLEvent -#include "nsIEventQueueService.h" -#include "plevent.h" - static HINSTANCE gInstance; //***************************************************************************** @@ -103,11 +102,6 @@ private: CPrintProgressDialog* m_PPDlg; }; -// Define PL Callback Functions -static void* PR_CALLBACK HandlePLEvent(PLEvent* aEvent); -static void PR_CALLBACK DestroyPLEvent(PLEvent* aEvent); - - //***************************************************************************** NS_IMPL_ISUPPORTS2(CPrintingPromptService, nsIPrintingPromptService, nsIWebProgressListener) @@ -167,33 +161,55 @@ CPrintingPromptService::ShowPrintDialog(nsIDOMWindow *parent, nsIWebBrowserPrint } } +//------------------------------------------------------------------------ +class NotifyObserverEvent : public nsIRunnable { +public: + NS_DECL_ISUPPORTS + + NotifyObserverEvent(CPrintingPromptService *pps) + : mPPS(pps) { + NS_ASSERTION(mPPS, "null parameter"); + NS_ADDREF(mPPS); + } + + ~NotifyObserverEvent() { + NS_RELEASE(mPPS); + } + + NS_IMETHOD Run() { + mPPS->NotifyObserver(); + return NS_OK; + } + +private: + CPrintingPromptService *mPPS; +}; +NS_IMPL_ISUPPORTS1(NotifyObserverEvent, nsIRunnable) //----------------------------------------------------------- PRBool CPrintingPromptService::FirePauseEvent() { - static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); + nsCOMPtr thread_mgr = + do_GetService(NS_THREADMANAGER_CONTRACTID); - nsCOMPtr event_service = do_GetService(kEventQueueServiceCID); - - if (!event_service) + if (!thread_mgr) { - NS_WARNING("Failed to get event queue service"); + NS_WARNING("Failed to get thread manager"); return PR_FALSE; } - nsCOMPtr event_queue; + nsCOMPtr thread; - event_service->GetThreadEventQueue(NS_CURRENT_THREAD, - getter_AddRefs(event_queue)); + thread_mgr->GetCurrentThread(getter_AddRefs(thread)); - if (!event_queue) + if (!thread) { - NS_WARNING("Failed to get event queue from service"); + NS_WARNING("Failed to get current thread from thread manager"); return PR_FALSE; } - PLEvent *event = new PLEvent; + nsCOMPtr event = new NotifyObserverEvent(this); if (!event) { @@ -201,12 +217,7 @@ CPrintingPromptService::FirePauseEvent() return PR_FALSE; } - PL_InitEvent(event, this, ::HandlePLEvent, ::DestroyPLEvent); - - // The event owns the content pointer now. - NS_ADDREF_THIS(); - - event_queue->PostEvent(event); + thread->Dispatch(event, NS_DISPATCH_NORMAL); return PR_TRUE; } @@ -276,27 +287,6 @@ void CPrintingPromptService::NotifyObserver() } } -//------------------------------------------------------------------------ -void* PR_CALLBACK HandlePLEvent(PLEvent* aEvent) -{ - CPrintingPromptService *printingPromptService = (CPrintingPromptService*)PL_GetEventOwner(aEvent); - - NS_ASSERTION(printingPromptService, "The event owner is null."); - if (printingPromptService) { - printingPromptService->NotifyObserver(); - } - return nsnull; -} - -//------------------------------------------------------------------------ -void PR_CALLBACK DestroyPLEvent(PLEvent* aEvent) -{ - CPrintingPromptService *printingPromptService = (CPrintingPromptService*)PL_GetEventOwner(aEvent); - NS_IF_RELEASE(printingPromptService); - - delete aEvent; -} - ////////////////////////////////////////////////////////////////////// // nsIWebProgressListener ////////////////////////////////////////////////////////////////////// diff --git a/mozilla/extensions/gnomevfs/nsGnomeVFSProtocolHandler.cpp b/mozilla/extensions/gnomevfs/nsGnomeVFSProtocolHandler.cpp index 91e15dbe61e..524de11da92 100644 --- a/mozilla/extensions/gnomevfs/nsGnomeVFSProtocolHandler.cpp +++ b/mozilla/extensions/gnomevfs/nsGnomeVFSProtocolHandler.cpp @@ -47,7 +47,7 @@ extern "C" { #include "nsIPrefService.h" #include "nsIPrefBranch2.h" #include "nsIObserver.h" -#include "nsEventQueueUtils.h" +#include "nsThreadUtils.h" #include "nsProxyRelease.h" #include "nsIAuthPrompt.h" #include "nsIStringBundle.h" @@ -282,31 +282,20 @@ ProxiedAuthCallback(gconstpointer in, nsMemory::Free(pass); } -struct nsGnomeVFSAuthParams +struct nsGnomeVFSAuthCallbackEvent : public nsRunnable { gconstpointer in; gsize in_size; gpointer out; gsize out_size; gpointer callback_data; + + NS_IMETHOD Run() { + ProxiedAuthCallback(in, in_size, out, out_size, callback_data); + return NS_OK; + } }; -PR_STATIC_CALLBACK(void *) -AuthCallbackEventHandler(PLEvent *ev) -{ - nsGnomeVFSAuthParams *params = (nsGnomeVFSAuthParams *) ev->owner; - ProxiedAuthCallback(params->in, params->in_size, - params->out, params->out_size, - params->callback_data); - return nsnull; -} - -PR_STATIC_CALLBACK(void) -AuthCallbackEventDestructor(PLEvent *ev) -{ - // ignored -} - static void AuthCallback(gconstpointer in, gsize in_size, @@ -314,30 +303,20 @@ AuthCallback(gconstpointer in, gsize out_size, gpointer callback_data) { - // Need to proxy this callback over to the main thread. This code is greatly - // simplified by the fact that we are making a synchronous callback. E.g., we - // don't need to allocate the PLEvent on the heap. + // Need to proxy this callback over to the main thread. Synchronous dispatch + // is required in order to provide data to the GnomeVFS callback. - nsCOMPtr eventQ; - NS_GetMainEventQ(getter_AddRefs(eventQ)); - if (!eventQ) - return; + nsRefPtr ev = new nsGnomeVFSAuthCallbackEvent(); + if (!ev) + return; // OOM - nsGnomeVFSAuthParams params; - params.in = in; - params.in_size = in_size; - params.out = out; - params.out_size = out_size; - params.callback_data = callback_data; + ev->in = in; + ev->in_size = in_size; + ev->out = out; + ev->out_size = out_size; + ev->callback_data = callback_data; - PLEvent ev; - PL_InitEvent(&ev, ¶ms, - AuthCallbackEventHandler, - AuthCallbackEventDestructor); - - void *result; - if (NS_FAILED(eventQ->PostSynchronousEvent(&ev, &result))) - PL_DestroyEvent(&ev); + NS_DispatchToMainThread(ev, NS_DISPATCH_SYNC); } //----------------------------------------------------------------------------- @@ -618,32 +597,25 @@ nsGnomeVFSInputStream::DoRead(char *aBuf, PRUint32 aCount, PRUint32 *aCountRead) } // This class is used to implement SetContentTypeOfChannel. -class nsGnomeVFSSetContentTypeEvent : public PLEvent +class nsGnomeVFSSetContentTypeEvent : public nsRunnable { public: nsGnomeVFSSetContentTypeEvent(nsIChannel *channel, const char *contentType) - : mContentType(contentType) + : mChannel(channel), mContentType(contentType) { - // stash channel reference in owner field. no AddRef here! see note + // stash channel reference in mChannel. no AddRef here! see note // in SetContentTypeOfchannel. - PL_InitEvent(this, channel, EventHandler, EventDestructor); } - PR_STATIC_CALLBACK(void *) EventHandler(PLEvent *ev) + NS_IMETHOD Run() { - nsGnomeVFSSetContentTypeEvent *self = (nsGnomeVFSSetContentTypeEvent *) ev; - ((nsIChannel *) self->owner)->SetContentType(self->mContentType); - return nsnull; - } - - PR_STATIC_CALLBACK(void) EventDestructor(PLEvent *ev) - { - nsGnomeVFSSetContentTypeEvent *self = (nsGnomeVFSSetContentTypeEvent *) ev; - delete self; + mChannel->SetContentType(mContentType); + return NS_OK; } private: - nsCString mContentType; + nsIChannel *mChannel; + nsCString mContentType; }; nsresult @@ -656,12 +628,7 @@ nsGnomeVFSInputStream::SetContentTypeOfChannel(const char *contentType) // thread's event queue to protect us against memory corruption. nsresult rv; - nsCOMPtr eventQ; - rv = NS_GetMainEventQ(getter_AddRefs(eventQ)); - if (NS_FAILED(rv)) - return rv; - - nsGnomeVFSSetContentTypeEvent *ev = + nsCOMPtr ev = new nsGnomeVFSSetContentTypeEvent(mChannel, contentType); if (!ev) { @@ -669,9 +636,7 @@ nsGnomeVFSInputStream::SetContentTypeOfChannel(const char *contentType) } else { - rv = eventQ->PostEvent(ev); - if (NS_FAILED(rv)) - PL_DestroyEvent(ev); + rv = NS_DispatchToMainThread(ev); } return rv; } @@ -698,14 +663,13 @@ nsGnomeVFSInputStream::Close() if (mChannel) { - nsresult rv; + nsresult rv = NS_OK; - nsCOMPtr eventQ; - rv = NS_GetMainEventQ(getter_AddRefs(eventQ)); - if (NS_SUCCEEDED(rv)) - rv = NS_ProxyRelease(eventQ, mChannel); + nsCOMPtr thread = do_GetMainThread(); + if (thread) + rv = NS_ProxyRelease(thread, mChannel); - NS_ASSERTION(NS_SUCCEEDED(rv), "leaking channel reference"); + NS_ASSERTION(thread && NS_SUCCEEDED(rv), "leaking channel reference"); mChannel = nsnull; } diff --git a/mozilla/extensions/pref/autoconfig/src/nsAutoConfig.cpp b/mozilla/extensions/pref/autoconfig/src/nsAutoConfig.cpp index 2b3d4b8faea..adfaaa31074 100644 --- a/mozilla/extensions/pref/autoconfig/src/nsAutoConfig.cpp +++ b/mozilla/extensions/pref/autoconfig/src/nsAutoConfig.cpp @@ -44,11 +44,11 @@ #include "nsIURI.h" #include "nsIHttpChannel.h" #include "nsIFileStreams.h" +#include "nsThreadUtils.h" #include "nsAppDirectoryServiceDefs.h" #include "prmem.h" #include "nsIProfile.h" #include "nsIObserverService.h" -#include "nsIEventQueueService.h" #include "nsLiteralString.h" #include "nsIPromptService.h" #include "nsIServiceManager.h" @@ -353,19 +353,11 @@ nsresult nsAutoConfig::downloadAutoConfig() firstTime = PR_FALSE; - // Getting an event queue. If we start an AsyncOpen, the thread + // Getting the current thread. If we start an AsyncOpen, the thread // needs to wait before the reading of autoconfig is done - nsCOMPtr service = - do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv); - if (NS_FAILED(rv)) - return rv; - - nsCOMPtr currentThreadQ; - rv = service->GetThreadEventQueue(NS_CURRENT_THREAD, - getter_AddRefs(currentThreadQ)); - if (NS_FAILED(rv)) - return rv; + nsCOMPtr thread = do_GetCurrentThread(); + NS_ENSURE_STATE(thread); /* process events until we're finished. AutoConfig.jsc reading needs to be finished before the browser starts loading up @@ -376,16 +368,9 @@ nsresult nsAutoConfig::downloadAutoConfig() */ while (!mLoaded) { - - PRBool isEventPending; - rv = currentThreadQ->PendingEvents(&isEventPending); - if (NS_FAILED(rv)) - return rv; - if (isEventPending) { - rv = currentThreadQ->ProcessPendingEvents(); - if (NS_FAILED(rv)) - return rv; - } + rv = thread->ProcessNextEvent(); + if (NS_FAILED(rv)) + return rv; } PRInt32 minutes = 0; diff --git a/mozilla/extensions/pref/autoconfig/src/nsLDAPSyncQuery.cpp b/mozilla/extensions/pref/autoconfig/src/nsLDAPSyncQuery.cpp index c91938c2326..e0f917ff996 100644 --- a/mozilla/extensions/pref/autoconfig/src/nsLDAPSyncQuery.cpp +++ b/mozilla/extensions/pref/autoconfig/src/nsLDAPSyncQuery.cpp @@ -44,7 +44,7 @@ #include "nsIProxyObjectManager.h" #include "nsXPIDLString.h" #include "nsILDAPErrors.h" -#include "nsIEventQueueService.h" +#include "nsThreadUtils.h" #include "nsReadableUtils.h" #include "nsILDAPMessage.h" @@ -144,10 +144,10 @@ nsLDAPSyncQuery::OnLDAPInit(nsILDAPConnection *aConn, nsresult aStatus) // get a proxy object so the callback happens on the main thread // - rv = NS_GetProxyForObject(NS_CURRENT_EVENTQ, + rv = NS_GetProxyForObject(NS_PROXY_TO_CURRENT_THREAD, NS_GET_IID(nsILDAPMessageListener), NS_STATIC_CAST(nsILDAPMessageListener *, this), - PROXY_ASYNC | PROXY_ALWAYS, + NS_PROXY_ASYNC | NS_PROXY_ALWAYS, getter_AddRefs(selfProxy)); if (NS_FAILED(rv)) { FinishLDAPQuery(); @@ -283,10 +283,10 @@ nsLDAPSyncQuery::StartLDAPSearch() // get a proxy object so the callback happens on the main thread // - rv = NS_GetProxyForObject(NS_CURRENT_EVENTQ, + rv = NS_GetProxyForObject(NS_PROXY_TO_CURRENT_THREAD, NS_GET_IID(nsILDAPMessageListener), NS_STATIC_CAST(nsILDAPMessageListener *, this), - PROXY_ASYNC | PROXY_ALWAYS, + NS_PROXY_ASYNC | NS_PROXY_ALWAYS, getter_AddRefs(selfProxy)); if (NS_FAILED(rv)) { NS_ERROR("nsLDAPSyncQuery::StartLDAPSearch(): couldn't " @@ -407,10 +407,10 @@ nsresult nsLDAPSyncQuery::InitConnection() // get a proxy object so the callback happens on the main thread // - rv = NS_GetProxyForObject(NS_CURRENT_EVENTQ, + rv = NS_GetProxyForObject(NS_PROXY_TO_CURRENT_THREAD, NS_GET_IID(nsILDAPMessageListener), NS_STATIC_CAST(nsILDAPMessageListener *, this), - PROXY_ASYNC | PROXY_ALWAYS, + NS_PROXY_ASYNC | NS_PROXY_ALWAYS, getter_AddRefs(selfProxy)); if (NS_FAILED(rv)) { FinishLDAPQuery(); @@ -461,22 +461,7 @@ NS_IMETHODIMP nsLDAPSyncQuery::GetQueryResults(nsILDAPURL *aServerURL, mServerURL = aServerURL; mProtocolVersion = aProtocolVersion; - nsCOMPtr currentThreadQ; - nsCOMPtr service; - - // Get the eventQueue Service - // - service = do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv); - if (NS_FAILED(rv)) { - return rv; - } - - // Get the eventQ for the Current Thread - // - rv = service->PushThreadEventQueue(getter_AddRefs(currentThreadQ)); - if (NS_FAILED(rv)) { - return rv; - } + nsCOMPtr currentThread = do_GetCurrentThread(); // Start an LDAP query. // InitConnection will bind to the ldap server and post a OnLDAPMessage @@ -484,10 +469,8 @@ NS_IMETHODIMP nsLDAPSyncQuery::GetQueryResults(nsILDAPURL *aServerURL, // be carried out by chain of events // rv = InitConnection(); - if (NS_FAILED(rv)) { - service->PopThreadEventQueue(currentThreadQ); + if (NS_FAILED(rv)) return rv; - } // We want this LDAP query to be synchronous while the XPCOM LDAP is // async in nature. So this eventQueue handling will wait for the @@ -500,25 +483,10 @@ NS_IMETHODIMP nsLDAPSyncQuery::GetQueryResults(nsILDAPURL *aServerURL, // mFinished is a control variable // while (!mFinished) { - - PRBool isEventPending; - rv = currentThreadQ->PendingEvents(&isEventPending); - if (NS_FAILED(rv)) { - service->PopThreadEventQueue(currentThreadQ); + rv = currentThread->ProcessNextEvent(); + if (NS_FAILED(rv)) return rv; - } - if (isEventPending) { - rv = currentThreadQ->ProcessPendingEvents(); - if (NS_FAILED(rv)) { - service->PopThreadEventQueue(currentThreadQ); - return rv; - } - } - } - rv = service->PopThreadEventQueue(currentThreadQ); - if (NS_FAILED(rv)) - return rv; // Return results // diff --git a/mozilla/extensions/webservices/security/src/nsWSAUtils.cpp b/mozilla/extensions/webservices/security/src/nsWSAUtils.cpp index 75b46d8332e..e8b73bb52e7 100755 --- a/mozilla/extensions/webservices/security/src/nsWSAUtils.cpp +++ b/mozilla/extensions/webservices/security/src/nsWSAUtils.cpp @@ -45,14 +45,12 @@ #include "nsIDNSRecord.h" #include "nsICancelable.h" #include "nsIRequest.h" -#include "nsEventQueueUtils.h" +#include "nsThreadUtils.h" #include "nsAutoPtr.h" #include "nsNetCID.h" static const char kSecurityProperties[] = "chrome://global/locale/webservices/security.properties"; -static NS_DEFINE_CID(kDNSServiceCID, NS_DNSSERVICE_CID); -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); class nsDNSListener : public nsIDNSListener { @@ -228,7 +226,7 @@ nsWSAUtils::GetOfficialHostName(nsIURI* aServiceURI, return NS_ERROR_NULL_POINTER; nsresult rv; - nsCOMPtr dns(do_GetService(kDNSServiceCID, &rv)); + nsCOMPtr dns(do_GetService(NS_DNSSERVICE_CONTRACTID, &rv)); if (NS_FAILED(rv)) return rv; @@ -239,36 +237,17 @@ nsWSAUtils::GetOfficialHostName(nsIURI* aServiceURI, nsRefPtr listener = new nsDNSListener(); NS_ENSURE_TRUE(listener, NS_ERROR_OUT_OF_MEMORY); - nsCOMPtr eventQService = - do_GetService(kEventQueueServiceCID, &rv); - - if (NS_FAILED(rv)) - return rv; - - nsCOMPtr eventQ; - rv = eventQService->PushThreadEventQueue(getter_AddRefs(eventQ)); - - if (NS_FAILED(rv)) - return rv; + nsCOMPtr thread = do_GetCurrentThread(); + NS_ENSURE_STATE(thread); nsCOMPtr dummy; rv = dns->AsyncResolve(host, nsIDNSService::RESOLVE_CANONICAL_NAME, - listener, eventQ, getter_AddRefs(dummy)); + listener, thread, getter_AddRefs(dummy)); - PLEvent *ev; - while (NS_SUCCEEDED(rv) && !listener->mLookupFinished) { - rv = eventQ->WaitForEvent(&ev); - NS_ASSERTION(NS_SUCCEEDED(rv), "WaitForEvent failed"); - if (NS_SUCCEEDED(rv)) { - rv = eventQ->HandleEvent(ev); - NS_ASSERTION(NS_SUCCEEDED(rv), "HandleEvent failed"); - } - } + while (NS_SUCCEEDED(rv) && !listener->mLookupFinished) + rv = thread->ProcessNextEvent(); aResult.Assign(listener->mOfficialHostName); - - eventQService->PopThreadEventQueue(eventQ); - return rv; } @@ -295,4 +274,3 @@ nsDNSListener::OnLookupComplete(nsICancelable* aRequest, mLookupFinished = PR_TRUE; return NS_OK; } - diff --git a/mozilla/extensions/webservices/security/src/nsWSAUtils.h b/mozilla/extensions/webservices/security/src/nsWSAUtils.h index 8d9896d384e..5829f97997c 100755 --- a/mozilla/extensions/webservices/security/src/nsWSAUtils.h +++ b/mozilla/extensions/webservices/security/src/nsWSAUtils.h @@ -39,7 +39,6 @@ #define nsWSAUtils_h__ #include "nsIDNSListener.h" -#include "nsIEventQueueService.h" #include "nsIURI.h" #include "nsCOMPtr.h" #include "nsString.h" diff --git a/mozilla/extensions/xmlextras/base/src/nsDOMParser.cpp b/mozilla/extensions/xmlextras/base/src/nsDOMParser.cpp index 613b785806c..9fd244f8b2d 100644 --- a/mozilla/extensions/xmlextras/base/src/nsDOMParser.cpp +++ b/mozilla/extensions/xmlextras/base/src/nsDOMParser.cpp @@ -62,10 +62,9 @@ #include "nsIDOMEventReceiver.h" #include "nsLoadListenerProxy.h" #include "nsStreamUtils.h" +#include "nsThreadUtils.h" #include "nsNetCID.h" -static NS_DEFINE_IID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); - static const char* kLoadAsData = "loadAsData"; static NS_DEFINE_CID(kIDOMDOMImplementationCID, NS_DOM_IMPLEMENTATION_CID); @@ -122,7 +121,6 @@ nsDOMParser::Error(nsIDOMEvent* aEvent) nsDOMParser::nsDOMParser() : mLoopingForSyncLoad(PR_FALSE) { - mEventQService = do_GetService(kEventQueueServiceCID); } nsDOMParser::~nsDOMParser() @@ -327,19 +325,11 @@ nsDOMParser::ParseFromStream(nsIInputStream *stream, nsCOMPtr document(do_QueryInterface(domDocument)); if (!document) return NS_ERROR_FAILURE; - nsCOMPtr modalEventQueue; - - if(!mEventQService) { - return NS_ERROR_FAILURE; - } + nsCOMPtr thread = do_GetCurrentThread(); + NS_ENSURE_STATE(thread); mLoopingForSyncLoad = PR_TRUE; - rv = mEventQService->PushThreadEventQueue(getter_AddRefs(modalEventQueue)); - if (NS_FAILED(rv)) { - return rv; - } - // Have to pass PR_FALSE for reset here, else the reset will remove // our event listener. Should that listener addition move to later // than this call? @@ -354,9 +344,6 @@ nsDOMParser::ParseFromStream(nsIInputStream *stream, } if (NS_FAILED(rv) || !listener) { - if (modalEventQueue) { - mEventQService->PopThreadEventQueue(modalEventQueue); - } return NS_ERROR_FAILURE; } @@ -381,17 +368,15 @@ nsDOMParser::ParseFromStream(nsIInputStream *stream, // the channel, so we do not need to call Cancel(rv) as we do above. if (NS_FAILED(rv)) { - if (modalEventQueue) { - mEventQService->PopThreadEventQueue(modalEventQueue); - } return NS_ERROR_FAILURE; } - while (mLoopingForSyncLoad) { - modalEventQueue->ProcessPendingEvents(); - } + // Process events until we receive a load, abort, or error event for the + // document object. That event may have already fired. - mEventQService->PopThreadEventQueue(modalEventQueue); + while (NS_SUCCEEDED(rv) && mLoopingForSyncLoad) { + rv = thread->ProcessNextEvent(); + } *_retval = domDocument; NS_ADDREF(*_retval); diff --git a/mozilla/extensions/xmlextras/base/src/nsDOMParser.h b/mozilla/extensions/xmlextras/base/src/nsDOMParser.h index 4fc7059bd8a..6a88a8f853a 100644 --- a/mozilla/extensions/xmlextras/base/src/nsDOMParser.h +++ b/mozilla/extensions/xmlextras/base/src/nsDOMParser.h @@ -41,7 +41,6 @@ #include "nsIDOMParser.h" #include "nsCOMPtr.h" #include "nsIURI.h" -#include "nsIEventQueueService.h" #include "nsIDOMLoadListener.h" #include "nsWeakReference.h" @@ -70,7 +69,6 @@ public: private: nsCOMPtr mBaseURI; - nsCOMPtr mEventQService; PRBool mLoopingForSyncLoad; }; diff --git a/mozilla/extensions/xmlextras/base/src/nsXMLHttpRequest.cpp b/mozilla/extensions/xmlextras/base/src/nsXMLHttpRequest.cpp index 3427a6aef32..fda1fa52fd0 100644 --- a/mozilla/extensions/xmlextras/base/src/nsXMLHttpRequest.cpp +++ b/mozilla/extensions/xmlextras/base/src/nsXMLHttpRequest.cpp @@ -50,6 +50,7 @@ #include "nsIURI.h" #include "nsILoadGroup.h" #include "nsNetUtil.h" +#include "nsThreadUtils.h" #include "nsIUploadChannel.h" #include "nsIDOMSerializer.h" #include "nsXPCOM.h" @@ -85,7 +86,6 @@ static const char* kLoadAsData = "loadAsData"; static NS_DEFINE_CID(kCharsetAliasCID, NS_CHARSETALIAS_CID); static NS_DEFINE_CID(kIDOMDOMImplementationCID, NS_DOM_IMPLEMENTATION_CID); static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID); -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); // State #define XML_HTTP_REQUEST_UNINITIALIZED (1 << 0) // 0 @@ -1579,17 +1579,12 @@ nsXMLHttpRequest::Send(nsIVariant *aBody) // Reset responseXML mDocument = nsnull; - nsCOMPtr modalEventQueue; + nsCOMPtr thread; if (!(mState & XML_HTTP_REQUEST_ASYNC)) { - if(!mEventQService) { - mEventQService = do_GetService(kEventQueueServiceCID, &rv); - NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); - } - mState |= XML_HTTP_REQUEST_SYNCLOOPING; - rv = mEventQService->PushThreadEventQueue(getter_AddRefs(modalEventQueue)); + rv = NS_GetCurrentThread(getter_AddRefs(thread)); if (NS_FAILED(rv)) { return rv; } @@ -1642,10 +1637,6 @@ nsXMLHttpRequest::Send(nsIVariant *aBody) rv = mChannel->AsyncOpen(listener, nsnull); if (NS_FAILED(rv)) { - if (modalEventQueue) { - mEventQService->PopThreadEventQueue(modalEventQueue); - } - // Drop our ref to the channel to avoid cycles mChannel = nsnull; return rv; @@ -1653,22 +1644,15 @@ nsXMLHttpRequest::Send(nsIVariant *aBody) // If we're synchronous, spin an event loop here and wait if (!(mState & XML_HTTP_REQUEST_ASYNC)) { - while (mState & XML_HTTP_REQUEST_SYNCLOOPING) { - modalEventQueue->ProcessPendingEvents(); - - // Be sure not to busy wait! (see bug 273578) - if (mState & XML_HTTP_REQUEST_SYNCLOOPING) - PR_Sleep(PR_MillisecondsToInterval(10)); - } - - mEventQService->PopThreadEventQueue(modalEventQueue); + while (NS_SUCCEEDED(rv) && mState & XML_HTTP_REQUEST_SYNCLOOPING) + rv = thread->ProcessNextEvent(); } if (!mChannel) { return NS_ERROR_FAILURE; } - return NS_OK; + return rv; } /* void setRequestHeader (in AUTF8String header, in AUTF8String value); */ diff --git a/mozilla/extensions/xmlextras/base/src/nsXMLHttpRequest.h b/mozilla/extensions/xmlextras/base/src/nsXMLHttpRequest.h index c1a2421ac83..740af0d5428 100644 --- a/mozilla/extensions/xmlextras/base/src/nsXMLHttpRequest.h +++ b/mozilla/extensions/xmlextras/base/src/nsXMLHttpRequest.h @@ -49,7 +49,6 @@ #include "nsIHttpChannel.h" #include "nsIDocument.h" #include "nsIStreamListener.h" -#include "nsIEventQueueService.h" #include "nsWeakReference.h" #include "nsISupportsArray.h" #include "jsapi.h" @@ -157,7 +156,6 @@ protected: nsCOMPtr mOnReadystatechangeListener; nsCOMPtr mXMLParserStreamListener; - nsCOMPtr mEventQService; // used to implement getAllResponseHeaders() class nsHeaderVisitor : public nsIHttpHeaderVisitor { diff --git a/mozilla/intl/strres/src/nsStringBundle.cpp b/mozilla/intl/strres/src/nsStringBundle.cpp index f56c9761718..223d8f37133 100644 --- a/mozilla/intl/strres/src/nsStringBundle.cpp +++ b/mozilla/intl/strres/src/nsStringBundle.cpp @@ -74,9 +74,6 @@ #include "nsIStringStream.h" #endif -// eventQ -#include "nsIEventQueueService.h" - #include "prenv.h" #include "nsCRT.h" diff --git a/mozilla/intl/strres/tests/StringBundleTest.cpp b/mozilla/intl/strres/tests/StringBundleTest.cpp index 154c4b07d69..96a6c9718ed 100644 --- a/mozilla/intl/strres/tests/StringBundleTest.cpp +++ b/mozilla/intl/strres/tests/StringBundleTest.cpp @@ -37,7 +37,6 @@ #include "nsCOMPtr.h" #include "nsIStringBundle.h" -#include "nsIEventQueueService.h" #include #include "nsIURL.h" diff --git a/mozilla/js/jsd/jsd_xpc.cpp b/mozilla/js/jsd/jsd_xpc.cpp index 9e044ef961b..e15bf1bd28d 100644 --- a/mozilla/js/jsd/jsd_xpc.cpp +++ b/mozilla/js/jsd/jsd_xpc.cpp @@ -50,7 +50,7 @@ #include "nsIObserverService.h" #include "nsICategoryManager.h" #include "nsIJSRuntimeService.h" -#include "nsIEventQueueService.h" +#include "nsThreadUtils.h" #include "nsMemory.h" #include "jsdebug.h" #include "nsReadableUtils.h" @@ -118,8 +118,6 @@ jsds_GCCallbackProc (JSContext *cx, JSGCStatus status); ******************************************************************************/ const char implementationString[] = "Mozilla JavaScript Debugger Service"; -static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID); -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); const char jsdServiceCtrID[] = "@mozilla.org/js/jsd/debugger-service;1"; const char jsdARObserverCtrID[] = "@mozilla.org/js/jsd/app-start-observer;2"; @@ -2942,23 +2940,16 @@ jsdService::WrapValue(jsdIValue **_rval) NS_IMETHODIMP jsdService::EnterNestedEventLoop (jsdINestCallback *callback, PRUint32 *_rval) { - nsCOMPtr appShell(do_CreateInstance(kAppShellCID)); - NS_ENSURE_TRUE(appShell, NS_ERROR_FAILURE); - nsCOMPtr - eventService(do_GetService(kEventQueueServiceCID)); - NS_ENSURE_TRUE(eventService, NS_ERROR_FAILURE); - - appShell->Create(0, nsnull); - appShell->Spinup(); - + // Nesting event queues is a thing of the past. Now, we just spin the + // current event loop. + nsCOMPtr stack(do_GetService("@mozilla.org/js/xpc/ContextStack;1")); nsresult rv = NS_OK; PRUint32 nestLevel = ++mNestedLoopLevel; - nsCOMPtr eventQ; - if (stack && NS_SUCCEEDED(stack->Push(nsnull)) && - NS_SUCCEEDED(eventService->PushThreadEventQueue(getter_AddRefs(eventQ)))) + nsCOMPtr thread = do_GetCurrentThread(); + if (stack && NS_SUCCEEDED(stack->Push(nsnull))) { if (NS_SUCCEEDED(rv) && callback) { Pause(nsnull); @@ -2966,16 +2957,9 @@ jsdService::EnterNestedEventLoop (jsdINestCallback *callback, PRUint32 *_rval) UnPause(nsnull); } - while(NS_SUCCEEDED(rv) && mNestedLoopLevel >= nestLevel) - { - void* data; - PRBool isRealEvent; - //PRBool processEvent; - - rv = appShell->GetNativeEvent(isRealEvent, data); - if(NS_SUCCEEDED(rv)) - appShell->DispatchNativeEvent(isRealEvent, data); - } + while (NS_SUCCEEDED(rv) && mNestedLoopLevel >= nestLevel) + rv = thread->ProcessNextEvent(); + JSContext* cx; stack->Pop(&cx); NS_ASSERTION(cx == nsnull, "JSContextStack mismatch"); @@ -2983,9 +2967,6 @@ jsdService::EnterNestedEventLoop (jsdINestCallback *callback, PRUint32 *_rval) else rv = NS_ERROR_FAILURE; - eventService->PopThreadEventQueue(eventQ); - appShell->Spindown(); - NS_ASSERTION (mNestedLoopLevel <= nestLevel, "nested event didn't unwind properly"); if (mNestedLoopLevel == nestLevel) diff --git a/mozilla/js/src/xpconnect/src/nsXPConnect.cpp b/mozilla/js/src/xpconnect/src/nsXPConnect.cpp index 0ccbbebb66b..b910b0cb6ae 100644 --- a/mozilla/js/src/xpconnect/src/nsXPConnect.cpp +++ b/mozilla/js/src/xpconnect/src/nsXPConnect.cpp @@ -49,7 +49,6 @@ NS_IMPL_THREADSAFE_ISUPPORTS2(nsXPConnect,nsIXPConnect,nsISupportsWeakReference) nsXPConnect* nsXPConnect::gSelf = nsnull; JSBool nsXPConnect::gOnceAliveNowDead = JS_FALSE; -PRThread* nsXPConnect::gMainThread = nsnull; const char XPC_CONTEXT_STACK_CONTRACTID[] = "@mozilla.org/js/xpc/ContextStack;1"; const char XPC_RUNTIME_CONTRACTID[] = "@mozilla.org/js/xpc/RuntimeService;1"; @@ -326,19 +325,6 @@ nsXPConnect::CreateRuntime() return nsnull != mRuntime; } -// static -PRThread* -nsXPConnect::FindMainThread() -{ - nsCOMPtr t; - nsresult rv; - rv = nsIThread::GetMainThread(getter_AddRefs(t)); - NS_ASSERTION(NS_SUCCEEDED(rv) && t, "bad"); - rv = t->GetPRThread(&gMainThread); - NS_ASSERTION(NS_SUCCEEDED(rv) && gMainThread, "bad"); - return gMainThread; -} - /***************************************************************************/ typedef PRBool (*InfoTester)(nsIInterfaceInfoManager* manager, const void* data, diff --git a/mozilla/js/src/xpconnect/src/xpcjsruntime.cpp b/mozilla/js/src/xpconnect/src/xpcjsruntime.cpp index 32d4f5a6aab..46237e526d8 100644 --- a/mozilla/js/src/xpconnect/src/xpcjsruntime.cpp +++ b/mozilla/js/src/xpconnect/src/xpcjsruntime.cpp @@ -236,8 +236,7 @@ JSBool XPCJSRuntime::GCCallback(JSContext *cx, JSGCStatus status) { case JSGC_BEGIN: { - if(self->GetMainThreadOnlyGC() && - PR_GetCurrentThread() != nsXPConnect::GetMainThread()) + if(self->GetMainThreadOnlyGC() && !NS_IsMainThread()) { return JS_FALSE; } diff --git a/mozilla/js/src/xpconnect/src/xpcprivate.h b/mozilla/js/src/xpconnect/src/xpcprivate.h index de01e4f12f8..f8e68f42281 100644 --- a/mozilla/js/src/xpconnect/src/xpcprivate.h +++ b/mozilla/js/src/xpconnect/src/xpcprivate.h @@ -93,9 +93,8 @@ #include "nsReadableUtils.h" #include "nsXPIDLString.h" -#include "nsIThread.h" +#include "nsThreadUtils.h" #include "nsIJSContextStack.h" -#include "prthread.h" #include "nsDeque.h" #include "nsVoidArray.h" @@ -455,9 +454,6 @@ public: static JSBool IsISupportsDescendant(nsIInterfaceInfo* info); - static PRThread* GetMainThread() - {return gMainThread ? gMainThread : FindMainThread();} - nsIXPCSecurityManager* GetDefaultSecurityManager() const {return mDefaultSecurityManager;} @@ -498,7 +494,6 @@ private: // Singleton instance static nsXPConnect* gSelf; static JSBool gOnceAliveNowDead; - static PRThread* gMainThread; XPCJSRuntime* mRuntime; nsCOMPtr mInterfaceInfoManager; @@ -2098,8 +2093,7 @@ private: #ifdef XPC_CHECK_WRAPPER_THREADSAFETY public: - PRThread* mThread; // Don't want to overload _mOwningThread - static PRThread* gMainThread; + nsCOMPtr mThread; // Don't want to overload _mOwningThread #endif }; diff --git a/mozilla/js/src/xpconnect/src/xpcwrappednative.cpp b/mozilla/js/src/xpconnect/src/xpcwrappednative.cpp index c2ddcf1f1e0..c0955e8580e 100644 --- a/mozilla/js/src/xpconnect/src/xpcwrappednative.cpp +++ b/mozilla/js/src/xpconnect/src/xpcwrappednative.cpp @@ -53,10 +53,6 @@ static void DEBUG_CheckClassInfoClaims(XPCWrappedNative* wrapper); #define DEBUG_CheckClassInfoClaims(wrapper) ((void)0) #endif -#ifdef XPC_CHECK_WRAPPER_THREADSAFETY -PRThread* XPCWrappedNative::gMainThread = nsnull; -#endif - #ifdef XPC_TRACK_WRAPPER_STATS static int DEBUG_TotalWrappedNativeCount; static int DEBUG_TotalLiveWrappedNativeCount; @@ -806,12 +802,9 @@ XPCWrappedNative::Init(XPCCallContext& ccx, JSObject* parent, } #ifdef XPC_CHECK_WRAPPER_THREADSAFETY - if(!gMainThread) - gMainThread = nsXPConnect::GetMainThread(); + mThread = do_GetCurrentThread(); - mThread = PR_GetCurrentThread(); - - if(HasProto() && GetProto()->ClassIsMainThreadOnly() && gMainThread != mThread) + if(HasProto() && GetProto()->ClassIsMainThreadOnly() && !NS_IsMainThread()) DEBUG_ReportWrapperThreadSafetyError(ccx, "MainThread only wrapper created on the wrong thread", this); #endif @@ -3097,18 +3090,17 @@ void DEBUG_CheckWrapperThreadSafety(const XPCWrappedNative* wrapper) if(proto && proto->ClassIsThreadSafe()) return; - PRThread* currentThread = PR_GetCurrentThread(); - + PRBool val; if(proto && proto->ClassIsMainThreadOnly()) { - if(currentThread != wrapper->gMainThread) + if(!NS_IsMainThread()) { XPCCallContext ccx(NATIVE_CALLER); DEBUG_ReportWrapperThreadSafetyError(ccx, "Main Thread Only wrapper accessed on another thread", wrapper); } } - else if(currentThread != wrapper->mThread) + else if(NS_SUCCEEDED(wrapper->mThread->IsOnCurrentThread(&val)) && !val) { XPCCallContext ccx(NATIVE_CALLER); DEBUG_ReportWrapperThreadSafetyError(ccx, diff --git a/mozilla/layout/base/nsCSSFrameConstructor.cpp b/mozilla/layout/base/nsCSSFrameConstructor.cpp index 3c8d881f2eb..1daae0e2952 100644 --- a/mozilla/layout/base/nsCSSFrameConstructor.cpp +++ b/mozilla/layout/base/nsCSSFrameConstructor.cpp @@ -116,8 +116,6 @@ #include "nsImageFrame.h" #include "nsIObjectLoadingContent.h" -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); - #include "nsIDOMWindowInternal.h" #include "nsIMenuFrame.h" @@ -1923,6 +1921,7 @@ nsCSSFrameConstructor::nsCSSFrameConstructor(nsIDocument *aDocument, , mUpdateCount(0) , mQuotesDirty(PR_FALSE) , mCountersDirty(PR_FALSE) + , mRestyleEventPending(PR_FALSE) { if (!gGotXBLFormPrefs) { gGotXBLFormPrefs = PR_TRUE; @@ -1936,9 +1935,6 @@ nsCSSFrameConstructor::nsCSSFrameConstructor(nsIDocument *aDocument, // now what? } - // XXXbz this should be in Init() or something! - mEventQueueService = do_GetService(kEventQueueServiceCID); - #ifdef DEBUG static PRBool gFirstTime = PR_TRUE; if (gFirstTime) { @@ -10866,11 +10862,7 @@ nsCSSFrameConstructor::WillDestroyFrameTree() mCounterManager.Clear(); // Cancel all pending reresolves - mRestyleEventQueue = nsnull; - nsCOMPtr eventQueue; - mEventQueueService->GetSpecialEventQueue(nsIEventQueueService::UI_THREAD_EVENT_QUEUE, - getter_AddRefs(eventQueue)); - eventQueue->RevokeEvents(this); + mWeakSelf.forget(); } //STATIC @@ -13518,6 +13510,12 @@ nsCSSFrameConstructor::PostRestyleEvent(nsIContent* aContent, // Nothing to do here return; } + + if (!mWeakSelf) { + mWeakSelf = this; + if (!mWeakSelf) + return; // out of memory + } RestyleData existingData; existingData.mRestyleHint = nsReStyleHint(0); @@ -13530,24 +13528,22 @@ nsCSSFrameConstructor::PostRestyleEvent(nsIContent* aContent, mPendingRestyles.Put(aContent, existingData); - nsCOMPtr eventQueue; - mEventQueueService->GetSpecialEventQueue(nsIEventQueueService::UI_THREAD_EVENT_QUEUE, - getter_AddRefs(eventQueue)); - - if (eventQueue != mRestyleEventQueue) { - RestyleEvent* ev = new RestyleEvent(this); - if (NS_FAILED(eventQueue->PostEvent(ev))) { - PL_DestroyEvent(ev); + if (!mRestyleEventPending) { + nsCOMPtr ev = new RestyleEvent(mWeakSelf); + if (NS_FAILED(NS_DispatchToCurrentThread(ev))) { + NS_WARNING("failed to dispatch restyle event"); // XXXbz and what? } else { - mRestyleEventQueue = eventQueue; + mRestyleEventPending = PR_TRUE; } } } -void nsCSSFrameConstructor::RestyleEvent::HandleEvent() { - nsCSSFrameConstructor* constructor = - NS_STATIC_CAST(nsCSSFrameConstructor*, owner); +NS_IMETHODIMP nsCSSFrameConstructor::RestyleEvent::Run() { + nsCSSFrameConstructor* constructor = mConstructor; + if (!constructor) + return NS_OK; // event was revoked + nsIViewManager* viewManager = constructor->mPresShell->GetViewManager(); NS_ASSERTION(viewManager, "Must have view manager for update"); @@ -13561,33 +13557,19 @@ void nsCSSFrameConstructor::RestyleEvent::HandleEvent() { // Make sure that any restyles that happen from now on will go into // a new event. - constructor->mRestyleEventQueue = nsnull; + constructor->mRestyleEventPending = PR_FALSE; constructor->ProcessPendingRestyles(); viewManager->EndUpdateViewBatch(NS_VMREFRESH_NO_SYNC); + + return NS_OK; } -PR_STATIC_CALLBACK(void*) -HandleRestyleEvent(PLEvent* aEvent) -{ - nsCSSFrameConstructor::RestyleEvent* evt = - NS_STATIC_CAST(nsCSSFrameConstructor::RestyleEvent*, aEvent); - evt->HandleEvent(); - return nsnull; -} - -PR_STATIC_CALLBACK(void) -DestroyRestyleEvent(PLEvent* aEvent) -{ - delete NS_STATIC_CAST(nsCSSFrameConstructor::RestyleEvent*, aEvent); -} - -nsCSSFrameConstructor::RestyleEvent::RestyleEvent(nsCSSFrameConstructor* aConstructor) +nsCSSFrameConstructor::RestyleEvent::RestyleEvent( + const nsCSSFrameConstructorWeakRef &aConstructor) + : mConstructor(aConstructor) { NS_PRECONDITION(aConstructor, "Must have a constructor!"); - - PL_InitEvent(this, aConstructor, - ::HandleRestyleEvent, ::DestroyRestyleEvent); } nsresult diff --git a/mozilla/layout/base/nsCSSFrameConstructor.h b/mozilla/layout/base/nsCSSFrameConstructor.h index 66ba00a8433..bf48ad2f5df 100644 --- a/mozilla/layout/base/nsCSSFrameConstructor.h +++ b/mozilla/layout/base/nsCSSFrameConstructor.h @@ -44,9 +44,8 @@ #include "nsCounterManager.h" #include "nsDataHashtable.h" #include "nsHashKeys.h" -#include "plevent.h" -#include "nsIEventQueueService.h" -#include "nsIEventQueue.h" +#include "nsThreadUtils.h" +#include "nsTWeakRef.h" class nsIDocument; struct nsFrameItems; @@ -64,6 +63,8 @@ class nsPresContext; class nsStyleChangeList; class nsIFrame; +typedef nsTWeakRef nsCSSFrameConstructorWeakRef; + struct nsFindFrameHint { nsIFrame *mPrimaryFrameForPrevSibling; // weak ref to the primary frame for the content for which we need a frame @@ -77,7 +78,7 @@ class nsCSSFrameConstructor { public: nsCSSFrameConstructor(nsIDocument *aDocument, nsIPresShell* aPresShell); - ~nsCSSFrameConstructor(void) {} + ~nsCSSFrameConstructor(void) { } // Maintain global objects - gXBLService static nsIXBLService * GetXBLService(); @@ -1007,17 +1008,14 @@ public: struct RestyleEvent; friend struct RestyleEvent; - struct RestyleEvent : public PLEvent { - RestyleEvent(nsCSSFrameConstructor* aConstructor); - ~RestyleEvent() { } - void HandleEvent(); + struct RestyleEvent : public nsRunnable { + RestyleEvent(const nsCSSFrameConstructorWeakRef &aConstructor); + NS_IMETHOD Run(); + nsCSSFrameConstructorWeakRef mConstructor; }; friend class nsFrameConstructorState; -protected: - nsCOMPtr mRestyleEventQueue; - private: #ifdef ACCESSIBILITY // If the frame is visible, return the frame type @@ -1046,11 +1044,12 @@ private: PRUint16 mUpdateCount; PRPackedBool mQuotesDirty; PRPackedBool mCountersDirty; + PRPackedBool mRestyleEventPending; + + nsCSSFrameConstructorWeakRef mWeakSelf; nsCOMPtr mTempFrameTreeState; - nsCOMPtr mEventQueueService; - nsDataHashtable mPendingRestyles; static nsIXBLService * gXBLService; diff --git a/mozilla/layout/base/nsDocumentViewer.cpp b/mozilla/layout/base/nsDocumentViewer.cpp index 6dacaa00bdb..14c9ae51be4 100644 --- a/mozilla/layout/base/nsDocumentViewer.cpp +++ b/mozilla/layout/base/nsDocumentViewer.cpp @@ -115,9 +115,6 @@ #include "nsIClipboardHelper.h" -#include "nsIEventQueueService.h" -#include "nsIEventQueue.h" - #include "nsPIDOMWindow.h" #include "nsIFocusController.h" @@ -153,8 +150,6 @@ static const char sPrintOptionsContractID[] = "@mozilla.org/gfx/printsettings-service;1"; // Printing Events -#include "nsIEventQueue.h" -#include "nsIEventQueueService.h" #include "nsPrintPreviewListener.h" #include "nsIDOMHTMLFrameElement.h" diff --git a/mozilla/layout/base/nsFrameManager.cpp b/mozilla/layout/base/nsFrameManager.cpp index ef6bb27b9b0..a740e337c2c 100644 --- a/mozilla/layout/base/nsFrameManager.cpp +++ b/mozilla/layout/base/nsFrameManager.cpp @@ -51,7 +51,6 @@ #include "nsCSSFrameConstructor.h" #include "nsStyleContext.h" #include "nsStyleChangeList.h" -#include "nsIEventQueueService.h" #include "nsIServiceManager.h" #include "nsCOMPtr.h" #include "prthread.h" @@ -110,9 +109,6 @@ #define NOISY_TRACE_FRAME(_msg,_frame); #endif -// Class IID's -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); - // IID's //---------------------------------------------------------------------- diff --git a/mozilla/layout/base/nsPresShell.cpp b/mozilla/layout/base/nsPresShell.cpp index 016870f0fdc..3a7f21a4b23 100644 --- a/mozilla/layout/base/nsPresShell.cpp +++ b/mozilla/layout/base/nsPresShell.cpp @@ -157,6 +157,8 @@ #include "nsIObjectLoadingContent.h" #include "nsNetUtil.h" #include "nsEventDispatcher.h" +#include "nsThreadUtils.h" +#include "nsTWeakRef.h" // Drag & Drop, Clipboard #include "nsWidgetsCID.h" @@ -164,9 +166,6 @@ #include "nsIClipboardHelper.h" #include "nsIDocShellTreeItem.h" #include "nsIURI.h" -#include "nsIEventQueue.h" -#include "nsIEventQueueService.h" -#include "nsEventQueueUtils.h" #include "nsIScrollableFrame.h" #include "prtime.h" #include "prlong.h" @@ -1010,6 +1009,8 @@ ReflowCommandHashMatchEntry(PLDHashTable *table, const PLDHashEntryHdr *entry, // ---------------------------------------------------------------------------- class nsPresShellEventCB; +typedef nsTWeakRef PresShellWeakRef; + class PresShell : public nsIPresShell, public nsIViewObserver, public nsStubDocumentObserver, public nsISelectionController, public nsIObserver, @@ -1380,12 +1381,13 @@ protected: nsCOMPtr mCaret; PRInt16 mSelectionFlags; PRPackedBool mBatchReflows; // When set to true, the pres shell batches reflow commands. + PRPackedBool mReflowEventPending; PresShellViewEventListener *mViewEventListener; - nsCOMPtr mReflowEventQueue; FrameArena mFrameArena; StackArena* mStackArena; nsCOMPtr mDragService; PRInt32 mRCCreatedDuringLoad; // Counter to keep track of reflow commands created during doc + PresShellWeakRef mWeakSelf; // used for list of posted events and attribute changes. To be done // after reflow. @@ -1620,6 +1622,7 @@ PresShell::PresShell() mSelectionFlags = nsISelectionDisplay::DISPLAY_TEXT | nsISelectionDisplay::DISPLAY_IMAGES; mIsThemeSupportDisabled = PR_FALSE; mIsReleasingAnonymousContent = PR_FALSE; + mReflowEventPending = PR_FALSE; new (this) nsFrameManager(); } @@ -1926,13 +1929,7 @@ PresShell::Destroy() } // Revoke pending events - mReflowEventQueue = nsnull; - nsCOMPtr eventQueue; - nsresult rv = NS_GetCurrentEventQ(getter_AddRefs(eventQueue), - nsContentUtils::EventQueueService()); - if (NS_SUCCEEDED(rv)) { - eventQueue->RevokeEvents(this); - } + mWeakSelf.forget(); CancelAllReflowCommands(); @@ -6323,67 +6320,45 @@ PresShell::Thaw() //-------------- Begin Reflow Event Definition ------------------------ -struct ReflowEvent : public PLEvent { - ReflowEvent(nsIPresShell* aPresShell); +struct ReflowEvent : public nsRunnable { + ReflowEvent(const PresShellWeakRef &aPresShell); ~ReflowEvent() { } - void HandleEvent() { - nsCOMPtr presShell = do_QueryReferent(mPresShell); - if (presShell) { + NS_IMETHOD Run() { + PresShell *ps = mPresShell.get(); + if (ps) { #ifdef DEBUG if (VERIFY_REFLOW_NOISY_RC & gVerifyReflowFlags) { - printf("\n*** Handling reflow event: PresShell=%p, event=%p\n", (void*)presShell.get(), (void*)this); + printf("\n*** Handling reflow event: PresShell=%p, event=%p\n", (void*)ps, (void*)this); } #endif - // XXX Statically cast the pres shell pointer so that we can call - // protected methods on the pres shell. (the ReflowEvent struct - // is a friend of the PresShell class) - PresShell* ps = NS_REINTERPRET_CAST(PresShell*, presShell.get()); + // NOTE: the ReflowEvent struct is a friend of the PresShell class PRBool isBatching; ps->ClearReflowEventStatus(); ps->GetReflowBatchingStatus(&isBatching); if (!isBatching) { // Set a kung fu death grip on the view manager associated with the pres shell // before processing that pres shell's reflow commands. Fixes bug 54868. - nsCOMPtr viewManager = presShell->GetViewManager(); + nsCOMPtr viewManager = ps->GetViewManager(); viewManager->BeginUpdateViewBatch(); ps->ProcessReflowCommands(PR_TRUE); viewManager->EndUpdateViewBatch(NS_VMREFRESH_NO_SYNC); // Now, explicitly release the pres shell before the view manager - presShell = nsnull; viewManager = nsnull; } } - else - mPresShell = 0; + return NS_OK; } - nsWeakPtr mPresShell; + PresShellWeakRef mPresShell; }; -static void* PR_CALLBACK HandlePLEvent(PLEvent* aEvent) -{ - ReflowEvent* event = NS_STATIC_CAST(ReflowEvent*, aEvent); - event->HandleEvent(); - return nsnull; -} - -static void PR_CALLBACK DestroyPLEvent(PLEvent* aEvent) -{ - ReflowEvent* event = NS_STATIC_CAST(ReflowEvent*, aEvent); - delete event; -} - - -ReflowEvent::ReflowEvent(nsIPresShell* aPresShell) +ReflowEvent::ReflowEvent(const PresShellWeakRef &aPresShell) + : mPresShell(aPresShell) { NS_ASSERTION(aPresShell, "Null parameters!"); - - mPresShell = do_GetWeakReference(aPresShell); - - PL_InitEvent(this, aPresShell, ::HandlePLEvent, ::DestroyPLEvent); } //-------------- End Reflow Event Definition --------------------------- @@ -6392,21 +6367,19 @@ ReflowEvent::ReflowEvent(nsIPresShell* aPresShell) void PresShell::PostReflowEvent() { - nsCOMPtr eventQueue; - nsContentUtils::EventQueueService()-> - GetSpecialEventQueue(nsIEventQueueService::UI_THREAD_EVENT_QUEUE, - getter_AddRefs(eventQueue)); - - if (eventQueue != mReflowEventQueue && !mIsDestroying && + if (!mReflowEventPending && !mIsDestroying && !mIsReflowing && mReflowCommands.Count() > 0) { - ReflowEvent* ev = new ReflowEvent(NS_STATIC_CAST(nsIPresShell*, this)); - // OOM note: both PostEvent and PL_DestroyEvent accept a null arg. - if (NS_FAILED(eventQueue->PostEvent(ev))) { - NS_ERROR("failed to post reflow event"); - PL_DestroyEvent(ev); + if (!mWeakSelf) { + mWeakSelf = this; + if (!mWeakSelf) + return; // OOM + } + nsCOMPtr ev = new ReflowEvent(mWeakSelf); + if (NS_FAILED(NS_DispatchToCurrentThread(ev))) { + NS_WARNING("failed to dispatch reflow event"); } else { - mReflowEventQueue = eventQueue; + mReflowEventPending = PR_TRUE; #ifdef DEBUG if (VERIFY_REFLOW_NOISY_RC & gVerifyReflowFlags) { printf("\n*** PresShell::PostReflowEvent(), this=%p, event=%p\n", (void*)this, (void*)ev); @@ -6600,7 +6573,7 @@ PresShell::ProcessReflowCommands(PRBool aInterruptible) nsresult PresShell::ClearReflowEventStatus() { - mReflowEventQueue = nsnull; + mReflowEventPending = PR_FALSE; return NS_OK; } diff --git a/mozilla/layout/forms/nsComboboxControlFrame.cpp b/mozilla/layout/forms/nsComboboxControlFrame.cpp index ea3aa3b5ce2..edf75191b4d 100644 --- a/mozilla/layout/forms/nsComboboxControlFrame.cpp +++ b/mozilla/layout/forms/nsComboboxControlFrame.cpp @@ -97,47 +97,23 @@ #include "nsIFontMetrics.h" #endif -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); - -class RedisplayTextEvent : public PLEvent +class RedisplayTextEvent : public nsRunnable { public: - RedisplayTextEvent(nsComboboxControlFrame* aComboboxControlFrame); + RedisplayTextEvent(const nsComboboxControlFrameWeakRef &aControlFrame) + : mControlFrame(aControlFrame) {} - void HandleEvent() + NS_IMETHOD Run() { - NS_STATIC_CAST(nsComboboxControlFrame*, owner) -> - HandleRedisplayTextEvent(); + if (mControlFrame) + mControlFrame->HandleRedisplayTextEvent(); + return NS_OK; } + +private: + nsComboboxControlFrameWeakRef mControlFrame; }; -PR_STATIC_CALLBACK(void*) -HandleRedisplayTextPLEvent(PLEvent* aEvent) -{ - NS_ASSERTION(nsnull != aEvent, "Event is null"); - RedisplayTextEvent* event = NS_STATIC_CAST(RedisplayTextEvent*, aEvent); - - event->HandleEvent(); - - return nsnull; -} - -PR_STATIC_CALLBACK(void) -DestroyRedisplayTextPLEvent(PLEvent* aEvent) -{ - NS_ASSERTION(nsnull != aEvent, "Event is null"); - RedisplayTextEvent* event = NS_STATIC_CAST(RedisplayTextEvent*, aEvent); - - delete event; -} - -RedisplayTextEvent::RedisplayTextEvent(nsComboboxControlFrame* aComboboxControlFrame) -{ - PL_InitEvent(this, aComboboxControlFrame, - ::HandleRedisplayTextPLEvent, - ::DestroyRedisplayTextPLEvent); -} - class nsPresState; #define FIX_FOR_BUG_53259 @@ -414,8 +390,6 @@ nsComboboxControlFrame::Init(nsPresContext* aPresContext, nsStyleContext* aContext, nsIFrame* aPrevInFlow) { - mEventQueueService = do_GetService(kEventQueueServiceCID); - return nsAreaFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow); } @@ -1601,34 +1575,30 @@ nsComboboxControlFrame::RedisplayText(PRInt32 aIndex) // Send reflow command because the new text maybe larger nsresult rv = NS_OK; - if (mDisplayContent && mEventQueueService) { + if (mDisplayContent) { // Don't call ActuallyDisplayText(PR_TRUE) directly here since that // could cause recursive frame construction. See bug 283117 and the comment in // HandleRedisplayTextEvent() below. - nsCOMPtr eventQueue; - rv = mEventQueueService->GetSpecialEventQueue(nsIEventQueueService::UI_THREAD_EVENT_QUEUE, - getter_AddRefs(eventQueue)); - if (eventQueue) { - RedisplayTextEvent* event = new RedisplayTextEvent(this); - if (event) { - // Revoke outstanding events to avoid out-of-order events which could mean - // displaying the wrong text. - if (mRedisplayTextEventPosted) { - eventQueue->RevokeEvents(this); - mRedisplayTextEventPosted = PR_FALSE; - } - rv = eventQueue->PostEvent(event); + nsCOMPtr event = new RedisplayTextEvent(mWeakSelf); + NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY); - if (NS_SUCCEEDED(rv)) { - mRedisplayTextEventPosted = PR_TRUE; - } else { - PL_DestroyEvent(event); - } - } else { - rv = NS_ERROR_OUT_OF_MEMORY; - } + // Revoke outstanding events to avoid out-of-order events which could mean + // displaying the wrong text. + if (mRedisplayTextEventPosted) { + mWeakSelf.forget(); + mRedisplayTextEventPosted = PR_FALSE; } + + if (!mWeakSelf) { + mWeakSelf = this; + if (!mWeakSelf) + return NS_ERROR_OUT_OF_MEMORY; + } + + rv = NS_DispatchToCurrentThread(event); + if (NS_SUCCEEDED(rv)) + mRedisplayTextEventPosted = PR_TRUE; } return rv; } @@ -1956,14 +1926,7 @@ NS_IMETHODIMP nsComboboxControlFrame::Destroy(nsPresContext* aPresContext) { // Revoke queued RedisplayTextEvents - if (mEventQueueService) { - nsCOMPtr eventQueue; - mEventQueueService->GetSpecialEventQueue(nsIEventQueueService::UI_THREAD_EVENT_QUEUE, - getter_AddRefs(eventQueue)); - if (eventQueue) { - eventQueue->RevokeEvents(this); - } - } + mWeakSelf.forget(); nsFormControlFrame::RegUnRegAccessKey(GetPresContext(), NS_STATIC_CAST(nsIFrame*, this), PR_FALSE); diff --git a/mozilla/layout/forms/nsComboboxControlFrame.h b/mozilla/layout/forms/nsComboboxControlFrame.h index 7b88c39ed12..dccc571c70c 100644 --- a/mozilla/layout/forms/nsComboboxControlFrame.h +++ b/mozilla/layout/forms/nsComboboxControlFrame.h @@ -64,6 +64,7 @@ #include "nsIScrollableViewProvider.h" #include "nsIStatefulFrame.h" #include "nsIDOMMouseListener.h" +#include "nsTWeakRef.h" class nsIView; class nsStyleContext; @@ -76,6 +77,8 @@ class nsIScrollableView; */ #define NS_COMBO_FRAME_POPUP_LIST_INDEX (NS_BLOCK_FRAME_ABSOLUTE_LIST_INDEX + 1) +typedef nsTWeakRef nsComboboxControlFrameWeakRef; + class nsComboboxControlFrame : public nsAreaFrame, public nsIFormControlFrame, public nsIComboboxControlFrame, @@ -259,6 +262,8 @@ protected: PRPackedBool mInRedisplayText; PRPackedBool mRedisplayTextEventPosted; + nsComboboxControlFrameWeakRef mWeakSelf; + PRInt32 mRecentSelectedIndex; PRInt32 mDisplayedIndex; nsString mDisplayedOptionText; @@ -267,8 +272,6 @@ protected: // then open or close the combo box. nsCOMPtr mButtonListener; - nsCOMPtr mEventQueueService; - // static class data member for Bug 32920 // only one control can be focused at a time static nsComboboxControlFrame * mFocused; diff --git a/mozilla/layout/generic/nsGfxScrollFrame.cpp b/mozilla/layout/generic/nsGfxScrollFrame.cpp index d2b5f841a44..b2cddbd9252 100644 --- a/mozilla/layout/generic/nsGfxScrollFrame.cpp +++ b/mozilla/layout/generic/nsGfxScrollFrame.cpp @@ -71,7 +71,6 @@ #include "nsContentCreatorFunctions.h" #include "nsISupportsPrimitives.h" #include "nsIPresShell.h" -#include "nsIEventQueueService.h" #include "nsReflowPath.h" #include "nsAutoPtr.h" #include "nsPresState.h" @@ -82,8 +81,7 @@ #include "nsIAccessibilityService.h" #endif #include "nsDisplayList.h" - -static const char kEventQueueServiceCID[] = NS_EVENTQUEUESERVICE_CONTRACTID; +#include "nsThreadUtils.h" //---------------------------------------------------------------------- @@ -1340,9 +1338,8 @@ nsGfxScrollFrameInner::nsGfxScrollFrameInner(nsContainerFrame* aOuter, PRBool aI nsGfxScrollFrameInner::~nsGfxScrollFrameInner() { - if (mScrollEventQueue) { - mScrollEventQueue->RevokeEvents(this); - } + // "revoke" any pending events + mWeakSelf.forget(); } NS_IMETHODIMP_(nsrefcnt) nsGfxScrollFrameInner::AddRef(void) @@ -1845,24 +1842,24 @@ void nsGfxScrollFrameInner::CurPosAttributeChanged(nsIContent* aContent, PRInt32 } /* ============= Scroll events ========== */ -PR_STATIC_CALLBACK(void*) HandleScrollEvent(PLEvent* aEvent) -{ - NS_ASSERTION(nsnull != aEvent,"Event is null"); - nsGfxScrollFrameInner* inner = NS_STATIC_CAST(nsGfxScrollFrameInner*, aEvent->owner); - inner->FireScrollEvent(); - return nsnull; -} -PR_STATIC_CALLBACK(void) DestroyScrollEvent(PLEvent* aEvent) -{ - NS_ASSERTION(nsnull != aEvent,"Event is null"); - delete aEvent; -} +class nsGfxScrollEvent : public nsRunnable { +public: + nsGfxScrollEvent(const nsGfxScrollFrameInnerWeakRef &inner) + : mInner(inner) {} + NS_IMETHOD Run() { + if (mInner) + mInner->FireScrollEvent(); + return NS_OK; + } +private: + nsGfxScrollFrameInnerWeakRef mInner; +}; void nsGfxScrollFrameInner::FireScrollEvent() { - mScrollEventQueue = nsnull; + mScrollEventPending = PR_FALSE; nsScrollbarEvent event(PR_TRUE, NS_SCROLL_EVENT, nsnull); nsEventStatus status = nsEventStatus_eIgnore; @@ -1886,26 +1883,21 @@ nsGfxScrollFrameInner::FireScrollEvent() void nsGfxScrollFrameInner::PostScrollEvent() { - nsCOMPtr service = do_GetService(kEventQueueServiceCID); - NS_ASSERTION(service, "No event service"); - nsCOMPtr eventQueue; - service->GetSpecialEventQueue( - nsIEventQueueService::UI_THREAD_EVENT_QUEUE, getter_AddRefs(eventQueue)); - NS_ASSERTION(eventQueue, "Event queue is null"); - - if (eventQueue == mScrollEventQueue) + if (mScrollEventPending) return; - - PLEvent* ev = new PLEvent; - if (!ev) - return; - PL_InitEvent(ev, this, ::HandleScrollEvent, ::DestroyScrollEvent); - if (mScrollEventQueue) { - mScrollEventQueue->RevokeEvents(this); + if (!mWeakSelf) { + mWeakSelf = this; + if (!mWeakSelf) + return; // out of memory + } + + nsCOMPtr ev = new nsGfxScrollEvent(mWeakSelf); + if (NS_FAILED(NS_DispatchToCurrentThread(ev))) { + NS_WARNING("failed to dispatch scroll event"); + } else { + mScrollEventPending = PR_TRUE; } - eventQueue->PostEvent(ev); - mScrollEventQueue = eventQueue; } void diff --git a/mozilla/layout/generic/nsGfxScrollFrame.h b/mozilla/layout/generic/nsGfxScrollFrame.h index 38770188816..26545253873 100644 --- a/mozilla/layout/generic/nsGfxScrollFrame.h +++ b/mozilla/layout/generic/nsGfxScrollFrame.h @@ -44,7 +44,7 @@ #include "nsIScrollPositionListener.h" #include "nsIStatefulFrame.h" #include "nsGUIEvent.h" -#include "nsIEventQueue.h" +#include "nsTWeakRef.h" class nsISupportsArray; class nsIScrollableView; @@ -57,6 +57,8 @@ class nsIScrollFrameInternal; class nsPresState; struct ScrollReflowState; +typedef nsTWeakRef nsGfxScrollFrameInnerWeakRef; + class nsGfxScrollFrameInner : public nsIScrollPositionListener { public: NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr); @@ -133,7 +135,7 @@ public: const nsRect& aOldScrollArea, const nsRect& aScrollArea); - nsCOMPtr mScrollEventQueue; + nsGfxScrollFrameInnerWeakRef mWeakSelf; nsIScrollableView* mScrollableView; nsIBox* mHScrollbarBox; nsIBox* mVScrollbarBox; @@ -170,6 +172,7 @@ public: // which overflow states have changed. PRPackedBool mHorizontalOverflow:1; PRPackedBool mVerticalOverflow:1; + PRPackedBool mScrollEventPending:1; }; /** diff --git a/mozilla/layout/generic/nsImageFrame.cpp b/mozilla/layout/generic/nsImageFrame.cpp index 0573d74a5c4..30c4ae46ce7 100644 --- a/mozilla/layout/generic/nsImageFrame.cpp +++ b/mozilla/layout/generic/nsImageFrame.cpp @@ -88,9 +88,6 @@ #include "imgIContainer.h" #include "imgILoader.h" -#include "nsIEventQueueService.h" -#include "plevent.h" - #include "nsContentPolicyUtils.h" #include "nsCSSFrameConstructor.h" #include "nsIPrefBranch2.h" diff --git a/mozilla/layout/generic/nsObjectFrame.h b/mozilla/layout/generic/nsObjectFrame.h index 329cbb37346..7d1cbb6f0f1 100644 --- a/mozilla/layout/generic/nsObjectFrame.h +++ b/mozilla/layout/generic/nsObjectFrame.h @@ -37,6 +37,10 @@ #ifndef nsObjectFrame_h___ #define nsObjectFrame_h___ +#ifdef XP_WIN +#include +#endif + #include "nsIObjectFrame.h" #include "nsFrame.h" diff --git a/mozilla/layout/generic/nsSelection.cpp b/mozilla/layout/generic/nsSelection.cpp index 4348506a0ec..382844ce126 100644 --- a/mozilla/layout/generic/nsSelection.cpp +++ b/mozilla/layout/generic/nsSelection.cpp @@ -81,6 +81,8 @@ static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID); #include "nsIDOMText.h" #include "nsContentUtils.h" +#include "nsThreadUtils.h" +#include "nsTWeakRef.h" //included for desired x position; #include "nsPresContext.h" @@ -94,8 +96,6 @@ static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID); #include "nsIDeviceContext.h" #include "nsITimer.h" #include "nsIServiceManager.h" -#include "nsIEventQueue.h" -#include "nsIEventQueueService.h" // notifications #include "nsIDOMDocument.h" @@ -183,6 +183,8 @@ struct CachedOffsetForFrame { PRPackedBool mCanCacheFrameOffset; // cached frame offset is valid? }; +typedef nsTWeakRef nsTypedSelectionWeakRef; + class nsTypedSelection : public nsISelection, public nsISelectionPrivate, public nsSupportsWeakReference @@ -281,9 +283,9 @@ private: SelectionType mType;//type of this nsTypedSelection; nsAutoScrollTimer *mAutoScrollTimer; // timer for autoscrolling. nsCOMArray mSelectionListeners; - PRBool mTrueDirection; - nsCOMPtr mEventQueue; - PRBool mScrollEventPosted; + PRPackedBool mTrueDirection; + PRPackedBool mScrollEventPosted; + nsTypedSelectionWeakRef mWeakSelf; CachedOffsetForFrame *mCachedOffsetForFrame; }; @@ -4265,10 +4267,7 @@ nsTypedSelection::~nsTypedSelection() NS_RELEASE(mAutoScrollTimer); } - if (mEventQueue && mScrollEventPosted) { - mEventQueue->RevokeEvents(this); - mScrollEventPosted = PR_FALSE; - } + mWeakSelf.forget(); delete mCachedOffsetForFrame; } @@ -7060,88 +7059,55 @@ nsTypedSelection::ScrollRectIntoView(nsIScrollableView *aScrollableView, return rv; } -static void* PR_CALLBACK HandlePLEvent(PLEvent* aEvent); -static void PR_CALLBACK DestroyPLEvent(PLEvent* aEvent); - -struct nsScrollSelectionIntoViewEvent : public PLEvent { - nsScrollSelectionIntoViewEvent(nsTypedSelection *aTypedSelection, SelectionRegion aRegion) { - if (!aTypedSelection) - return; - - mTypedSelection = aTypedSelection; - mRegion = aRegion; - - PL_InitEvent(this, aTypedSelection, ::HandlePLEvent, ::DestroyPLEvent); +struct nsScrollSelectionIntoViewEvent : public nsRunnable { + nsScrollSelectionIntoViewEvent(const nsTypedSelectionWeakRef &aTypedSelection, + SelectionRegion aRegion) + : mTypedSelection(aTypedSelection), + mRegion(aRegion) { + NS_ASSERTION(aTypedSelection, "null parameter"); } - ~nsScrollSelectionIntoViewEvent() {} + NS_IMETHOD Run() { + nsTypedSelection *sel = mTypedSelection.get(); + if (!sel) + return NS_OK; // event revoked - void HandleEvent() { - mTypedSelection->mScrollEventPosted = PR_FALSE; - - if (!mTypedSelection) - return; - - mTypedSelection->ScrollIntoView(mRegion, PR_TRUE); + sel->mScrollEventPosted = PR_FALSE; + sel->ScrollIntoView(mRegion, PR_TRUE); + return NS_OK; } - nsTypedSelection *mTypedSelection; - SelectionRegion mRegion; + nsTypedSelectionWeakRef mTypedSelection; + SelectionRegion mRegion; }; -static void* PR_CALLBACK HandlePLEvent(PLEvent* aEvent) -{ - nsScrollSelectionIntoViewEvent* event = - NS_STATIC_CAST(nsScrollSelectionIntoViewEvent*, aEvent); - NS_ASSERTION(nsnull != event,"Event is null"); - event->HandleEvent(); - return nsnull; -} - -static void PR_CALLBACK DestroyPLEvent(PLEvent* aEvent) -{ - nsScrollSelectionIntoViewEvent* event = - NS_STATIC_CAST(nsScrollSelectionIntoViewEvent*, aEvent); - NS_ASSERTION(nsnull != event,"Event is null"); - delete event; -} - nsresult nsTypedSelection::PostScrollSelectionIntoViewEvent(SelectionRegion aRegion) { - static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); + if (mScrollEventPosted) { + // We've already posted an event, revoke it and + // place a new one at the end of the queue to make + // sure that any new pending reflow events are processed + // before we scroll. This will insure that we scroll + // to the correct place on screen. - if (!mEventQueue) { - nsresult rv; - - // Cache the event queue of the current UI thread - nsCOMPtr eventService = do_GetService(kEventQueueServiceCID, &rv); - if (NS_SUCCEEDED(rv) && (nsnull != eventService)) { // XXX this implies that the UI is the current thread. - rv = eventService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(mEventQueue)); - } + mWeakSelf.forget(); + mScrollEventPosted = PR_FALSE; } - if (mEventQueue) { - if (mScrollEventPosted) { - // We've already posted an event, revoke it and - // place a new one at the end of the queue to make - // sure that any new pending reflow events are processed - // before we scroll. This will insure that we scroll - // to the correct place on screen. - - mEventQueue->RevokeEvents(this); - mScrollEventPosted = PR_FALSE; - } - - nsScrollSelectionIntoViewEvent *ev = new nsScrollSelectionIntoViewEvent(this, aRegion); - if (ev) { - mEventQueue->PostEvent(ev); - mScrollEventPosted = PR_TRUE; - return NS_OK; - } + if (!mWeakSelf) { + mWeakSelf = this; + if (!mWeakSelf) + return NS_ERROR_OUT_OF_MEMORY; } - return NS_ERROR_FAILURE; + nsCOMPtr ev = + new nsScrollSelectionIntoViewEvent(mWeakSelf, aRegion); + if (NS_FAILED(NS_DispatchToCurrentThread(ev))) + return NS_ERROR_UNEXPECTED; + + mScrollEventPosted = PR_TRUE; + return NS_OK; } NS_IMETHODIMP diff --git a/mozilla/layout/printing/nsPrintEngine.cpp b/mozilla/layout/printing/nsPrintEngine.cpp index 15d749d5b47..d71c3b18dfd 100644 --- a/mozilla/layout/printing/nsPrintEngine.cpp +++ b/mozilla/layout/printing/nsPrintEngine.cpp @@ -64,10 +64,8 @@ static const char sPrintSettingsServiceContractID[] = "@mozilla.org/gfx/printset static const char sPrintOptionsContractID[] = "@mozilla.org/gfx/printsettings-service;1"; // Printing Events -#include "nsIEventQueue.h" -#include "nsIEventQueueService.h" -#include "nsEventQueueUtils.h" #include "nsPrintPreviewListener.h" +#include "nsThreadUtils.h" // Printing #include "nsIWebBrowserPrint.h" @@ -162,9 +160,6 @@ static const char kPrintingPromptService[] = "@mozilla.org/embedcomp/printingpro #include "nsIContentViewerContainer.h" #include "nsIContentViewer.h" -#include "nsIEventQueueService.h" -#include "nsIEventQueue.h" - #include "nsPIDOMWindow.h" #include "nsIFocusController.h" @@ -4408,66 +4403,30 @@ nsPrintEngine::Observe(nsISupports *aSubject, const char *aTopic, const PRUnicha //--------------------------------------------------------------- //-- PLEvent Notification //--------------------------------------------------------------- -PR_STATIC_CALLBACK(void*) HandlePLEvent(PLEvent* aEvent) -{ - nsIDocumentViewerPrint *docViewerPrint = (nsIDocumentViewerPrint*)PL_GetEventOwner(aEvent); - - NS_ASSERTION(docViewerPrint, "The event owner is null."); - if (docViewerPrint) { - docViewerPrint->OnDonePrinting(); +class nsPrintCompletionEvent : public nsRunnable { +public: + nsPrintCompletionEvent(nsIDocumentViewerPrint *docViewerPrint) + : mDocViewerPrint(docViewerPrint) { + NS_ASSERTION(mDocViewerPrint, "mDocViewerPrint is null."); } - return nsnull; -} + NS_IMETHOD Run() { + if (mDocViewerPrint) + mDocViewerPrint->OnDonePrinting(); + return NS_OK; + } -//------------------------------------------------------------------------ -PR_STATIC_CALLBACK(void) DestroyPLEvent(PLEvent* aEvent) -{ - nsIDocumentViewerPrint *docViewerPrint = (nsIDocumentViewerPrint*)PL_GetEventOwner(aEvent); - NS_IF_RELEASE(docViewerPrint); +private: + nsCOMPtr mDocViewerPrint; +}; - delete aEvent; -} //----------------------------------------------------------- void nsPrintEngine::FirePrintCompletionEvent() { - static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); - - nsCOMPtr event_service = do_GetService(kEventQueueServiceCID); - - if (!event_service) - { - NS_WARNING("Failed to get event queue service"); - return; - } - - nsCOMPtr event_queue; - - event_service->GetThreadEventQueue(NS_CURRENT_THREAD, - getter_AddRefs(event_queue)); - - if (!event_queue) - { - NS_WARNING("Failed to get event queue from service"); - return; - } - - PLEvent *event = new PLEvent; - - if (!event) - { - NS_WARNING("Out of memory?"); - return; - } - - PL_InitEvent(event, mDocViewerPrint, ::HandlePLEvent, ::DestroyPLEvent); - - // The event owns the docviewer pointer now. - NS_ADDREF(mDocViewerPrint); - - event_queue->PostEvent(event); - return; + nsCOMPtr event = new nsPrintCompletionEvent(mDocViewerPrint); + if (NS_FAILED(NS_DispatchToCurrentThread(event))) + NS_WARNING("failed to dispatch print completion event"); } //--------------------------------------------------------------- diff --git a/mozilla/layout/style/nsCSSLoader.cpp b/mozilla/layout/style/nsCSSLoader.cpp index 6b77e3a71f1..08779a37d5c 100644 --- a/mozilla/layout/style/nsCSSLoader.cpp +++ b/mozilla/layout/style/nsCSSLoader.cpp @@ -74,9 +74,7 @@ #include "nsICSSLoader.h" #include "nsICSSParser.h" #include "nsICSSImportRule.h" -#include "plevent.h" -#include "nsIEventQueue.h" -#include "nsIEventQueueService.h" +#include "nsThreadUtils.h" #include "nsHTMLAtoms.h" #ifdef MOZ_XUL @@ -137,7 +135,7 @@ static const char* const gStateStrings[] = { /******************************** * SheetLoadData implementation * ********************************/ -NS_IMPL_ISUPPORTS1(SheetLoadData, nsIUnicharStreamLoaderObserver) +NS_IMPL_ISUPPORTS2(SheetLoadData, nsIUnicharStreamLoaderObserver, nsIRunnable) SheetLoadData::SheetLoadData(CSSLoaderImpl* aLoader, const nsSubstring& aTitle, @@ -237,6 +235,14 @@ SheetLoadData::~SheetLoadData() NS_IF_RELEASE(mNext); } +NS_IMETHODIMP +SheetLoadData::Run() +{ + mLoader->HandleLoadEvent(this); + mLoader->DestroyLoadEvent(this); + return NS_OK; +} + /************************* * Loader Implementation * *************************/ @@ -1920,11 +1926,7 @@ CSSLoaderImpl::InternalLoadNonDocumentSheet(nsIURI* aURL, return rv; } -PR_BEGIN_EXTERN_C -PR_STATIC_CALLBACK(void*) HandleStyleSheetLoadedEvent(PLEvent* aEvent); -PR_STATIC_CALLBACK(void) DestroyStyleSheetLoadedEvent(PLEvent* aEvent); -PR_END_EXTERN_C - +#if 0 PR_STATIC_CALLBACK(void*) HandleStyleSheetLoadedEvent(PLEvent* aEvent) { @@ -1939,6 +1941,7 @@ DestroyStyleSheetLoadedEvent(PLEvent* aEvent) SheetLoadData* data = NS_STATIC_CAST(SheetLoadData*, aEvent); data->mLoader->DestroyLoadEvent(data); } +#endif nsresult CSSLoaderImpl::PostLoadEvent(nsIURI* aURI, @@ -1953,13 +1956,7 @@ CSSLoaderImpl::PostLoadEvent(nsIURI* aURI, // observer, since we may need to unblock the parser // NS_PRECONDITION(aObserver, "Must have observer"); - nsCOMPtr eventQ; - nsresult rv = nsContentUtils::EventQueueService()-> - GetSpecialEventQueue(nsIEventQueueService::UI_THREAD_EVENT_QUEUE, - getter_AddRefs(eventQ)); - NS_ENSURE_TRUE(eventQ, rv); - - SheetLoadData* evt = + SheetLoadData *evt = new SheetLoadData(this, EmptyString(), // title doesn't matter here aParserToUnblock, aURI, @@ -1971,9 +1968,6 @@ CSSLoaderImpl::PostLoadEvent(nsIURI* aURI, NS_ADDREF(evt); - PL_InitEvent(evt, this, ::HandleStyleSheetLoadedEvent, - ::DestroyStyleSheetLoadedEvent); - // We'll unblock onload when we destroy the event, so make sure to block it // now. We unblock from destruction, not firing, just in case events get // revoked for some reason. @@ -1982,13 +1976,14 @@ CSSLoaderImpl::PostLoadEvent(nsIURI* aURI, } if (!mPostedEvents.AppendElement(evt)) { - PL_DestroyEvent(evt); + NS_RELEASE(evt); return NS_ERROR_OUT_OF_MEMORY; } - rv = eventQ->PostEvent(evt); + nsresult rv = NS_DispatchToCurrentThread(evt); if (NS_FAILED(rv)) { - PL_DestroyEvent(evt); + NS_WARNING("failed to dispatch stylesheet load event"); + DestroyLoadEvent(evt); } else { // We want to notify the observer for this data. We didn't want to set // this earlier, since we would have returned an error _and_ notified. diff --git a/mozilla/layout/style/nsCSSLoader.h b/mozilla/layout/style/nsCSSLoader.h index 93673484009..156c8c244fc 100644 --- a/mozilla/layout/style/nsCSSLoader.h +++ b/mozilla/layout/style/nsCSSLoader.h @@ -60,6 +60,7 @@ class nsICSSImportRule; class nsMediaList; #include "nsICSSLoader.h" +#include "nsIRunnable.h" #include "nsIUnicharStreamLoader.h" #include "nsCOMPtr.h" #include "nsCOMArray.h" @@ -67,7 +68,6 @@ class nsMediaList; #include "nsURIHashKey.h" #include "nsInterfaceHashtable.h" #include "nsDataHashtable.h" -#include "plevent.h" /** * OVERALL ARCHITECTURE @@ -101,7 +101,7 @@ class nsMediaList; * Data needed to properly load a stylesheet * *********************************************/ -class SheetLoadData : public PLEvent, +class SheetLoadData : public nsIRunnable, public nsIUnicharStreamLoaderObserver { public: @@ -133,6 +133,7 @@ public: already_AddRefed GetReferrerURI(); NS_DECL_ISUPPORTS + NS_DECL_NSIRUNNABLE NS_DECL_NSIUNICHARSTREAMLOADEROBSERVER // Hold a ref to the CSSLoader so we can call back to it to let it diff --git a/mozilla/layout/xul/base/src/nsImageBoxFrame.cpp b/mozilla/layout/xul/base/src/nsImageBoxFrame.cpp index 61a2ca03b34..0b99c83ba12 100644 --- a/mozilla/layout/xul/base/src/nsImageBoxFrame.cpp +++ b/mozilla/layout/xul/base/src/nsImageBoxFrame.cpp @@ -83,13 +83,13 @@ #include "nsIDOMHTMLMapElement.h" #include "nsBoxLayoutState.h" #include "nsIDOMDocument.h" -#include "nsIEventQueueService.h" #include "nsTransform2D.h" #include "nsITheme.h" #include "nsIServiceManager.h" #include "nsIURI.h" #include "nsNetUtil.h" +#include "nsThreadUtils.h" #include "nsGUIEvent.h" #include "nsEventDispatcher.h" #include "nsDisplayList.h" @@ -98,73 +98,50 @@ #define ONLOAD_CALLED_TOO_EARLY 1 -static void PR_CALLBACK -HandleImagePLEvent(nsIContent *aContent, PRUint32 aMessage, - PRUint32 aEventFlags) +class nsImageBoxFrameEvent : public nsRunnable { - if (!aContent) { - NS_ERROR("null node passed to HandleImagePLEvent!"); +public: + nsImageBoxFrameEvent(nsIContent *content, PRUint32 message) + : mContent(content), mMessage(message) {} - return; - } + NS_IMETHOD Run(); - nsIDocument* doc = aContent->GetOwnerDoc(); +private: + nsCOMPtr mContent; + PRUint32 mMessage; +}; +NS_IMETHODIMP +nsImageBoxFrameEvent::Run() +{ + nsIDocument* doc = mContent->GetOwnerDoc(); if (!doc) { - return; + return NS_OK; } nsIPresShell *pres_shell = doc->GetShellAt(0); if (!pres_shell) { - return; + return NS_OK; } nsCOMPtr pres_context = pres_shell->GetPresContext(); if (!pres_context) { - return; + return NS_OK; } nsEventStatus status = nsEventStatus_eIgnore; - nsEvent event(PR_TRUE, aMessage); + nsEvent event(PR_TRUE, mMessage); - event.flags |= aEventFlags; - nsEventDispatcher::Dispatch(aContent, pres_context, &event, nsnull, &status); + event.flags = NS_EVENT_FLAG_INIT; + if (mMessage == NS_IMAGE_LOAD) { + event.flags |= NS_EVENT_FLAG_CANT_BUBBLE; + } + + nsEventDispatcher::Dispatch(mContent, pres_context, &event, nsnull, &status); + return NS_OK; } -static void* PR_CALLBACK -HandleImageOnloadPLEvent(PLEvent *aEvent) -{ - nsIContent *content = (nsIContent *)PL_GetEventOwner(aEvent); - - HandleImagePLEvent(content, NS_IMAGE_LOAD, - NS_EVENT_FLAG_CANT_BUBBLE); - - // XXXldb Why not put this in DestroyImagePLEvent? - NS_RELEASE(content); - - return nsnull; -} - -static void* PR_CALLBACK -HandleImageOnerrorPLEvent(PLEvent *aEvent) -{ - nsIContent *content = (nsIContent *)PL_GetEventOwner(aEvent); - - HandleImagePLEvent(content, NS_IMAGE_ERROR, NS_EVENT_FLAG_CANT_BUBBLE); - - // XXXldb Why not put this in DestroyImagePLEvent? - NS_RELEASE(content); - - return nsnull; -} - -static void PR_CALLBACK -DestroyImagePLEvent(PLEvent* aEvent) -{ - delete aEvent; -} - -// Fire off a PLEvent that'll asynchronously call the image elements +// Fire off an event that'll asynchronously call the image elements // onload handler once handled. This is needed since the image library // can't decide if it wants to call it's observer methods // synchronously or asynchronously. If an image is loaded from the @@ -172,65 +149,15 @@ DestroyImagePLEvent(PLEvent* aEvent) // is loaded from the netswork the notifications come back // asynchronously. -void +static void FireDOMEvent(nsIContent* aContent, PRUint32 aMessage) { - static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); + NS_ASSERTION(aMessage == NS_IMAGE_LOAD || aMessage == NS_IMAGE_ERROR, + "invalid message"); - nsCOMPtr event_service = - do_GetService(kEventQueueServiceCID); - - if (!event_service) { - NS_WARNING("Failed to get event queue service"); - - return; - } - - nsCOMPtr event_queue; - - event_service->GetThreadEventQueue(NS_CURRENT_THREAD, - getter_AddRefs(event_queue)); - - if (!event_queue) { - NS_WARNING("Failed to get event queue from service"); - - return; - } - - PLEvent *event = new PLEvent; - - if (!event) { - // Out of memory, but none of our callers care, so just warn and - // don't fire the event - - NS_WARNING("Out of memory?"); - - return; - } - - PLHandleEventProc f; - - switch (aMessage) { - case NS_IMAGE_LOAD : - f = ::HandleImageOnloadPLEvent; - - break; - case NS_IMAGE_ERROR : - f = ::HandleImageOnerrorPLEvent; - - break; - default: - NS_WARNING("Huh, I don't know how to fire this type of event?!"); - - return; - } - - PL_InitEvent(event, aContent, f, ::DestroyImagePLEvent); - - // The event owns the content pointer now. - NS_ADDREF(aContent); - - event_queue->PostEvent(event); + nsCOMPtr event = new nsImageBoxFrameEvent(aContent, aMessage); + if (NS_FAILED(NS_DispatchToCurrentThread(event))) + NS_WARNING("failed to dispatch image event"); } // diff --git a/mozilla/layout/xul/base/src/tree/src/nsTreeSelection.cpp b/mozilla/layout/xul/base/src/tree/src/nsTreeSelection.cpp index 850213a38b0..9777d1fd9f3 100644 --- a/mozilla/layout/xul/base/src/tree/src/nsTreeSelection.cpp +++ b/mozilla/layout/xul/base/src/tree/src/nsTreeSelection.cpp @@ -612,21 +612,12 @@ NS_IMETHODIMP nsTreeSelection::SetCurrentIndex(PRInt32 aIndex) nsCOMPtr treeDOMNode(do_QueryInterface(treeElt)); NS_ENSURE_TRUE(treeDOMNode, NS_ERROR_UNEXPECTED); - nsPLDOMEvent *event = new nsPLDOMEvent(treeDOMNode, + nsRefPtr event = new nsPLDOMEvent(treeDOMNode, NS_LITERAL_STRING("DOMMenuItemActive")); + if (!event) + return NS_ERROR_OUT_OF_MEMORY; - nsresult rv; - if (event) { - rv = event->PostDOMEvent(); - if (NS_FAILED(rv)) { - PL_DestroyEvent(event); - } - } - else { - rv = NS_ERROR_OUT_OF_MEMORY; - } - - return rv; + return event->PostDOMEvent(); } #define ADD_NEW_RANGE(macro_range, macro_selection, macro_start, macro_end) \ diff --git a/mozilla/mailnews/addrbook/src/nsAbLDAPDirectoryQuery.cpp b/mozilla/mailnews/addrbook/src/nsAbLDAPDirectoryQuery.cpp index 6c2abf03bcc..21e57da1d4b 100644 --- a/mozilla/mailnews/addrbook/src/nsAbLDAPDirectoryQuery.cpp +++ b/mozilla/mailnews/addrbook/src/nsAbLDAPDirectoryQuery.cpp @@ -402,10 +402,10 @@ NS_IMETHODIMP nsAbQueryLDAPMessageListener::OnLDAPInit(nsILDAPConnection *aConn, NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr proxyListener; - rv = NS_GetProxyForObject(NS_UI_THREAD_EVENTQ, + rv = NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD, NS_GET_IID(nsILDAPMessageListener), NS_STATIC_CAST(nsILDAPMessageListener *, this), - PROXY_SYNC | PROXY_ALWAYS, + NS_PROXY_SYNC | NS_PROXY_ALWAYS, getter_AddRefs(proxyListener)); rv = ldapOperation->Init(mConnection, proxyListener, nsnull); @@ -471,13 +471,11 @@ nsresult nsAbQueryLDAPMessageListener::OnLDAPMessageBind (nsILDAPMessage *aMessa mSearchOperation = do_CreateInstance(NS_LDAPOPERATION_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr proxyMgr = - do_GetService(NS_XPCOMPROXY_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr proxyListener; - rv = proxyMgr->GetProxyForObject( NS_UI_THREAD_EVENTQ, NS_GET_IID(nsILDAPMessageListener), - this, PROXY_SYNC | PROXY_ALWAYS, getter_AddRefs(proxyListener)); + rv = NS_GetProxyForObject( NS_PROXY_TO_MAIN_THREAD, + NS_GET_IID(nsILDAPMessageListener), + this, NS_PROXY_SYNC | NS_PROXY_ALWAYS, + getter_AddRefs(proxyListener)); NS_ENSURE_SUCCESS(rv, rv); rv = mSearchOperation->Init (mConnection, proxyListener, nsnull); diff --git a/mozilla/mailnews/addrbook/src/nsAbLDAPReplicationData.cpp b/mozilla/mailnews/addrbook/src/nsAbLDAPReplicationData.cpp index 265d8195a71..406c4696039 100644 --- a/mozilla/mailnews/addrbook/src/nsAbLDAPReplicationData.cpp +++ b/mozilla/mailnews/addrbook/src/nsAbLDAPReplicationData.cpp @@ -132,10 +132,10 @@ NS_IMETHODIMP nsAbLDAPProcessReplicationData::OnLDAPInit(nsILDAPConnection *aCon } nsCOMPtr listener; - nsresult rv = NS_GetProxyForObject(NS_CURRENT_EVENTQ, + nsresult rv = NS_GetProxyForObject(NS_PROXY_TO_CURRENT_THREAD, NS_GET_IID(nsILDAPMessageListener), NS_STATIC_CAST(nsILDAPMessageListener*, this), - PROXY_SYNC | PROXY_ALWAYS, + NS_PROXY_SYNC | NS_PROXY_ALWAYS, getter_AddRefs(listener)); if(NS_FAILED(rv)) { Done(PR_FALSE); diff --git a/mozilla/mailnews/addrbook/src/nsAbLDAPReplicationQuery.cpp b/mozilla/mailnews/addrbook/src/nsAbLDAPReplicationQuery.cpp index 0e9eae5c079..4aad4346760 100644 --- a/mozilla/mailnews/addrbook/src/nsAbLDAPReplicationQuery.cpp +++ b/mozilla/mailnews/addrbook/src/nsAbLDAPReplicationQuery.cpp @@ -144,10 +144,10 @@ NS_IMETHODIMP nsAbLDAPReplicationQuery::ConnectToLDAPServer(nsILDAPURL *aURL, co // Initiate LDAP message listener to the current thread nsCOMPtr listener; - rv = NS_GetProxyForObject(NS_CURRENT_EVENTQ, + rv = NS_GetProxyForObject(NS_PROXY_TO_CURRENT_THREAD, NS_GET_IID(nsILDAPMessageListener), NS_STATIC_CAST(nsILDAPMessageListener*, mDataProcessor), - PROXY_SYNC | PROXY_ALWAYS, + NS_PROXY_SYNC | NS_PROXY_ALWAYS, getter_AddRefs(listener)); if (!listener) return NS_ERROR_FAILURE; diff --git a/mozilla/mailnews/addrbook/src/nsAbRDFDataSource.cpp b/mozilla/mailnews/addrbook/src/nsAbRDFDataSource.cpp index e19948139ba..6fbe4bfe82b 100644 --- a/mozilla/mailnews/addrbook/src/nsAbRDFDataSource.cpp +++ b/mozilla/mailnews/addrbook/src/nsAbRDFDataSource.cpp @@ -48,8 +48,6 @@ #include "nsRDFCID.h" #include "nsIRDFNode.h" #include "nsEnumeratorUtils.h" -#include "nsIThread.h" -#include "nsIEventQueueService.h" #include "nsIProxyObjectManager.h" #include "nsString.h" @@ -57,6 +55,7 @@ #include "nsXPIDLString.h" #include "nsAutoLock.h" #include "nsIServiceManager.h" +#include "nsThreadUtils.h" // this is used for notification of observers using nsVoidArray typedef struct _nsAbRDFNotification { @@ -136,34 +135,21 @@ nsresult nsAbRDFDataSource::CreateProxyObserver (nsIRDFObserver* observer, { nsresult rv; - nsCOMPtr eventQSvc = do_GetService (NS_EVENTQUEUESERVICE_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - - // Get the UI event queue - nsCOMPtr uiQueue; - rv = eventQSvc->GetSpecialEventQueue ( - nsIEventQueueService::UI_THREAD_EVENT_QUEUE, - getter_AddRefs (uiQueue)); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr proxyMgr = - do_GetService(NS_XPCOMPROXY_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - - // Proxy the observer on the UI queue + // Proxy the observer on the UI thread /* * TODO - * Currenly using PROXY_ASYNC, however + * Currenly using NS_PROXY_ASYNC, however * this can flood the event queue if * rate of events on the observer is * greater that the time to process the * events. * This causes the UI to pause. */ - rv = proxyMgr->GetProxyForObject (uiQueue, + rv = NS_GetProxyForObject ( + NS_PROXY_TO_MAIN_THREAD, NS_GET_IID(nsIRDFObserver), observer, - PROXY_ASYNC | PROXY_ALWAYS, + NS_PROXY_ASYNC | NS_PROXY_ALWAYS, (void** )proxyObserver); return rv; @@ -232,12 +218,6 @@ nsresult nsAbRDFDataSource::NotifyObservers(nsIRDFResource *subject, return NS_OK; - // Get the current thread - nsCOMPtr currentThread; - rv = nsIThread::GetCurrent (getter_AddRefs(currentThread)); - NS_ENSURE_SUCCESS (rv, rv); - - // Get the main thread, which is the UI thread /* * TODO * Is the main thread always guaranteed to be @@ -249,12 +229,8 @@ nsresult nsAbRDFDataSource::NotifyObservers(nsIRDFResource *subject, * RDF datasources that are not UI specific * but are used in the UI? */ - nsCOMPtr uiThread; - rv = nsIThread::GetMainThread (getter_AddRefs(uiThread)); - NS_ENSURE_SUCCESS (rv, rv); - nsCOMPtr observers; - if (currentThread == uiThread) + if (NS_IsMainThread()) { /* * Since this is the UI Thread use the diff --git a/mozilla/mailnews/addrbook/src/nsAddrDatabase.cpp b/mozilla/mailnews/addrbook/src/nsAddrDatabase.cpp index 894bf3427c8..caf501abe92 100644 --- a/mozilla/mailnews/addrbook/src/nsAddrDatabase.cpp +++ b/mozilla/mailnews/addrbook/src/nsAddrDatabase.cpp @@ -43,6 +43,7 @@ #include "nsIEnumerator.h" #include "nsString.h" #include "nsReadableUtils.h" +#include "nsAutoPtr.h" #include "nsRDFCID.h" #include "nsUnicharUtils.h" #include "nsMsgUtils.h" @@ -3619,12 +3620,9 @@ NS_IMETHODIMP nsAddrDatabase::AddListDirNode(nsIMdbRow * listRow) { nsresult rv = NS_OK; - nsCOMPtr proxyMgr = - do_GetService(NS_XPCOMPROXY_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - - static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); - NS_WITH_PROXIED_SERVICE(nsIRDFService, rdfService, kRDFServiceCID, NS_UI_THREAD_EVENTQ, &rv); + static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); + NS_WITH_PROXIED_SERVICE(nsIRDFService, rdfService, kRDFServiceCID, + NS_PROXY_TO_MAIN_THREAD, &rv); if (NS_SUCCEEDED(rv)) { nsCOMPtr parentResource; @@ -3637,8 +3635,11 @@ NS_IMETHODIMP nsAddrDatabase::AddListDirNode(nsIMdbRow * listRow) rv = rdfService->GetResource(NS_ConvertUTF16toUTF8(parentURI), getter_AddRefs(parentResource)); nsCOMPtr parentDir; - rv = proxyMgr->GetProxyForObject( NS_UI_THREAD_EVENTQ, NS_GET_IID( nsIAbDirectory), - parentResource, PROXY_SYNC | PROXY_ALWAYS, getter_AddRefs( parentDir)); + rv = NS_GetProxyForObject( NS_PROXY_TO_MAIN_THREAD, + NS_GET_IID( nsIAbDirectory), + parentResource, + NS_PROXY_SYNC | NS_PROXY_ALWAYS, + getter_AddRefs( parentDir)); if (parentDir) { m_dbDirectory = parentDir; diff --git a/mozilla/mailnews/addrbook/src/nsLDAPAutoCompleteSession.cpp b/mozilla/mailnews/addrbook/src/nsLDAPAutoCompleteSession.cpp index 3762a63e89e..740557b7608 100644 --- a/mozilla/mailnews/addrbook/src/nsLDAPAutoCompleteSession.cpp +++ b/mozilla/mailnews/addrbook/src/nsLDAPAutoCompleteSession.cpp @@ -581,10 +581,10 @@ nsLDAPAutoCompleteSession::OnLDAPInit(nsILDAPConnection *aConn, nsresult aStatus // get a proxy object so the callback happens on the main thread // - rv = NS_GetProxyForObject(NS_UI_THREAD_EVENTQ, + rv = NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD, NS_GET_IID(nsILDAPMessageListener), NS_STATIC_CAST(nsILDAPMessageListener *, this), - PROXY_ASYNC | PROXY_ALWAYS, + NS_PROXY_ASYNC | NS_PROXY_ALWAYS, getter_AddRefs(selfProxy)); if (NS_FAILED(rv)) { NS_ERROR("nsLDAPAutoCompleteSession::OnLDAPInit(): couldn't " @@ -866,10 +866,10 @@ nsLDAPAutoCompleteSession::StartLDAPSearch() // get a proxy object so the callback happens on the main thread // - rv = NS_GetProxyForObject(NS_UI_THREAD_EVENTQ, + rv = NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD, NS_GET_IID(nsILDAPMessageListener), NS_STATIC_CAST(nsILDAPMessageListener *, this), - PROXY_ASYNC | PROXY_ALWAYS, + NS_PROXY_ASYNC | NS_PROXY_ALWAYS, getter_AddRefs(selfProxy)); if (NS_FAILED(rv)) { NS_ERROR("nsLDAPAutoCompleteSession::StartLDAPSearch(): couldn't " @@ -1170,10 +1170,10 @@ nsLDAPAutoCompleteSession::InitConnection() // get a proxy object so the callback happens on the main thread // - rv = NS_GetProxyForObject(NS_UI_THREAD_EVENTQ, + rv = NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD, NS_GET_IID(nsILDAPMessageListener), NS_STATIC_CAST(nsILDAPMessageListener *, this), - PROXY_ASYNC | PROXY_ALWAYS, + NS_PROXY_ASYNC | NS_PROXY_ALWAYS, getter_AddRefs(selfProxy)); if (NS_FAILED(rv)) { NS_ERROR("nsLDAPAutoCompleteSession::InitConnection(): couldn't " diff --git a/mozilla/mailnews/base/src/nsMsgAccountManager.cpp b/mozilla/mailnews/base/src/nsMsgAccountManager.cpp index a1eae491c7c..e52756e372b 100644 --- a/mozilla/mailnews/base/src/nsMsgAccountManager.cpp +++ b/mozilla/mailnews/base/src/nsMsgAccountManager.cpp @@ -76,7 +76,6 @@ #include "nsIMsgPurgeService.h" #include "nsIObserverService.h" #include "nsIMsgMailSession.h" -#include "nsIEventQueueService.h" #include "nsIDirectoryService.h" #include "nsAppDirectoryServiceDefs.h" #include "nsMsgFolderFlags.h" @@ -94,6 +93,7 @@ #include "nsIDBFolderInfo.h" #include "nsIMsgHdr.h" #include "nsILineInputStream.h" +#include "nsThreadUtils.h" #include "nsNetUtil.h" #include "nsEscape.h" @@ -112,7 +112,6 @@ static NS_DEFINE_CID(kMsgAccountCID, NS_MSGACCOUNT_CID); static NS_DEFINE_CID(kMsgFolderCacheCID, NS_MSGFOLDERCACHE_CID); -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); // use this to search for all servers with the given hostname/iid and // put them in "servers" @@ -1052,12 +1051,6 @@ PRBool PR_CALLBACK nsMsgAccountManager::cleanupOnExit(nsHashKey *aKey, void *aDa nsCOMPtr accountManager = do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; - nsCOMPtr pEventQService = - do_GetService(kEventQueueServiceCID, &rv); - if (NS_FAILED(rv)) return rv; - nsCOMPtr eventQueue; - pEventQService->GetThreadEventQueue(NS_CURRENT_THREAD, - getter_AddRefs(eventQueue)); if (isImap) urlListener = do_QueryInterface(accountManager, &rv); @@ -1094,6 +1087,8 @@ PRBool PR_CALLBACK nsMsgAccountManager::cleanupOnExit(nsHashKey *aKey, void *aDa if (isImap && urlListener) { + nsCOMPtr thread = do_GetCurrentThread(); + PRBool inProgress = PR_FALSE; if (cleanupInboxOnExit) { @@ -1104,8 +1099,7 @@ PRBool PR_CALLBACK nsMsgAccountManager::cleanupOnExit(nsHashKey *aKey, void *aDa PR_CEnterMonitor(folder); PR_CWait(folder, PR_MicrosecondsToInterval(1000UL)); PR_CExitMonitor(folder); - if (eventQueue) - eventQueue->ProcessPendingEvents(); + NS_ProcessPendingEvents(thread); } } if (emptyTrashOnExit) @@ -1117,8 +1111,7 @@ PRBool PR_CALLBACK nsMsgAccountManager::cleanupOnExit(nsHashKey *aKey, void *aDa PR_CEnterMonitor(folder); PR_CWait(folder, PR_MicrosecondsToInterval(1000UL)); PR_CExitMonitor(folder); - if (eventQueue) - eventQueue->ProcessPendingEvents(); + NS_ProcessPendingEvents(thread); } } } diff --git a/mozilla/mailnews/base/src/nsMsgPrintEngine.cpp b/mozilla/mailnews/base/src/nsMsgPrintEngine.cpp index bda17197d16..468af267e6c 100644 --- a/mozilla/mailnews/base/src/nsMsgPrintEngine.cpp +++ b/mozilla/mailnews/base/src/nsMsgPrintEngine.cpp @@ -69,12 +69,7 @@ #include "nsIXULWindow.h" #include "nsIPrefService.h" #include "nsIPrefBranch.h" - -// For PLEvents -#include "plevent.h" -#include "nsIEventQueue.h" -#include "nsIEventQueueService.h" -#include "nsIServiceManager.h" +#include "nsThreadUtils.h" // Interfaces Needed #include "nsIBaseWindow.h" @@ -726,114 +721,61 @@ nsMsgPrintEngine::PrintMsgWindow() } //--------------------------------------------------------------- -//-- PLEvent Notification +//-- Event Notification //--------------------------------------------------------------- + +//--------------------------------------------------------------- +class nsPrintMsgWindowEvent : public nsRunnable +{ +public: + nsPrintMsgWindowEvent(nsMsgPrintEngine *mpe) + : mMsgPrintEngine(mpe) + {} + + NS_IMETHOD Run() + { + if (mMsgPrintEngine) + mMsgPrintEngine->PrintMsgWindow(); + return NS_OK; + } + +private: + nsRefPtr mMsgPrintEngine; +}; + //----------------------------------------------------------- -PRBool -FireEvent(nsMsgPrintEngine* aMPE, PLHandleEventProc handler, PLDestroyEventProc destructor) +class nsStartNextPrintOpEvent : public nsRunnable { - static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); +public: + nsStartNextPrintOpEvent(nsMsgPrintEngine *mpe) + : mMsgPrintEngine(mpe) + {} - nsCOMPtr event_service = do_GetService(kEventQueueServiceCID); - - if (!event_service) + NS_IMETHOD Run() { - NS_WARNING("Failed to get event queue service"); - return PR_FALSE; + if (mMsgPrintEngine) + mMsgPrintEngine->StartNextPrintOperation(); + return NS_OK; } - nsCOMPtr event_queue; - - event_service->GetThreadEventQueue(NS_CURRENT_THREAD, - getter_AddRefs(event_queue)); - - if (!event_queue) - { - NS_WARNING("Failed to get event queue from service"); - return PR_FALSE; - } - - PLEvent *event = new PLEvent; - - if (!event) - { - NS_WARNING("Out of memory?"); - return PR_FALSE; - } - - PL_InitEvent(event, aMPE, handler, destructor); - - // The event owns the msgPrintEngine pointer now. - NS_ADDREF(aMPE); - - if (NS_FAILED(event_queue->PostEvent(event))) - { - NS_WARNING("Failed to post event"); - PL_DestroyEvent(event); - return PR_FALSE; - } - - return PR_TRUE; -} - -PR_STATIC_CALLBACK(void*) HandlePLEventPrintMsgWindow(PLEvent* aEvent) -{ - nsMsgPrintEngine *msgPrintEngine = (nsMsgPrintEngine*)PL_GetEventOwner(aEvent); - - NS_ASSERTION(msgPrintEngine, "The event owner is null."); - if (msgPrintEngine) - { - msgPrintEngine->PrintMsgWindow(); - } - - return nsnull; -} - -//------------------------------------------------------------------------ -PR_STATIC_CALLBACK(void) DestroyPLEventPrintMsgWindow(PLEvent* aEvent) -{ - nsMsgPrintEngine *msgPrintEngine = (nsMsgPrintEngine*)PL_GetEventOwner(aEvent); - NS_IF_RELEASE(msgPrintEngine); - - delete aEvent; -} +private: + nsRefPtr mMsgPrintEngine; +}; //----------------------------------------------------------- PRBool nsMsgPrintEngine::FirePrintEvent() { - return FireEvent(this, ::HandlePLEventPrintMsgWindow, - ::DestroyPLEventPrintMsgWindow); -} - -PR_STATIC_CALLBACK(void*) HandlePLEventStartNext(PLEvent* aEvent) -{ - nsMsgPrintEngine *msgPrintEngine = (nsMsgPrintEngine*)PL_GetEventOwner(aEvent); - - NS_ASSERTION(msgPrintEngine, "The event owner is null."); - if (msgPrintEngine) - { - msgPrintEngine->StartNextPrintOperation(); - } - - return nsnull; -} - -//------------------------------------------------------------------------ -PR_STATIC_CALLBACK(void) DestroyPLEventStartNext(PLEvent* aEvent) -{ - nsMsgPrintEngine *msgPrintEngine = (nsMsgPrintEngine*)PL_GetEventOwner(aEvent); - NS_IF_RELEASE(msgPrintEngine); - - delete aEvent; + nsCOMPtr event = new nsPrintMsgWindowEvent(this); + return NS_DispatchToCurrentThread(event); } //----------------------------------------------------------- PRBool nsMsgPrintEngine::FireStartNextEvent() { - return FireEvent(this, ::HandlePLEventStartNext, - ::DestroyPLEventStartNext); + nsCOMPtr event = new nsStartNextPrintOpEvent(this); + return NS_DispatchToCurrentThread(event); } /* void setStartupPPObserver (in nsIObserver startupPPObs); */ diff --git a/mozilla/mailnews/base/util/nsImapMoveCoalescer.cpp b/mozilla/mailnews/base/util/nsImapMoveCoalescer.cpp index 399acbc7197..27cfd50e8d4 100755 --- a/mozilla/mailnews/base/util/nsImapMoveCoalescer.cpp +++ b/mozilla/mailnews/base/util/nsImapMoveCoalescer.cpp @@ -45,10 +45,8 @@ #include "nsIMsgFolder.h" // TO include biffState enum. Change to bool later... #include "nsMsgFolderFlags.h" #include "nsIMsgHdr.h" -#include "nsIEventQueueService.h" #include "nsIMsgImapMailFolder.h" - -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); +#include "nsThreadUtils.h" NS_IMPL_ISUPPORTS1(nsImapMoveCoalescer, nsIUrlListener) @@ -287,14 +285,9 @@ NS_IMETHODIMP nsMoveCoalescerCopyListener::OnStopCopy(nsresult aStatus) nsCOMPtr imapService = do_GetService(NS_IMAPSERVICE_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr url; - nsCOMPtr pEventQService = - do_GetService(kEventQueueServiceCID, &rv); - nsCOMPtr eventQueue; - if (NS_SUCCEEDED(rv) && pEventQService) - pEventQService->GetThreadEventQueue(NS_CURRENT_THREAD, - getter_AddRefs(eventQueue)); + nsCOMPtr thread = do_GetCurrentThread(); nsCOMPtr listener = do_QueryInterface(m_coalescer); - rv = imapService->SelectFolder(eventQueue, m_destFolder, listener, nsnull, getter_AddRefs(url)); + rv = imapService->SelectFolder(thread, m_destFolder, listener, nsnull, getter_AddRefs(url)); } } return rv; diff --git a/mozilla/mailnews/base/util/nsMsgProtocol.cpp b/mozilla/mailnews/base/util/nsMsgProtocol.cpp index 7c830318d90..b70e93bc2c3 100644 --- a/mozilla/mailnews/base/util/nsMsgProtocol.cpp +++ b/mozilla/mailnews/base/util/nsMsgProtocol.cpp @@ -59,7 +59,7 @@ #include "nsIStringBundle.h" #include "nsIProtocolProxyService.h" #include "nsIProxyInfo.h" -#include "nsEventQueueUtils.h" +#include "nsThreadUtils.h" #include "nsIPrefBranch.h" #include "nsIPrefService.h" @@ -142,10 +142,9 @@ nsMsgProtocol::OpenNetworkSocketWithInfo(const char * aHostName, strans->SetSecurityCallbacks(callbacks); // creates cyclic reference! - nsCOMPtr eventQ; - NS_GetCurrentEventQ(getter_AddRefs(eventQ)); - if (eventQ) - strans->SetEventSink(this, eventQ); + nsCOMPtr thread = do_GetCurrentThread(); + if (thread) + strans->SetEventSink(this, thread); m_socketIsOpen = PR_FALSE; m_transport = strans; @@ -1093,7 +1092,7 @@ public: // try to write again... if (NS_SUCCEEDED(rv)) - rv = aOutStream->AsyncWait(this, 0, 0, mMsgProtocol->mProviderEventQ); + rv = aOutStream->AsyncWait(this, 0, 0, mMsgProtocol->mProviderThread); NS_ASSERTION(NS_SUCCEEDED(rv) || rv == NS_BINDING_ABORTED, "unexpected error writing stream"); return NS_OK; @@ -1192,7 +1191,7 @@ NS_IMETHODIMP nsMsgFilePostHelper::OnDataAvailable(nsIRequest * /* aChannel */, // things off again. mProtInstance->mSuspendedWrite = PR_FALSE; mProtInstance->mAsyncOutStream->AsyncWait(mProtInstance->mProvider, 0, 0, - mProtInstance->mProviderEventQ); + mProtInstance->mProviderThread); } return NS_OK; @@ -1459,7 +1458,7 @@ nsresult nsMsgAsyncWriteProtocol::SetupTransportState() PR_TRUE, PR_TRUE); - rv = NS_GetCurrentEventQ(getter_AddRefs(mProviderEventQ)); + rv = NS_GetCurrentThread(getter_AddRefs(mProviderThread)); if (NS_FAILED(rv)) return rv; nsMsgProtocolStreamProvider *provider; @@ -1477,7 +1476,7 @@ nsresult nsMsgAsyncWriteProtocol::SetupTransportState() if (NS_FAILED(rv)) return rv; // wait for the output stream to become writable - rv = mAsyncOutStream->AsyncWait(mProvider, 0, 0, mProviderEventQ); + rv = mAsyncOutStream->AsyncWait(mProvider, 0, 0, mProviderThread); } // if m_transport return rv; @@ -1499,7 +1498,7 @@ nsresult nsMsgAsyncWriteProtocol::CloseSocket() mAsyncOutStream = 0; mProvider = 0; - mProviderEventQ = 0; + mProviderThread = 0; return rv; } @@ -1541,7 +1540,7 @@ PRInt32 nsMsgAsyncWriteProtocol::SendData(nsIURI * aURL, const char * dataBuffer // data to write (i.e. the pipe went empty). So resume the channel to kick // things off again. mSuspendedWrite = PR_FALSE; - mAsyncOutStream->AsyncWait(mProvider, 0, 0, mProviderEventQ); + mAsyncOutStream->AsyncWait(mProvider, 0, 0, mProviderThread); } return NS_OK; } diff --git a/mozilla/mailnews/base/util/nsMsgProtocol.h b/mozilla/mailnews/base/util/nsMsgProtocol.h index a811403574a..e5b0660cb83 100644 --- a/mozilla/mailnews/base/util/nsMsgProtocol.h +++ b/mozilla/mailnews/base/util/nsMsgProtocol.h @@ -43,6 +43,7 @@ #include "nsIOutputStream.h" #include "nsIChannel.h" #include "nsIURL.h" +#include "nsIThread.h" #include "nsILoadGroup.h" #include "nsCOMPtr.h" #include "nsIFileSpec.h" @@ -51,7 +52,6 @@ #include "nsIProgressEventSink.h" #include "nsITransport.h" #include "nsIAsyncOutputStream.h" -#include "nsIEventQueue.h" #include "nsIAuthModule.h" #define UNKNOWN_ERROR 101 @@ -217,7 +217,7 @@ public: nsCOMPtr m_WriteRequest; nsCOMPtr mAsyncOutStream; nsCOMPtr mProvider; - nsCOMPtr mProviderEventQ; + nsCOMPtr mProviderThread; // because we are reading the post data in asychronously, it's possible that we aren't sending it // out fast enough and the reading gets blocked. The following set of state variables are used to diff --git a/mozilla/mailnews/compose/src/nsMsgCopy.cpp b/mozilla/mailnews/compose/src/nsMsgCopy.cpp index 008ffc5b534..6775eb45204 100644 --- a/mozilla/mailnews/compose/src/nsMsgCopy.cpp +++ b/mozilla/mailnews/compose/src/nsMsgCopy.cpp @@ -56,13 +56,12 @@ #include "nsMsgCompUtils.h" #include "prcmon.h" #include "nsIMsgImapMailFolder.h" -#include "nsIEventQueueService.h" +#include "nsThreadUtils.h" #include "nsMsgSimulateError.h" #include "nsIMsgWindow.h" #include "nsIMsgProgress.h" static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); //////////////////////////////////////////////////////////////////////////////////// // This is the listener class for the copy operation. We have to create this class @@ -282,7 +281,7 @@ nsMsgCopy::DoCopy(nsIFileSpec *aDiskFile, nsIMsgFolder *dstFolder, return NS_ERROR_OUT_OF_MEMORY; copyListener->SetMsgComposeAndSendObject(aMsgSendObj); - nsCOMPtr eventQueue; + nsCOMPtr thread; if (aIsDraft) { @@ -299,11 +298,7 @@ nsMsgCopy::DoCopy(nsIFileSpec *aDiskFile, nsIMsgFolder *dstFolder, // set the following only when we were in the middle of shutdown // process copyListener->mCopyInProgress = PR_TRUE; - nsCOMPtr pEventQService = - do_GetService(kEventQueueServiceCID, &rv); - if (NS_FAILED(rv)) return rv; - pEventQService->GetThreadEventQueue(NS_CURRENT_THREAD, - getter_AddRefs(eventQueue)); + thread = do_GetCurrentThread(); } } nsCOMPtr copyService = do_GetService(NS_MSGCOPYSERVICE_CONTRACTID, &rv); @@ -318,8 +313,8 @@ nsMsgCopy::DoCopy(nsIFileSpec *aDiskFile, nsIMsgFolder *dstFolder, PR_CEnterMonitor(copyListener); PR_CWait(copyListener, PR_MicrosecondsToInterval(1000UL)); PR_CExitMonitor(copyListener); - if (eventQueue) - eventQueue->ProcessPendingEvents(); + if (thread) + NS_ProcessPendingEvents(thread); } } diff --git a/mozilla/mailnews/compose/src/nsMsgCreate.cpp b/mozilla/mailnews/compose/src/nsMsgCreate.cpp index c02cddf1bec..0d0bba0c14a 100644 --- a/mozilla/mailnews/compose/src/nsMsgCreate.cpp +++ b/mozilla/mailnews/compose/src/nsMsgCreate.cpp @@ -37,7 +37,6 @@ * ***** END LICENSE BLOCK ***** */ #include "nsCOMPtr.h" #include "nsIURL.h" -#include "nsIEventQueueService.h" #include "nsIInputStream.h" #include "nsIOutputStream.h" #include "nsIGenericFactory.h" diff --git a/mozilla/mailnews/imap/public/nsIImapIncomingServer.idl b/mozilla/mailnews/imap/public/nsIImapIncomingServer.idl index d53b8751918..12825955f66 100644 --- a/mozilla/mailnews/imap/public/nsIImapIncomingServer.idl +++ b/mozilla/mailnews/imap/public/nsIImapIncomingServer.idl @@ -40,7 +40,7 @@ interface nsIUrlListener; interface nsIURI; interface nsIImapUrl; -interface nsIEventQueue; +interface nsIEventTarget; interface nsIImapProtocol; interface nsISupportsArray; interface nsIMsgFolder; @@ -88,7 +88,7 @@ interface nsIImapIncomingServer : nsISupports { nsIMsgFolder getPFC(in boolean createIfMissing); attribute boolean downloadBodiesOnGetNewMail; attribute boolean autoSyncOfflineStores; - void GetImapConnectionAndLoadUrl(in nsIEventQueue aClientEventQueue, + void GetImapConnectionAndLoadUrl(in nsIEventTarget aClientEventTarget, in nsIImapUrl aImapUrl, in nsISupports aConsumer); diff --git a/mozilla/mailnews/imap/public/nsIImapProtocol.idl b/mozilla/mailnews/imap/public/nsIImapProtocol.idl index 382a1c1e2bb..16a8958390e 100644 --- a/mozilla/mailnews/imap/public/nsIImapProtocol.idl +++ b/mozilla/mailnews/imap/public/nsIImapProtocol.idl @@ -41,7 +41,7 @@ interface nsIUrlListener; interface nsIURI; interface nsIImapUrl; -interface nsIEventQueue; +interface nsIEventTarget; interface nsIImapProtocol; interface nsIImapIncomingServer; interface nsISupportsArray; @@ -79,7 +79,7 @@ interface nsIImapProtocol : nsISupports { // protocol data. The protocol also needs a host session list. ///////////////////////////////////////////////////////////////////////// void Initialize(in nsIImapHostSessionList aHostSessionList, in nsIImapIncomingServer aServer, - in nsIEventQueue aSinkEventQueue) ; + in nsIEventTarget aSinkEventTarget) ; void NotifyHdrsToDownload(out unsigned long keys, in unsigned long keyCount); void NotifyBodysToDownload(out unsigned long keys, in unsigned long count); diff --git a/mozilla/mailnews/imap/public/nsIImapService.idl b/mozilla/mailnews/imap/public/nsIImapService.idl index da2054f9624..87594e0a9e8 100644 --- a/mozilla/mailnews/imap/public/nsIImapService.idl +++ b/mozilla/mailnews/imap/public/nsIImapService.idl @@ -51,27 +51,27 @@ interface nsIImapProtocol; interface nsIImapMessageSink; interface nsIUrlListener; interface nsIURI; -interface nsIEventQueue; +interface nsIEventTarget; interface nsIMsgFolder; interface nsIMsgWindow; interface nsIImapIncomingServer; interface nsICacheSession; -[scriptable, uuid(4032dc12-8684-4458-9b41-647034d8c7d2)] +[scriptable, uuid(0819ca53-746b-4072-896a-87a452dc5a77)] interface nsIImapService : nsISupports { // As always, you can pass in null for the url listener and the url if you don't require either..... - // aClientEventQueue is the event queue of the event sinks. We post events into this queue. + // aClientEventTarget is the event queue of the event sinks. We post events into this queue. // mscott -- eventually this function will take in the account (identity/incoming server) associated with // the request - void selectFolder(in nsIEventQueue aClientEventQueue, + void selectFolder(in nsIEventTarget aClientEventTarget, in nsIMsgFolder aImapMailFolder, in nsIUrlListener aUrlListener, in nsIMsgWindow aMsgWindow, out nsIURI aURL); - void liteSelectFolder(in nsIEventQueue aClientEventQueue, + void liteSelectFolder(in nsIEventTarget aClientEventTarget, in nsIMsgFolder aImapMailFolder, in nsIUrlListener aUrlListener, out nsIURI aURL); @@ -87,52 +87,52 @@ interface nsIImapService : nsISupports in string additionalHeader, out nsIURI aOutURL); - void noop(in nsIEventQueue aClientEventQueue, + void noop(in nsIEventTarget aClientEventTarget, in nsIMsgFolder aImapMailFolder, in nsIUrlListener aUrlListener, out nsIURI aURL); - void getHeaders(in nsIEventQueue aClientEventQueue, + void getHeaders(in nsIEventTarget aClientEventTarget, in nsIMsgFolder aImapMailFolder, in nsIUrlListener aUrlListener, out nsIURI aURL, in string aMessageIdentifierList, in boolean aMessageIdsAreUID); - nsIURI getBodyStart(in nsIEventQueue aClientEventQueue, + nsIURI getBodyStart(in nsIEventTarget aClientEventTarget, in nsIMsgFolder aImapMailFolder, in nsIUrlListener aUrlListener, in string aMessageIdentifierList, in long numBytes); - void expunge(in nsIEventQueue aClientEventQueue, + void expunge(in nsIEventTarget aClientEventTarget, in nsIMsgFolder aImapMailFolder, in nsIUrlListener aUrlListener, out nsIURI aURL); - nsIURI updateFolderStatus(in nsIEventQueue aClientEventQueue, + nsIURI updateFolderStatus(in nsIEventTarget aClientEventTarget, in nsIMsgFolder aImapMailFolder, in nsIUrlListener aUrlListener); - void biff(in nsIEventQueue aClientEventQueue, + void biff(in nsIEventTarget aClientEventTarget, in nsIMsgFolder aImapMailFolder, in nsIUrlListener aUrlListener, out nsIURI aURL, in unsigned long aUidHighWater); - void deleteMessages(in nsIEventQueue aClientEventQueue, + void deleteMessages(in nsIEventTarget aClientEventTarget, in nsIMsgFolder aImapMailFolder, in nsIUrlListener aUrlListener, out nsIURI aURL, in string aMessageIdentifierList, in boolean aMessageIdsAreUID); - void deleteAllMessages(in nsIEventQueue aClientEventQueue, + void deleteAllMessages(in nsIEventTarget aClientEventTarget, in nsIMsgFolder aImapMailFolder, in nsIUrlListener aUrlListener, out nsIURI aURL); - void addMessageFlags(in nsIEventQueue aClientEventQueue, + void addMessageFlags(in nsIEventTarget aClientEventTarget, in nsIMsgFolder aImapMailFolder, in nsIUrlListener aUrlListener, out nsIURI aURL, @@ -140,7 +140,7 @@ interface nsIImapService : nsISupports in imapMessageFlagsType aFlags, in boolean aMessageIdsAreUID); - void subtractMessageFlags(in nsIEventQueue aClientEventQueue, + void subtractMessageFlags(in nsIEventTarget aClientEventTarget, in nsIMsgFolder aImapMailFolder, in nsIUrlListener aUrlListener, out nsIURI aURL, @@ -148,7 +148,7 @@ interface nsIImapService : nsISupports in imapMessageFlagsType aFlags, in boolean aMessageIdsAreUID); - void setMessageFlags(in nsIEventQueue aClientEventQueue, + void setMessageFlags(in nsIEventTarget aClientEventTarget, in nsIMsgFolder aImapMailFolder, in nsIUrlListener aUrlListener, out nsIURI aURL, @@ -156,23 +156,23 @@ interface nsIImapService : nsISupports in imapMessageFlagsType aFlags, in boolean aMessageIdsAreUID); - void discoverAllFolders(in nsIEventQueue aClientEventQueue, + void discoverAllFolders(in nsIEventTarget aClientEventTarget, in nsIMsgFolder aImapMailFolder, in nsIUrlListener aUrlListener, in nsIMsgWindow aMsgWindow, out nsIURI aURL); - void discoverAllAndSubscribedFolders(in nsIEventQueue aClientEventQueue, + void discoverAllAndSubscribedFolders(in nsIEventTarget aClientEventTarget, in nsIMsgFolder aImapMailFolder, in nsIUrlListener aUrlListener, out nsIURI aURL); - void discoverChildren(in nsIEventQueue aClientEventQueue, + void discoverChildren(in nsIEventTarget aClientEventTarget, in nsIMsgFolder aImapMailFolder, in nsIUrlListener aUrlListener, in string folderPath, out nsIURI aURL); - void onlineMessageCopy(in nsIEventQueue aClientEventQueue, + void onlineMessageCopy(in nsIEventTarget aClientEventTarget, in nsIMsgFolder aSrcFolder, in string aMessageIds, in nsIMsgFolder aDstFolder, @@ -184,7 +184,7 @@ interface nsIImapService : nsISupports in nsIMsgWindow aWindow); - void appendMessageFromFile(in nsIEventQueue aClientEventQueue, + void appendMessageFromFile(in nsIEventTarget aClientEventTarget, in nsIFileSpec aFileSpec, in nsIMsgFolder aDstFolder, in string aMessageId, @@ -198,37 +198,37 @@ interface nsIImapService : nsISupports void downloadMessagesForOffline(in string aMessageIds, in nsIMsgFolder aSrcFolder, in nsIUrlListener aListener, in nsIMsgWindow aMsgWindow); - nsIURI moveFolder(in nsIEventQueue aClientEventQueue, + nsIURI moveFolder(in nsIEventTarget aClientEventTarget, in nsIMsgFolder aSrcFolder, in nsIMsgFolder aDstFolder, in nsIUrlListener aUrlListener, in nsIMsgWindow msgWindow); - nsIURI renameLeaf(in nsIEventQueue aClientEventQueue, + nsIURI renameLeaf(in nsIEventTarget aClientEventTarget, in nsIMsgFolder aSrcFolder, in wstring aLeafName, in nsIUrlListener aUrlListener, in nsIMsgWindow msgWindow); - nsIURI deleteFolder(in nsIEventQueue aClientEventQueue, + nsIURI deleteFolder(in nsIEventTarget aClientEventTarget, in nsIMsgFolder aFolder, in nsIUrlListener aUrlListener); - nsIURI createFolder(in nsIEventQueue aClientEventQueue, + nsIURI createFolder(in nsIEventTarget aClientEventTarget, in nsIMsgFolder aParentFolder, in wstring aLeafName, in nsIUrlListener aUrlListener); - nsIURI listFolder(in nsIEventQueue aClientEventQueue, + nsIURI listFolder(in nsIEventTarget aClientEventTarget, in nsIMsgFolder aMailFolder, in nsIUrlListener aUrlListener); - nsIURI subscribeFolder(in nsIEventQueue aClientEventQueue, + nsIURI subscribeFolder(in nsIEventTarget aClientEventTarget, in nsIMsgFolder aMailFolder, in wstring mailboxName, in nsIUrlListener aUrlListener); - nsIURI unsubscribeFolder(in nsIEventQueue aClientEventQueue, + nsIURI unsubscribeFolder(in nsIEventTarget aClientEventTarget, in nsIMsgFolder aMailFolder, in wstring mailboxName, in nsIUrlListener aUrlListener); @@ -237,30 +237,30 @@ interface nsIImapService : nsISupports // not subscribed to, in which case it will subscribe to the folder. // otherwise, it will try to create the folder. It will try to do this // with one url. - nsIURI ensureFolderExists(in nsIEventQueue aClientEventQueue, + nsIURI ensureFolderExists(in nsIEventTarget aClientEventTarget, in nsIMsgFolder aParentFolder, in wstring aLeafName, in nsIUrlListener aUrlListener); - nsIURI getFolderAdminUrl(in nsIEventQueue aClientEventQueue, + nsIURI getFolderAdminUrl(in nsIEventTarget aClientEventTarget, in nsIMsgFolder aMailFolder, in nsIMsgWindow aMsgWindow, in nsIUrlListener aUrlListener); - nsIURI issueCommandOnMsgs(in nsIEventQueue aClientEventQueue, + nsIURI issueCommandOnMsgs(in nsIEventTarget aClientEventTarget, in nsIMsgFolder aMailFolder, in nsIMsgWindow aMsgWindow, in string aCommand, in string aMessageIdentifierList); - nsIURI fetchCustomMsgAttribute(in nsIEventQueue aClientEventQueue, + nsIURI fetchCustomMsgAttribute(in nsIEventTarget aClientEventTarget, in nsIMsgFolder aMailFolder, in nsIMsgWindow aMsgWindow, in string aAttribute, in string aMessageIdentifierList); - nsIURI storeCustomKeywords(in nsIEventQueue aClientEventQueue, + nsIURI storeCustomKeywords(in nsIEventTarget aClientEventTarget, in nsIMsgFolder aMailFolder, in nsIMsgWindow aMsgWindow, in string flagsToAdd, diff --git a/mozilla/mailnews/imap/src/nsImapIncomingServer.cpp b/mozilla/mailnews/imap/src/nsImapIncomingServer.cpp index 40104f727a2..546fe1f09ec 100644 --- a/mozilla/mailnews/imap/src/nsImapIncomingServer.cpp +++ b/mozilla/mailnews/imap/src/nsImapIncomingServer.cpp @@ -56,7 +56,7 @@ #include "nsIMsgIdentity.h" #include "nsIImapUrl.h" #include "nsIUrlListener.h" -#include "nsIEventQueue.h" +#include "nsThreadUtils.h" #include "nsImapProtocol.h" #include "nsISupportsArray.h" #include "nsVoidArray.h" @@ -75,7 +75,6 @@ #include "nsIRDFService.h" #include "nsRDFCID.h" #include "nsEnumeratorUtils.h" -#include "nsIEventQueueService.h" #include "nsIMsgMailNewsUrl.h" #include "nsIImapService.h" #include "nsMsgI18N.h" @@ -100,7 +99,6 @@ static NS_DEFINE_CID(kImapProtocolCID, NS_IMAPPROTOCOL_CID); static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); static NS_DEFINE_CID(kImapServiceCID, NS_IMAPSERVICE_CID); static NS_DEFINE_CID(kSubscribableServerCID, NS_SUBSCRIBABLESERVER_CID); static NS_DEFINE_CID(kCImapHostSessionListCID, NS_IIMAPHOSTSESSIONLIST_CID); @@ -430,14 +428,14 @@ nsImapIncomingServer::SetIsAOLServer(PRBool aBool) NS_IMETHODIMP -nsImapIncomingServer::GetImapConnectionAndLoadUrl(nsIEventQueue * aClientEventQueue, +nsImapIncomingServer::GetImapConnectionAndLoadUrl(nsIEventTarget * aClientEventTarget, nsIImapUrl* aImapUrl, nsISupports* aConsumer) { nsresult rv = NS_OK; nsCOMPtr aProtocol; - rv = GetImapConnection(aClientEventQueue, aImapUrl, getter_AddRefs(aProtocol)); + rv = GetImapConnection(aClientEventTarget, aImapUrl, getter_AddRefs(aProtocol)); if (NS_FAILED(rv)) return rv; nsCOMPtr mailnewsurl = do_QueryInterface(aImapUrl, &rv); @@ -476,16 +474,11 @@ NS_IMETHODIMP nsImapIncomingServer::RetryUrl(nsIImapUrl *aImapUrl) { nsresult rv; - nsCOMPtr aEventQueue; + nsCOMPtr thread = do_GetCurrentThread(); // Get current thread envent queue - nsCOMPtr pEventQService = - do_GetService(kEventQueueServiceCID, &rv); - if (NS_SUCCEEDED(rv) && pEventQService) - pEventQService->GetThreadEventQueue(NS_CURRENT_THREAD, - getter_AddRefs(aEventQueue)); nsCOMPtr protocolInstance; nsImapProtocol::LogImapUrl("creating protocol instance to retry queued url", aImapUrl); - rv = GetImapConnection(aEventQueue, aImapUrl, getter_AddRefs(protocolInstance)); + rv = GetImapConnection(thread, aImapUrl, getter_AddRefs(protocolInstance)); if (NS_SUCCEEDED(rv) && protocolInstance) { nsCOMPtr url = do_QueryInterface(aImapUrl, &rv); @@ -691,7 +684,7 @@ nsImapIncomingServer::ConnectionTimeOut(nsIImapProtocol* aConnection) } nsresult -nsImapIncomingServer::GetImapConnection(nsIEventQueue *aEventQueue, +nsImapIncomingServer::GetImapConnection(nsIEventTarget *aEventTarget, nsIImapUrl * aImapUrl, nsIImapProtocol ** aImapConnection) { @@ -853,10 +846,10 @@ nsImapIncomingServer::GetImapConnection(nsIEventQueue *aEventQueue, // (e.g., a folder delete or msg append) but we shouldn't create new connections // for these types of urls if we have a free connection. So we check the actual // required state here. - else if (cnt < ((PRUint32)maxConnections) && aEventQueue + else if (cnt < ((PRUint32)maxConnections) && aEventTarget && (!freeConnection || requiredState == nsIImapUrl::nsImapSelectedState)) { - rv = CreateProtocolInstance(aEventQueue, aImapConnection); + rv = CreateProtocolInstance(aEventTarget, aImapConnection); } else if (freeConnection) { @@ -876,7 +869,7 @@ nsImapIncomingServer::GetImapConnection(nsIEventQueue *aEventQueue, } nsresult -nsImapIncomingServer::CreateProtocolInstance(nsIEventQueue *aEventQueue, +nsImapIncomingServer::CreateProtocolInstance(nsIEventTarget *aEventTarget, nsIImapProtocol ** aImapConnection) { // create a new connection and add it to the connection cache @@ -899,7 +892,7 @@ nsImapIncomingServer::CreateProtocolInstance(nsIEventQueue *aEventQueue, nsCOMPtr hostSession = do_GetService(kCImapHostSessionListCID, &rv); if (NS_SUCCEEDED(rv)) - rv = protocolInstance->Initialize(hostSession, this, aEventQueue); + rv = protocolInstance->Initialize(hostSession, this, aEventTarget); } // take the protocol instance and add it to the connectionCache @@ -1003,16 +996,9 @@ nsImapIncomingServer::PerformExpand(nsIMsgWindow *aMsgWindow) nsCOMPtr imapService = do_GetService(kImapServiceCID, &rv); if (NS_FAILED(rv)) return rv; if (!imapService) return NS_ERROR_FAILURE; - nsCOMPtr queue; - // get the Event Queue for this thread... - nsCOMPtr pEventQService = - do_GetService(kEventQueueServiceCID, &rv); - if (NS_FAILED(rv)) return rv; - if (!pEventQService) return NS_ERROR_FAILURE; - - rv = pEventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(queue)); - if (NS_FAILED(rv)) return rv; - rv = imapService->DiscoverAllFolders(queue, rootMsgFolder, this, aMsgWindow, nsnull); + nsCOMPtr thread = do_GetCurrentThread(); + if (!thread) return NS_ERROR_FAILURE; + rv = imapService->DiscoverAllFolders(thread, rootMsgFolder, this, aMsgWindow, nsnull); return rv; } @@ -2569,19 +2555,13 @@ NS_IMETHODIMP nsImapIncomingServer::OnLogonRedirectionError(const PRUnichar *pEr if (urlQueueCnt > 0) { nsCOMPtr imapProtocol; - nsCOMPtr aEventQueue; - // Get current thread envent queue - nsCOMPtr pEventQService = - do_GetService(kEventQueueServiceCID, &rv); - if (NS_SUCCEEDED(rv) && pEventQService) - pEventQService->GetThreadEventQueue(NS_CURRENT_THREAD, - getter_AddRefs(aEventQueue)); + nsCOMPtr thread = do_GetCurrentThread(); if (aImapUrl) { nsCOMPtr protocolInstance ; m_waitingForConnectionInfo = PR_FALSE; - rv = GetImapConnection(aEventQueue, aImapUrl, getter_AddRefs(protocolInstance)); + rv = GetImapConnection(thread, aImapUrl, getter_AddRefs(protocolInstance)); // If users cancel the login then we need to reset url state. if (rv == NS_BINDING_ABORTED) resetUrlState = PR_TRUE; @@ -2623,14 +2603,8 @@ NS_IMETHODIMP nsImapIncomingServer::OnLogonRedirectionReply(const PRUnichar *pHo PRBool urlRun = PR_FALSE; nsresult rv; nsCOMPtr imapProtocol; - nsCOMPtr aEventQueue; + nsCOMPtr thread = do_GetCurrentThread(); nsCAutoString cookie(pCookieData, pCookieSize); - // Get current thread envent queue - nsCOMPtr pEventQService = - do_GetService(kEventQueueServiceCID, &rv); - if (NS_SUCCEEDED(rv) && pEventQService) - pEventQService->GetThreadEventQueue(NS_CURRENT_THREAD, - getter_AddRefs(aEventQueue)); // we used to logoff the external requestor...we no longer need to do // that. @@ -2648,7 +2622,7 @@ NS_IMETHODIMP nsImapIncomingServer::OnLogonRedirectionReply(const PRUnichar *pHo nsCOMPtr aConsumer = (nsISupports*)m_urlConsumers.ElementAt(0); nsCOMPtr protocolInstance ; - rv = GetImapConnection(aEventQueue, aImapUrl, getter_AddRefs(protocolInstance)); + rv = GetImapConnection(thread, aImapUrl, getter_AddRefs(protocolInstance)); m_waitingForConnectionInfo = PR_FALSE; if (NS_SUCCEEDED(rv) && protocolInstance) { @@ -2985,23 +2959,16 @@ nsImapIncomingServer::SubscribeToFolder(const PRUnichar *aName, PRBool subscribe rv = rootMsgFolder->FindSubFolder(folderCName, getter_AddRefs(msgFolder)); } - nsCOMPtr queue; - // get the Event Queue for this thread... - nsCOMPtr pEventQService = - do_GetService(kEventQueueServiceCID, &rv); - if (NS_FAILED(rv)) return rv; - - rv = pEventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(queue)); - if (NS_FAILED(rv)) return rv; + nsCOMPtr thread = do_GetCurrentThread(); nsAutoString unicodeName; rv = CopyMUTF7toUTF16(folderCName, unicodeName); NS_ENSURE_SUCCESS(rv, rv); if (subscribe) - rv = imapService->SubscribeFolder(queue, msgFolder, unicodeName.get(), nsnull, aUri); + rv = imapService->SubscribeFolder(thread, msgFolder, unicodeName.get(), nsnull, aUri); else - rv = imapService->UnsubscribeFolder(queue, msgFolder, unicodeName.get(), nsnull, nsnull); + rv = imapService->UnsubscribeFolder(thread, msgFolder, unicodeName.get(), nsnull, nsnull); if (NS_FAILED(rv)) return rv; return NS_OK; diff --git a/mozilla/mailnews/imap/src/nsImapIncomingServer.h b/mozilla/mailnews/imap/src/nsImapIncomingServer.h index 1180e9c1c08..7e906c2f228 100644 --- a/mozilla/mailnews/imap/src/nsImapIncomingServer.h +++ b/mozilla/mailnews/imap/src/nsImapIncomingServer.h @@ -51,6 +51,9 @@ #include "nsAdapterEnumerator.h" #include "nsIMsgImapMailFolder.h" #include "nsCOMArray.h" + +class nsIEventTarget; + /* get some implementation from nsMsgIncomingServer */ class nsImapIncomingServer : public nsMsgIncomingServer, public nsIImapIncomingServer, @@ -115,10 +118,10 @@ protected: private: nsresult SetDelimiterFromHierarchyDelimiter(); nsresult SubscribeToFolder(const PRUnichar *aName, PRBool subscribe); - nsresult GetImapConnection (nsIEventQueue* aEventQueue, + nsresult GetImapConnection (nsIEventTarget* aEventTarget, nsIImapUrl* aImapUrl, nsIImapProtocol** aImapConnection); - nsresult CreateProtocolInstance(nsIEventQueue *aEventQueue, + nsresult CreateProtocolInstance(nsIEventTarget *aEventTarget, nsIImapProtocol ** aImapConnection); nsresult RequestOverrideInfo(nsIMsgWindow *aMsgWindow); nsresult CreateHostSpecificPrefName(const char *prefPrefix, nsCAutoString &prefName); diff --git a/mozilla/mailnews/imap/src/nsImapMailFolder.cpp b/mozilla/mailnews/imap/src/nsImapMailFolder.cpp index fa53bf93eec..56fbc8ec1f3 100644 --- a/mozilla/mailnews/imap/src/nsImapMailFolder.cpp +++ b/mozilla/mailnews/imap/src/nsImapMailFolder.cpp @@ -53,7 +53,7 @@ #include "nsMsgDBCID.h" #include "nsMsgFolderFlags.h" #include "nsImapFlagAndUidState.h" -#include "nsIEventQueueService.h" +#include "nsThreadUtils.h" #include "nsIImapUrl.h" #include "nsImapUtils.h" #include "nsMsgUtils.h" @@ -117,7 +117,6 @@ static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); static NS_DEFINE_CID(kCMailDB, NS_MAILDB_CID); static NS_DEFINE_CID(kCImapDB, NS_IMAPDB_CID); -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); static NS_DEFINE_CID(kParseMailMsgStateCID, NS_PARSEMAILMSGSTATE_CID); static NS_DEFINE_CID(kCImapHostSessionList, NS_IIMAPHOSTSESSIONLIST_CID); @@ -221,12 +220,7 @@ nsImapMailFolder::nsImapMailFolder() : nsresult rv; - // Get current thread envent queue - nsCOMPtr pEventQService = - do_GetService(kEventQueueServiceCID, &rv); - if (NS_SUCCEEDED(rv) && pEventQService) - pEventQService->GetThreadEventQueue(NS_CURRENT_THREAD, - getter_AddRefs(m_eventQueue)); + m_thread = do_GetCurrentThread(); m_moveCoalescer = nsnull; m_boxFlags = 0; m_uidValidity = kUidUnknown; @@ -810,7 +804,7 @@ nsImapMailFolder::UpdateFolder(nsIMsgWindow *msgWindow) if (NS_FAILED(rv)) return rv; nsCOMPtr url; - rv = imapService->SelectFolder(m_eventQueue, this, m_urlListener, msgWindow, getter_AddRefs(url)); + rv = imapService->SelectFolder(m_thread, this, m_urlListener, msgWindow, getter_AddRefs(url)); if (NS_SUCCEEDED(rv)) m_urlRunning = PR_TRUE; if (url) @@ -880,8 +874,7 @@ NS_IMETHODIMP nsImapMailFolder::CreateSubfolder(const PRUnichar* folderName, nsI nsCOMPtr imapService = do_GetService(NS_IMAPSERVICE_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv,rv); - rv = imapService->CreateFolder(m_eventQueue, this, - folderName, this, nsnull); + rv = imapService->CreateFolder(m_thread, this, folderName, this, nsnull); return rv; } @@ -1032,7 +1025,7 @@ NS_IMETHODIMP nsImapMailFolder::List() nsCOMPtr imapService = do_GetService(NS_IMAPSERVICE_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv,rv); - rv = imapService->ListFolder(m_eventQueue, this, this, nsnull); + rv = imapService->ListFolder(m_thread, this, this, nsnull); return rv; } @@ -1088,7 +1081,7 @@ NS_IMETHODIMP nsImapMailFolder::CreateStorageIfMissing(nsIUrlListener* urlListen if (NS_SUCCEEDED(rv) && imapService) { nsCOMPtr uri; - imapService->EnsureFolderExists(m_eventQueue, msgParent, folderName.get(), urlListener, getter_AddRefs(uri)); + imapService->EnsureFolderExists(m_thread, msgParent, folderName.get(), urlListener, getter_AddRefs(uri)); } } @@ -1247,7 +1240,7 @@ NS_IMETHODIMP nsImapMailFolder::Compact(nsIUrlListener *aListener, nsIMsgWindow nsCOMPtr imapService = do_GetService(NS_IMAPSERVICE_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv,rv); - return imapService->Expunge(m_eventQueue, this, aListener, nsnull); + return imapService->Expunge(m_thread, this, aListener, nsnull); } NS_IMETHODIMP nsImapMailFolder::CompactAll(nsIUrlListener *aListener, nsIMsgWindow *aMsgWindow, nsISupportsArray *aFolderArray, PRBool aCompactOfflineAlso, nsISupportsArray *aOfflineFolderArray) @@ -1300,7 +1293,7 @@ NS_IMETHODIMP nsImapMailFolder::UpdateStatus(nsIUrlListener *aListener, nsIMsgWi nsCOMPtr uri; - rv = imapService->UpdateFolderStatus(m_eventQueue, this, aListener, getter_AddRefs(uri)); + rv = imapService->UpdateFolderStatus(m_thread, this, aListener, getter_AddRefs(uri)); if (uri) { nsCOMPtr mailNewsUrl = do_QueryInterface(uri); @@ -1436,14 +1429,14 @@ NS_IMETHODIMP nsImapMailFolder::EmptyTrash(nsIMsgWindow *aMsgWindow, } if (aListener) { - rv = imapService->DeleteAllMessages(m_eventQueue, trashFolder, + rv = imapService->DeleteAllMessages(m_thread, trashFolder, aListener, nsnull); } else { nsCOMPtr urlListener = do_QueryInterface(trashFolder); - rv = imapService->DeleteAllMessages(m_eventQueue, trashFolder, + rv = imapService->DeleteAllMessages(m_thread, trashFolder, urlListener, nsnull); } // return an error if this failed. We want the empty trash on exit code @@ -1562,7 +1555,7 @@ NS_IMETHODIMP nsImapMailFolder::Rename (const PRUnichar *newName, nsIMsgWindow * nsCOMPtr imapService = do_GetService(NS_IMAPSERVICE_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv,rv); - return imapService->RenameLeaf(m_eventQueue, this, newName, this, msgWindow, + return imapService->RenameLeaf(m_thread, this, newName, this, msgWindow, nsnull); } @@ -2226,7 +2219,7 @@ NS_IMETHODIMP nsImapMailFolder::DeleteMessages(nsISupportsArray *messages, //need to take care of these two delete models nsImapMoveCopyMsgTxn* undoMsgTxn = new nsImapMoveCopyMsgTxn( this, &srcKeyArray, messageIds.get(), nsnull, - PR_TRUE, isMove, m_eventQueue, nsnull); + PR_TRUE, isMove, m_thread, nsnull); if (!undoMsgTxn) return NS_ERROR_OUT_OF_MEMORY; undoMsgTxn->SetTransactionType(nsIMessenger::eDeleteMsg); // we're adding this undo action before the delete is successful. This is evil, @@ -2433,7 +2426,7 @@ nsImapMailFolder::DeleteSubFolders(nsISupportsArray* folders, nsIMsgWindow *msgW { urlListener = do_QueryInterface(curFolder); if (deleteNoTrash) - rv = imapService->DeleteFolder(m_eventQueue, + rv = imapService->DeleteFolder(m_thread, curFolder, urlListener, nsnull); @@ -2448,7 +2441,7 @@ nsImapMailFolder::DeleteSubFolders(nsISupportsArray* folders, nsIMsgWindow *msgW if (!confirm) return NS_OK; } - rv = imapService->MoveFolder(m_eventQueue, + rv = imapService->MoveFolder(m_thread, curFolder, trashFolder, urlListener, @@ -3229,7 +3222,7 @@ NS_IMETHODIMP nsImapMailFolder::EndCopy(PRBool copySucceeded) nsCOMPtr copySupport; if (m_copyState) copySupport = do_QueryInterface(m_copyState); - rv = imapService->AppendMessageFromFile(m_eventQueue, + rv = imapService->AppendMessageFromFile(m_thread, m_copyState->m_tmpFileSpec, this, "", PR_TRUE, m_copyState->m_selectedState, @@ -3534,7 +3527,7 @@ NS_IMETHODIMP nsImapMailFolder::SetImapFlags(const char *uids, PRInt32 flags, ns nsCOMPtr imapService = do_GetService(NS_IMAPSERVICE_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv,rv); - return imapService->SetMessageFlags(m_eventQueue, this, this, + return imapService->SetMessageFlags(m_thread, this, this, url, uids, flags, PR_TRUE); } @@ -3547,7 +3540,7 @@ NS_IMETHODIMP nsImapMailFolder::PlaybackOfflineFolderCreate(const PRUnichar *aFo nsCOMPtr imapService = do_GetService(NS_IMAPSERVICE_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv,rv); - return imapService->CreateFolder(m_eventQueue, this, + return imapService->CreateFolder(m_thread, this, aFolderName, this, url); } @@ -3561,7 +3554,7 @@ NS_IMETHODIMP nsImapMailFolder::ReplayOfflineMoveCopy(nsMsgKey *msgKeys, PRUint3 nsCOMPtr resultUrl; nsCAutoString uids; AllocateUidStringFromKeys(msgKeys, numKeys, uids); - rv = imapService->OnlineMessageCopy(m_eventQueue, + rv = imapService->OnlineMessageCopy(m_thread, this, uids.get(), aDstFolder, @@ -3598,12 +3591,12 @@ NS_IMETHODIMP nsImapMailFolder::StoreImapFlags(PRInt32 flags, PRBool addFlags, if (addFlags) { - imapService->AddMessageFlags(m_eventQueue, this, aUrlListener ? aUrlListener : this, + imapService->AddMessageFlags(m_thread, this, aUrlListener ? aUrlListener : this, nsnull, msgIds.get(), flags, PR_TRUE); } else { - imapService->SubtractMessageFlags(m_eventQueue, this, aUrlListener ? aUrlListener : this, + imapService->SubtractMessageFlags(m_thread, this, aUrlListener ? aUrlListener : this, nsnull, msgIds.get(), flags, PR_TRUE); } @@ -3644,7 +3637,7 @@ NS_IMETHODIMP nsImapMailFolder::LiteSelect(nsIUrlListener *aUrlListener) nsCOMPtr imapService = do_GetService(NS_IMAPSERVICE_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv,rv); - return imapService->LiteSelectFolder(m_eventQueue, this, aUrlListener, nsnull); + return imapService->LiteSelectFolder(m_thread, this, aUrlListener, nsnull); } nsresult nsImapMailFolder::GetFolderOwnerUserName(char **userName) @@ -3791,7 +3784,7 @@ NS_IMETHODIMP nsImapMailFolder::FolderPrivileges(nsIMsgWindow *window) nsCOMPtr imapService = do_GetService(NS_IMAPSERVICE_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv,rv); - rv = imapService->GetFolderAdminUrl(m_eventQueue, this, window, this, nsnull); + rv = imapService->GetFolderAdminUrl(m_thread, this, window, this, nsnull); if (NS_SUCCEEDED(rv)) m_urlRunning = PR_TRUE; } @@ -3836,7 +3829,7 @@ NS_IMETHODIMP nsImapMailFolder::IssueCommandOnMsgs(const char *command, const ch nsCOMPtr imapService = do_GetService(NS_IMAPSERVICE_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv,rv); - return imapService->IssueCommandOnMsgs(m_eventQueue, this, aWindow, command, uids, url); + return imapService->IssueCommandOnMsgs(m_thread, this, aWindow, command, uids, url); } NS_IMETHODIMP nsImapMailFolder::FetchCustomMsgAttribute(const char *attribute, const char *uids, nsIMsgWindow *aWindow, nsIURI **url) @@ -3845,7 +3838,7 @@ NS_IMETHODIMP nsImapMailFolder::FetchCustomMsgAttribute(const char *attribute, c nsCOMPtr imapService = do_GetService(NS_IMAPSERVICE_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv,rv); - return imapService->FetchCustomMsgAttribute(m_eventQueue, this, aWindow, attribute, uids, url); + return imapService->FetchCustomMsgAttribute(m_thread, this, aWindow, attribute, uids, url); } nsresult nsImapMailFolder::MoveIncorporatedMessage(nsIMsgDBHdr *mailHdr, @@ -4197,7 +4190,7 @@ NS_IMETHODIMP nsImapMailFolder::DownloadAllForOffline(nsIUrlListener *listener, // selecting the folder with m_downloadingFolderForOfflineUse true will cause // us to fetch any message bodies we don't have. - rv = imapService->SelectFolder(m_eventQueue, this, listener, msgWindow, nsnull); + rv = imapService->SelectFolder(m_thread, this, listener, msgWindow, nsnull); if (NS_SUCCEEDED(rv)) m_urlRunning = PR_TRUE; } @@ -4330,7 +4323,7 @@ nsImapMailFolder::OnlineCopyCompleted(nsIImapProtocol *aProtocol, ImapOnlineCopy do_GetService(NS_IMAPSERVICE_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv,rv); - rv = imapService->AddMessageFlags(m_eventQueue, this, nsnull, nsnull, + rv = imapService->AddMessageFlags(m_thread, this, nsnull, nsnull, messageIds, kImapMsgDeletedFlag, PR_TRUE); @@ -6300,7 +6293,7 @@ nsImapMailFolder::CopyMessagesWithStream(nsIMsgFolder* srcFolder, nsImapMoveCopyMsgTxn* undoMsgTxn = new nsImapMoveCopyMsgTxn( srcFolder, &srcKeyArray, messageIds.get(), this, - PR_TRUE, isMove, m_eventQueue, urlListener); + PR_TRUE, isMove, m_thread, urlListener); if (!undoMsgTxn) return NS_ERROR_OUT_OF_MEMORY; if (isMove) @@ -6606,7 +6599,7 @@ nsresult nsImapMailFolder::CopyMessagesOffline(nsIMsgFolder* srcFolder, rv = QueryInterface(NS_GET_IID(nsIUrlListener), getter_AddRefs(urlListener)); nsImapOfflineTxn *undoMsgTxn = new nsImapOfflineTxn(srcFolder, &srcKeyArray, this, isMove, opType, message, - m_eventQueue, urlListener); + m_thread, urlListener); if (undoMsgTxn) { @@ -6679,7 +6672,7 @@ nsresult nsImapMailFolder::CopyMessagesOffline(nsIMsgFolder* srcFolder, keyArray.Add(fakeBase + sourceKeyIndex); nsImapOfflineTxn *undoMsgTxn = new nsImapOfflineTxn(this, &keyArray, this, isMove, nsIMsgOfflineImapOperation::kAddedHeader, - newMailHdr, m_eventQueue, urlListener); + newMailHdr, m_thread, urlListener); if (undoMsgTxn) { if (txnMgr) @@ -6710,7 +6703,7 @@ nsresult nsImapMailFolder::CopyMessagesOffline(nsIMsgFolder* srcFolder, srcKeyArray.Add(msgKey); nsImapOfflineTxn *undoMsgTxn = new nsImapOfflineTxn(srcFolder, &srcKeyArray, this, isMove, opType, mailHdr, - m_eventQueue, urlListener); + m_thread, urlListener); if (undoMsgTxn) { if (isMove) @@ -6870,7 +6863,7 @@ nsImapMailFolder::CopyMessages(nsIMsgFolder* srcFolder, copySupport = do_QueryInterface(m_copyState); if (imapService) - rv = imapService->OnlineMessageCopy(m_eventQueue, + rv = imapService->OnlineMessageCopy(m_thread, srcFolder, messageIds.get(), this, PR_TRUE, isMove, urlListener, nsnull, @@ -6880,7 +6873,7 @@ nsImapMailFolder::CopyMessages(nsIMsgFolder* srcFolder, { nsImapMoveCopyMsgTxn* undoMsgTxn = new nsImapMoveCopyMsgTxn( srcFolder, &srcKeyArray, messageIds.get(), this, - PR_TRUE, isMove, m_eventQueue, urlListener); + PR_TRUE, isMove, m_thread, urlListener); if (!undoMsgTxn) return NS_ERROR_OUT_OF_MEMORY; if (isMove) { @@ -6970,14 +6963,9 @@ nsImapFolderCopyState::StartNextCopy() nsXPIDLString folderName; m_srcFolder->GetName(getter_Copies(folderName)); - nsCOMPtr pEventQService = - do_GetService(kEventQueueServiceCID, &rv); - nsCOMPtr eventQueue; - if (NS_SUCCEEDED(rv) && pEventQService) - pEventQService->GetThreadEventQueue(NS_CURRENT_THREAD, - getter_AddRefs(eventQueue)); + nsCOMPtr thread = do_GetCurrentThread(); - rv = imapService->EnsureFolderExists(eventQueue, m_destParent, + rv = imapService->EnsureFolderExists(thread, m_destParent, folderName.get(), this, nsnull); } @@ -7261,7 +7249,7 @@ nsImapMailFolder::CopyFolder(nsIMsgFolder* srcFolder, return NS_OK; } } - rv = imapService->MoveFolder(m_eventQueue, + rv = imapService->MoveFolder(m_thread, srcFolder, this, urlListener, @@ -7325,7 +7313,7 @@ nsImapMailFolder::CopyFileMessage(nsIFileSpec* fileSpec, copySupport = do_QueryInterface(m_copyState); if (!isDraftOrTemplate) m_copyState->m_totalCount = 1; - rv = imapService->AppendMessageFromFile(m_eventQueue, fileSpec, this, + rv = imapService->AppendMessageFromFile(m_thread, fileSpec, this, messageId.get(), PR_TRUE, isDraftOrTemplate, urlListener, nsnull, @@ -7812,7 +7800,7 @@ NS_IMETHODIMP nsImapMailFolder::PerformExpand(nsIMsgWindow *aMsgWindow) nsCOMPtr imapService = do_GetService(NS_IMAPSERVICE_CONTRACTID, &rv); if (NS_SUCCEEDED(rv)) - rv = imapService->DiscoverChildren(m_eventQueue, this, this, + rv = imapService->DiscoverChildren(m_thread, this, this, m_onlineFolderName.get(), nsnull); } @@ -8145,7 +8133,7 @@ nsImapMailFolder::StoreCustomKeywords(nsIMsgWindow *aMsgWindow, const char *aFla NS_ENSURE_SUCCESS(rv, rv); nsCAutoString msgIds; AllocateUidStringFromKeys(aKeysToStore, aNumKeys, msgIds); - return imapService->StoreCustomKeywords(m_eventQueue, this, aMsgWindow, aFlagsToAdd, aFlagsToSubtract, msgIds.get(), _retval); + return imapService->StoreCustomKeywords(m_thread, this, aMsgWindow, aFlagsToAdd, aFlagsToSubtract, msgIds.get(), _retval); } NS_IMETHODIMP nsImapMailFolder::NotifyIfNewMail() @@ -8456,7 +8444,7 @@ NS_IMETHODIMP nsImapMailFolder::FetchMsgPreviewText(nsMsgKey *aKeysToFetch, PRUi AllocateImapUidString(keysToFetchFromServer.GetArray(), msgCount, nsnull, messageIds); - rv = imapService->GetBodyStart(m_eventQueue, this, aUrlListener, + rv = imapService->GetBodyStart(m_thread, this, aUrlListener, messageIds.get(), 2048, nsnull); *aAsyncResults = PR_TRUE; // the preview text will be available async... } diff --git a/mozilla/mailnews/imap/src/nsImapMailFolder.h b/mozilla/mailnews/imap/src/nsImapMailFolder.h index d334a6844c6..6c89807347d 100644 --- a/mozilla/mailnews/imap/src/nsImapMailFolder.h +++ b/mozilla/mailnews/imap/src/nsImapMailFolder.h @@ -54,12 +54,13 @@ #include "nsIMsgFilterList.h" #include "nsIMsgFilterPlugin.h" #include "prmon.h" -#include "nsIEventQueue.h" #include "nsIMsgImapMailFolder.h" #include "nsIMsgLocalMailFolder.h" #include "nsIImapMailFolderSink.h" #include "nsIImapServerSink.h" #include "nsIMsgFilterPlugin.h" +#include "nsIEventTarget.h" +#include "nsIThread.h" class nsImapMoveCoalescer; class nsHashtable; class nsHashKey; @@ -441,7 +442,7 @@ protected: PRInt32 m_numStatusRecentMessages; // used to store counts from Status command PRInt32 m_numStatusUnseenMessages; PRInt32 m_nextMessageByteLength; - nsCOMPtr m_eventQueue; + nsCOMPtr m_thread; nsCOMPtr m_urlListener; PRBool m_urlRunning; diff --git a/mozilla/mailnews/imap/src/nsImapProtocol.cpp b/mozilla/mailnews/imap/src/nsImapProtocol.cpp index 87b73eb58bb..155b039fe08 100644 --- a/mozilla/mailnews/imap/src/nsImapProtocol.cpp +++ b/mozilla/mailnews/imap/src/nsImapProtocol.cpp @@ -53,7 +53,7 @@ #include "nsIStringBundle.h" #include "nsMsgImapCID.h" -#include "nsIEventQueueService.h" +#include "nsThreadUtils.h" #include "nsISupportsObsolete.h" #include "nsImapCore.h" @@ -106,13 +106,11 @@ PRLogModuleInfo *IMAP; #include "nsIProxyObjectManager.h" #include "nsIStreamConverterService.h" #include "nsIProxyInfo.h" -#include "nsEventQueueUtils.h" #include "nsISSLSocketControl.h" #define ONE_SECOND ((PRUint32)1000) // one second static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID); -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID); static NS_DEFINE_CID(kProxyObjectManagerCID, NS_PROXYEVENT_MANAGER_CID); static NS_DEFINE_CID(kStreamListenerTeeCID, NS_STREAMLISTENERTEE_CID); @@ -473,11 +471,11 @@ nsresult nsImapProtocol::Configure(PRInt32 TooFastTime, PRInt32 IdealTime, nsresult nsImapProtocol::Initialize(nsIImapHostSessionList * aHostSessionList, nsIImapIncomingServer *aServer, - nsIEventQueue * aSinkEventQueue) + nsIEventTarget * aSinkEventTarget) { - NS_PRECONDITION(aSinkEventQueue && aHostSessionList, - "oops...trying to initialize with a null sink event queue!"); - if (!aSinkEventQueue || !aHostSessionList || !aServer) + NS_PRECONDITION(aSinkEventTarget && aHostSessionList, + "oops...trying to initialize with a null sink event target!"); + if (!aSinkEventTarget || !aHostSessionList || !aServer) return NS_ERROR_NULL_POINTER; nsresult rv = m_downloadLineCache.GrowBuffer(kDownLoadCacheSize); @@ -490,7 +488,7 @@ nsresult nsImapProtocol::Initialize(nsIImapHostSessionList * aHostSessionList, n aServer->GetUseIdle(&m_useIdle); NS_ADDREF(m_flagState); - m_sinkEventQueue = aSinkEventQueue; + m_sinkEventTarget = aSinkEventTarget; m_hostSessionList = aHostSessionList; // no ref count...host session list has life time > connection m_parser.SetHostSessionList(aHostSessionList); m_parser.SetFlagState(m_flagState); @@ -507,7 +505,7 @@ nsresult nsImapProtocol::Initialize(nsIImapHostSessionList * aHostSessionList, n m_fetchMsgListMonitor = PR_NewMonitor(); m_fetchBodyListMonitor = PR_NewMonitor(); - nsresult rv = NS_NewThread(getter_AddRefs(m_iThread), this); + nsresult rv = NS_NewThread(getter_AddRefs(m_iThread), this, "imap"); if (NS_FAILED(rv)) { NS_ASSERTION(m_iThread, "Unable to create imap thread.\n"); @@ -613,7 +611,7 @@ nsImapProtocol::SetupSinkProxy() if (m_runningUrl) { - NS_ASSERTION(m_sinkEventQueue && m_thread, "fatal... null sink event queue or thread"); + NS_ASSERTION(m_sinkEventTarget && m_thread, "fatal... null sink event queue or thread"); nsCOMPtr proxyManager(do_GetService(kProxyObjectManagerCID, &res)); if (proxyManager) // if we don't get one of these are as good as dead... @@ -623,10 +621,10 @@ nsImapProtocol::SetupSinkProxy() nsCOMPtr aImapMailFolderSink; res = m_runningUrl->GetImapMailFolderSink(getter_AddRefs(aImapMailFolderSink)); if (NS_SUCCEEDED(res) && aImapMailFolderSink) - res = proxyManager->GetProxyForObject(m_sinkEventQueue, + res = proxyManager->GetProxyForObject(m_sinkEventTarget, NS_GET_IID(nsIImapMailFolderSink), aImapMailFolderSink, - PROXY_SYNC | PROXY_ALWAYS, + NS_PROXY_SYNC | NS_PROXY_ALWAYS, getter_AddRefs(m_imapMailFolderSink)); } @@ -635,10 +633,10 @@ nsImapProtocol::SetupSinkProxy() nsCOMPtr aImapMessageSink; res = m_runningUrl->GetImapMessageSink(getter_AddRefs(aImapMessageSink)); if (NS_SUCCEEDED(res) && aImapMessageSink) - res = proxyManager->GetProxyForObject(m_sinkEventQueue, + res = proxyManager->GetProxyForObject(m_sinkEventTarget, NS_GET_IID(nsIImapMessageSink), aImapMessageSink, - PROXY_SYNC | PROXY_ALWAYS, + NS_PROXY_SYNC | NS_PROXY_ALWAYS, getter_AddRefs(m_imapMessageSink)); } if (!m_imapServerSink) @@ -646,10 +644,10 @@ nsImapProtocol::SetupSinkProxy() nsCOMPtr aImapServerSink; res = m_runningUrl->GetImapServerSink(getter_AddRefs(aImapServerSink)); if (NS_SUCCEEDED(res) && aImapServerSink) - res = proxyManager->GetProxyForObject( m_sinkEventQueue, + res = proxyManager->GetProxyForObject( m_sinkEventTarget, NS_GET_IID(nsIImapServerSink), aImapServerSink, - PROXY_SYNC | PROXY_ALWAYS, + NS_PROXY_SYNC | NS_PROXY_ALWAYS, getter_AddRefs(m_imapServerSink)); NS_ASSERTION(NS_SUCCEEDED(res), "couldn't get proxies"); } @@ -715,7 +713,12 @@ nsresult nsImapProtocol::SetupWithUrl(nsIURI * aURL, nsISupports* aConsumer) if (aRealStreamListener) { NS_ASSERTION(!m_channelListener, "shouldn't already have a channel listener"); - rv = NS_NewAsyncStreamListener(getter_AddRefs(m_channelListener), aRealStreamListener, m_sinkEventQueue); + rv = NS_GetProxyForObject(m_sinkEventTarget, + NS_GET_IID(nsIStreamListener), + aRealStreamListener, + NS_PROXY_ASYNC | NS_PROXY_ALWAYS, + getter_AddRefs(m_channelListener)); + if (NS_FAILED(rv)) return rv; } PRUint32 capability = kCapabilityUndefined; @@ -824,9 +827,8 @@ nsresult nsImapProtocol::SetupWithUrl(nsIURI * aURL, nsISupports* aConsumer) nsCOMPtr sink = do_QueryInterface(m_mockChannel); if (sink) { - nsCOMPtr eventQ; - NS_GetMainEventQ(getter_AddRefs(eventQ)); - m_transport->SetEventSink(sink, eventQ); + nsCOMPtr thread = do_GetMainThread(); + m_transport->SetEventSink(sink, thread); } // and if we have a cache entry that we are saving the message to, set the security info on it too. @@ -933,7 +935,7 @@ NS_IMETHODIMP nsImapProtocol::Run() me->m_runningUrl = nsnull; CloseStreams(); - me->m_sinkEventQueue = nsnull; + me->m_sinkEventTarget = nsnull; me->m_imapMailFolderSink = nsnull; me->m_imapMessageSink = nsnull; m_iThread = nsnull; @@ -1412,8 +1414,11 @@ PRBool nsImapProtocol::ProcessCurrentURL() { nsCOMPtr request = do_QueryInterface(m_mockChannel); NS_ASSERTION(request, "no request"); - if (request) - rv = m_channelListener->OnStopRequest(request, m_channelContext, NS_OK); + if (request) { + nsresult status; + request->GetStatus(&status); + rv = m_channelListener->OnStopRequest(request, m_channelContext, status); + } } SetFlag(IMAP_CLEAN_UP_URL_STATE); @@ -8276,14 +8281,9 @@ nsresult nsImapMockChannel::ReadFromImapConnection() NS_ENSURE_SUCCESS(rv, rv); // Assume AsyncRead is always called from the UI thread..... - nsCOMPtr queue; - // get the Event Queue for this thread... - nsCOMPtr pEventQService (do_GetService(kEventQueueServiceCID, &rv)); - NS_ENSURE_SUCCESS(rv, rv); - - rv = pEventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(queue)); - NS_ENSURE_SUCCESS(rv, rv); - rv = imapServer->GetImapConnectionAndLoadUrl(queue, imapUrl, nsnull); + nsCOMPtr thread = do_GetCurrentThread(); + NS_ENSURE_STATE(thread); + rv = imapServer->GetImapConnectionAndLoadUrl(thread, imapUrl, nsnull); return rv; } diff --git a/mozilla/mailnews/imap/src/nsImapProtocol.h b/mozilla/mailnews/imap/src/nsImapProtocol.h index da074045198..ebea7bc6eb6 100644 --- a/mozilla/mailnews/imap/src/nsImapProtocol.h +++ b/mozilla/mailnews/imap/src/nsImapProtocol.h @@ -43,7 +43,7 @@ #include "nsIImapUrl.h" #include "nsMsgProtocol.h" -#include "nsIEventQueue.h" +#include "nsIEventTarget.h" #include "nsIStreamListener.h" #include "nsIOutputStream.h" #include "nsIOutputStream.h" @@ -353,8 +353,8 @@ private: // ******* Thread support ******* - nsCOMPtr m_sinkEventQueue; - nsCOMPtr m_iThread; + nsCOMPtr m_sinkEventTarget; + nsCOMPtr m_iThread; PRThread *m_thread; PRMonitor *m_dataAvailableMonitor; // used to notify the arrival of data from the server PRMonitor *m_urlReadyToRunMonitor; // used to notify the arrival of a new url to be processed diff --git a/mozilla/mailnews/imap/src/nsImapProxyEvent.h b/mozilla/mailnews/imap/src/nsImapProxyEvent.h index 216f3f64eb9..db0c1f9de05 100644 --- a/mozilla/mailnews/imap/src/nsImapProxyEvent.h +++ b/mozilla/mailnews/imap/src/nsImapProxyEvent.h @@ -38,7 +38,7 @@ #ifndef nsImapProxyEvent_h__ #define nsImapProxyEvent_h__ -#include "plevent.h" +#include "nsThreadUtils.h" #include "prthread.h" #include "nsISupports.h" #include "nsIURL.h" @@ -50,35 +50,31 @@ #include "nsIImapUrl.h" #include "nsIImapMailFolderSink.h" #include "nsIMsgFolder.h" // TO include biffState enum. Change to bool later... - - #include "nsCOMPtr.h" + class nsImapProxyBase { public: nsImapProxyBase(nsIImapProtocol* aProtocol, - nsIEventQueue* aEventQ, + nsIEventTarget* aEventTarget, PRThread* aThread); virtual ~nsImapProxyBase(); - nsIEventQueue* m_eventQueue; + nsIEventTarget* m_eventTarget; PRThread* m_thread; nsIImapProtocol* m_protocol; }; /* ******* Imap Base Event struct ******** */ -struct nsImapEvent : public PLEvent +struct nsImapEvent : public nsRunnable { nsImapEvent(); virtual ~nsImapEvent(); virtual void InitEvent(); - NS_IMETHOD HandleEvent() = 0; - void PostEvent(nsIEventQueue* aEventQ); + void PostEvent(nsIEventTarget* aTarget); virtual void SetNotifyCompletion(PRBool notifyCompletion); - static void* PR_CALLBACK imap_event_handler(PLEvent* aEvent); - static void PR_CALLBACK imap_event_destructor(PLEvent *aEvent); PRBool m_notifyCompletion; }; diff --git a/mozilla/mailnews/imap/src/nsImapService.cpp b/mozilla/mailnews/imap/src/nsImapService.cpp index ed3deadb34f..882697ea059 100644 --- a/mozilla/mailnews/imap/src/nsImapService.cpp +++ b/mozilla/mailnews/imap/src/nsImapService.cpp @@ -57,7 +57,6 @@ #include "nsIDocShell.h" #include "nsIDocShellLoadInfo.h" #include "nsIRDFService.h" -#include "nsIEventQueueService.h" #include "nsXPIDLString.h" #include "nsReadableUtils.h" #include "nsRDFCID.h" @@ -100,13 +99,13 @@ #include "nsImapProtocol.h" #include "nsIMsgMailSession.h" #include "nsIStreamConverterService.h" +#include "nsThreadUtils.h" #include "nsNetUtil.h" #include "nsInt64.h" #define PREF_MAIL_ROOT_IMAP "mail.root.imap" // old - for backward compatibility only #define PREF_MAIL_ROOT_IMAP_REL "mail.root.imap-rel" -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); static NS_DEFINE_CID(kImapUrlCID, NS_IMAPURL_CID); static NS_DEFINE_CID(kCacheServiceCID, NS_CACHESERVICE_CID); @@ -202,15 +201,15 @@ nsImapService::GetFolderName(nsIMsgFolder* aImapFolder, } NS_IMETHODIMP -nsImapService::SelectFolder(nsIEventQueue * aClientEventQueue, +nsImapService::SelectFolder(nsIEventTarget * aClientEventTarget, nsIMsgFolder * aImapMailFolder, nsIUrlListener * aUrlListener, nsIMsgWindow *aMsgWindow, nsIURI ** aURL) { - NS_ASSERTION (aImapMailFolder && aClientEventQueue, + NS_ASSERTION (aImapMailFolder && aClientEventTarget, "Oops ... null pointer"); - if (!aImapMailFolder || !aClientEventQueue) + if (!aImapMailFolder || !aClientEventTarget) return NS_ERROR_NULL_POINTER; if (WeAreOffline()) @@ -253,7 +252,7 @@ nsImapService::SelectFolder(nsIEventQueue * aClientEventQueue, urlSpec.Append((const char *) folderName); rv = mailNewsUrl->SetSpec(urlSpec); if (NS_SUCCEEDED(rv)) - rv = GetImapConnectionAndLoadUrl(aClientEventQueue, + rv = GetImapConnectionAndLoadUrl(aClientEventTarget, imapUrl, nsnull, aURL); @@ -265,12 +264,12 @@ nsImapService::SelectFolder(nsIEventQueue * aClientEventQueue, // lite select, used to verify UIDVALIDITY while going on/offline NS_IMETHODIMP -nsImapService::LiteSelectFolder(nsIEventQueue * aClientEventQueue, +nsImapService::LiteSelectFolder(nsIEventTarget * aClientEventTarget, nsIMsgFolder * aImapMailFolder, nsIUrlListener * aUrlListener, nsIURI ** aURL) { - return FolderCommand(aClientEventQueue, aImapMailFolder, aUrlListener, + return FolderCommand(aClientEventTarget, aImapMailFolder, aUrlListener, "/liteselect>", nsIImapUrl::nsImapLiteSelectFolder, aURL); } @@ -693,16 +692,8 @@ nsresult nsImapService::FetchMimePart(nsIImapUrl * aImapUrl, #if defined(DEBUG_mscott) || defined(DEBUG_bienvenu) NS_ASSERTION(0, "oops...someone still is reaching this part of the code"); #endif - nsCOMPtr queue; - // get the Event Queue for this thread... - nsCOMPtr pEventQService = - do_GetService(kEventQueueServiceCID, &rv); - - if (NS_FAILED(rv)) return rv; - - rv = pEventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(queue)); - if (NS_FAILED(rv)) return rv; - rv = GetImapConnectionAndLoadUrl(queue, aImapUrl, aDisplayConsumer, aURL); + nsCOMPtr thread = do_GetCurrentThread(); + rv = GetImapConnectionAndLoadUrl(thread, aImapUrl, aDisplayConsumer, aURL); } } } @@ -858,16 +849,8 @@ NS_IMETHODIMP nsImapService::Search(nsIMsgSearchSession *aSearchSession, nsIMsgW rv = mailNewsUrl->SetSpec(urlSpec); if (NS_SUCCEEDED(rv)) { - nsCOMPtr queue; - // get the Event Queue for this thread... - nsCOMPtr pEventQService = - do_GetService(kEventQueueServiceCID, &rv); - - if (NS_FAILED(rv)) return rv; - - rv = pEventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(queue)); - if (NS_FAILED(rv)) return rv; - rv = GetImapConnectionAndLoadUrl(queue, imapUrl, nsnull, nsnull); + nsCOMPtr thread = do_GetCurrentThread(); + rv = GetImapConnectionAndLoadUrl(thread, imapUrl, nsnull, nsnull); } } return rv; @@ -1101,16 +1084,8 @@ nsImapService::FetchMessage(nsIImapUrl * aImapUrl, #if defined(DEBUG_mscott) || defined(DEBUG_bienvenu) NS_ASSERTION(0, "oops...someone still is reaching this part of the code"); #endif - nsCOMPtr queue; - // get the Event Queue for this thread... - nsCOMPtr pEventQService = - do_GetService(kEventQueueServiceCID, &rv); - - if (NS_FAILED(rv)) return rv; - - rv = pEventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(queue)); - if (NS_FAILED(rv)) return rv; - rv = GetImapConnectionAndLoadUrl(queue, aImapUrl, aDisplayConsumer, aURL); + nsCOMPtr thread = do_GetCurrentThread(); + rv = GetImapConnectionAndLoadUrl(thread, aImapUrl, aDisplayConsumer, aURL); } } return rv; @@ -1254,7 +1229,7 @@ nsImapService::CreateStartOfImapUrl(const char * aImapURI, nsIImapUrl ** imapUrl /* 'x' is the message UID or sequence number list */ /* will not affect the 'SEEN' flag */ NS_IMETHODIMP -nsImapService::GetHeaders(nsIEventQueue * aClientEventQueue, +nsImapService::GetHeaders(nsIEventTarget * aClientEventTarget, nsIMsgFolder * aImapMailFolder, nsIUrlListener * aUrlListener, nsIURI ** aURL, @@ -1264,9 +1239,9 @@ nsImapService::GetHeaders(nsIEventQueue * aClientEventQueue, // create a protocol instance to handle the request. // NOTE: once we start working with multiple connections, this step will be much more complicated...but for now // just create a connection and process the request. - NS_ASSERTION (aImapMailFolder && aClientEventQueue, + NS_ASSERTION (aImapMailFolder && aClientEventTarget, "Oops ... null pointer"); - if (!aImapMailFolder || !aClientEventQueue) + if (!aImapMailFolder || !aClientEventTarget) return NS_ERROR_NULL_POINTER; nsCOMPtr imapUrl; @@ -1298,7 +1273,7 @@ nsImapService::GetHeaders(nsIEventQueue * aClientEventQueue, rv = uri->SetSpec(urlSpec); if (NS_SUCCEEDED(rv)) - rv = GetImapConnectionAndLoadUrl(aClientEventQueue, imapUrl, + rv = GetImapConnectionAndLoadUrl(aClientEventTarget, imapUrl, nsnull, aURL); } @@ -1313,7 +1288,7 @@ nsImapService::GetHeaders(nsIEventQueue * aClientEventQueue, /* 'n' is the number of bytes to fetch */ /* will not affect the 'SEEN' flag */ NS_IMETHODIMP -nsImapService::GetBodyStart(nsIEventQueue * aClientEventQueue, +nsImapService::GetBodyStart(nsIEventTarget * aClientEventTarget, nsIMsgFolder * aImapMailFolder, nsIUrlListener * aUrlListener, const char *messageIdentifierList, @@ -1321,9 +1296,9 @@ nsImapService::GetBodyStart(nsIEventQueue * aClientEventQueue, nsIURI ** aURL) { nsresult rv; - NS_ASSERTION (aImapMailFolder && aClientEventQueue, + NS_ASSERTION (aImapMailFolder && aClientEventTarget, "Oops ... null pointer"); - if (!aImapMailFolder || !aClientEventQueue) + if (!aImapMailFolder || !aClientEventTarget) return NS_ERROR_NULL_POINTER; nsCOMPtr imapUrl; @@ -1357,23 +1332,23 @@ nsImapService::GetBodyStart(nsIEventQueue * aClientEventQueue, urlSpec.AppendInt(numBytes); rv = uri->SetSpec(urlSpec); if (NS_SUCCEEDED(rv)) - rv = GetImapConnectionAndLoadUrl(aClientEventQueue, imapUrl, + rv = GetImapConnectionAndLoadUrl(aClientEventTarget, imapUrl, nsnull, aURL); } } return rv; } -nsresult nsImapService::FolderCommand(nsIEventQueue * clientEventQueue, +nsresult nsImapService::FolderCommand(nsIEventTarget * clientEventTarget, nsIMsgFolder * imapMailFolder, nsIUrlListener * urlListener, const char *command, nsImapAction imapAction, nsIURI ** url) { - NS_ASSERTION (imapMailFolder && clientEventQueue, + NS_ASSERTION (imapMailFolder && clientEventTarget, "Oops ... null pointer"); - if (!imapMailFolder || !clientEventQueue) + if (!imapMailFolder || !clientEventTarget) return NS_ERROR_NULL_POINTER; nsCOMPtr imapUrl; @@ -1401,7 +1376,7 @@ nsresult nsImapService::FolderCommand(nsIEventQueue * clientEventQueue, urlSpec.Append((const char *) folderName); rv = uri->SetSpec(urlSpec); if (NS_SUCCEEDED(rv)) - rv = GetImapConnectionAndLoadUrl(clientEventQueue, imapUrl, + rv = GetImapConnectionAndLoadUrl(clientEventTarget, imapUrl, nsnull, url); } } @@ -1410,40 +1385,40 @@ nsresult nsImapService::FolderCommand(nsIEventQueue * clientEventQueue, // Noop, used to update a folder (causes server to send changes). NS_IMETHODIMP -nsImapService::Noop(nsIEventQueue * aClientEventQueue, +nsImapService::Noop(nsIEventTarget * aClientEventTarget, nsIMsgFolder * aImapMailFolder, nsIUrlListener * aUrlListener, nsIURI ** aURL) { - return FolderCommand(aClientEventQueue, aImapMailFolder, aUrlListener, + return FolderCommand(aClientEventTarget, aImapMailFolder, aUrlListener, "/selectnoop>", nsIImapUrl::nsImapSelectNoopFolder, aURL); } // FolderStatus, used to update message counts NS_IMETHODIMP -nsImapService::UpdateFolderStatus(nsIEventQueue * aClientEventQueue, +nsImapService::UpdateFolderStatus(nsIEventTarget * aClientEventTarget, nsIMsgFolder * aImapMailFolder, nsIUrlListener * aUrlListener, nsIURI ** aURL) { - return FolderCommand(aClientEventQueue, aImapMailFolder, aUrlListener, + return FolderCommand(aClientEventTarget, aImapMailFolder, aUrlListener, "/folderstatus>", nsIImapUrl::nsImapFolderStatus, aURL); } // Expunge, used to "compress" an imap folder,removes deleted messages. NS_IMETHODIMP -nsImapService::Expunge(nsIEventQueue * aClientEventQueue, +nsImapService::Expunge(nsIEventTarget * aClientEventTarget, nsIMsgFolder * aImapMailFolder, nsIUrlListener * aUrlListener, nsIURI ** aURL) { - return FolderCommand(aClientEventQueue, aImapMailFolder, aUrlListener, + return FolderCommand(aClientEventTarget, aImapMailFolder, aUrlListener, "/Expunge>", nsIImapUrl::nsImapExpungeFolder, aURL); } /* old-stle biff that doesn't download headers */ NS_IMETHODIMP -nsImapService::Biff(nsIEventQueue * aClientEventQueue, +nsImapService::Biff(nsIEventTarget * aClientEventTarget, nsIMsgFolder * aImapMailFolder, nsIUrlListener * aUrlListener, nsIURI ** aURL, @@ -1451,9 +1426,9 @@ nsImapService::Biff(nsIEventQueue * aClientEventQueue, { // static const char *formatString = "biff>%c%s>%ld"; - NS_ASSERTION (aImapMailFolder && aClientEventQueue, + NS_ASSERTION (aImapMailFolder && aClientEventTarget, "Oops ... null pointer"); - if (!aImapMailFolder || !aClientEventQueue) + if (!aImapMailFolder || !aClientEventTarget) return NS_ERROR_NULL_POINTER; nsCOMPtr imapUrl; @@ -1483,7 +1458,7 @@ nsImapService::Biff(nsIEventQueue * aClientEventQueue, urlSpec.AppendInt(uidHighWater); rv = uri->SetSpec(urlSpec); if (NS_SUCCEEDED(rv)) - rv = GetImapConnectionAndLoadUrl(aClientEventQueue, imapUrl, + rv = GetImapConnectionAndLoadUrl(aClientEventTarget, imapUrl, nsnull, aURL); } } @@ -1491,7 +1466,7 @@ nsImapService::Biff(nsIEventQueue * aClientEventQueue, } NS_IMETHODIMP -nsImapService::DeleteFolder(nsIEventQueue* aClientEventQueue, +nsImapService::DeleteFolder(nsIEventTarget* aClientEventTarget, nsIMsgFolder* aImapMailFolder, nsIUrlListener* aUrlListener, nsIURI** aURL) @@ -1508,14 +1483,14 @@ nsImapService::DeleteFolder(nsIEventQueue* aClientEventQueue, imapServer->GetIsAOLServer(&removeFolderAndMsgs); } - return FolderCommand(aClientEventQueue, aImapMailFolder, aUrlListener, + return FolderCommand(aClientEventTarget, aImapMailFolder, aUrlListener, removeFolderAndMsgs ? "/deletefolder>": "/delete>", nsIImapUrl::nsImapDeleteFolder, aURL); } NS_IMETHODIMP -nsImapService::DeleteMessages(nsIEventQueue * aClientEventQueue, +nsImapService::DeleteMessages(nsIEventTarget * aClientEventTarget, nsIMsgFolder * aImapMailFolder, nsIUrlListener * aUrlListener, nsIURI ** aURL, @@ -1526,9 +1501,9 @@ nsImapService::DeleteMessages(nsIEventQueue * aClientEventQueue, // create a protocol instance to handle the request. // NOTE: once we start working with multiple connections, this step will be much more complicated...but for now // just create a connection and process the request. - NS_ASSERTION (aImapMailFolder && aClientEventQueue, + NS_ASSERTION (aImapMailFolder && aClientEventTarget, "Oops ... null pointer"); - if (!aImapMailFolder || !aClientEventQueue) + if (!aImapMailFolder || !aClientEventTarget) return NS_ERROR_NULL_POINTER; nsCOMPtr imapUrl; @@ -1560,7 +1535,7 @@ nsImapService::DeleteMessages(nsIEventQueue * aClientEventQueue, urlSpec.Append(messageIdentifierList); rv = uri->SetSpec(urlSpec); if (NS_SUCCEEDED(rv)) - rv = GetImapConnectionAndLoadUrl(aClientEventQueue, imapUrl, + rv = GetImapConnectionAndLoadUrl(aClientEventTarget, imapUrl, nsnull, aURL); } @@ -1570,17 +1545,17 @@ nsImapService::DeleteMessages(nsIEventQueue * aClientEventQueue, // Delete all messages in a folder, used to empty trash NS_IMETHODIMP -nsImapService::DeleteAllMessages(nsIEventQueue * aClientEventQueue, +nsImapService::DeleteAllMessages(nsIEventTarget * aClientEventTarget, nsIMsgFolder * aImapMailFolder, nsIUrlListener * aUrlListener, nsIURI ** aURL) { - return FolderCommand(aClientEventQueue, aImapMailFolder, aUrlListener, + return FolderCommand(aClientEventTarget, aImapMailFolder, aUrlListener, "/deleteallmsgs>", nsIImapUrl::nsImapSelectNoopFolder, aURL); } NS_IMETHODIMP -nsImapService::AddMessageFlags(nsIEventQueue * aClientEventQueue, +nsImapService::AddMessageFlags(nsIEventTarget * aClientEventTarget, nsIMsgFolder * aImapMailFolder, nsIUrlListener * aUrlListener, nsIURI ** aURL, @@ -1588,12 +1563,12 @@ nsImapService::AddMessageFlags(nsIEventQueue * aClientEventQueue, imapMessageFlagsType flags, PRBool messageIdsAreUID) { - return DiddleFlags(aClientEventQueue, aImapMailFolder, aUrlListener, aURL, messageIdentifierList, + return DiddleFlags(aClientEventTarget, aImapMailFolder, aUrlListener, aURL, messageIdentifierList, "addmsgflags", flags, messageIdsAreUID); } NS_IMETHODIMP -nsImapService::SubtractMessageFlags(nsIEventQueue * aClientEventQueue, +nsImapService::SubtractMessageFlags(nsIEventTarget * aClientEventTarget, nsIMsgFolder * aImapMailFolder, nsIUrlListener * aUrlListener, nsIURI ** aURL, @@ -1601,12 +1576,12 @@ nsImapService::SubtractMessageFlags(nsIEventQueue * aClientEventQueue, imapMessageFlagsType flags, PRBool messageIdsAreUID) { - return DiddleFlags(aClientEventQueue, aImapMailFolder, aUrlListener, aURL, messageIdentifierList, + return DiddleFlags(aClientEventTarget, aImapMailFolder, aUrlListener, aURL, messageIdentifierList, "subtractmsgflags", flags, messageIdsAreUID); } NS_IMETHODIMP -nsImapService::SetMessageFlags(nsIEventQueue * aClientEventQueue, +nsImapService::SetMessageFlags(nsIEventTarget * aClientEventTarget, nsIMsgFolder * aImapMailFolder, nsIUrlListener * aUrlListener, nsIURI ** aURL, @@ -1618,11 +1593,11 @@ nsImapService::SetMessageFlags(nsIEventQueue * aClientEventQueue, // NOTE: once we start working with multiple connections, this step will be much more complicated...but for now // just create a connection and process the request. - return DiddleFlags(aClientEventQueue, aImapMailFolder, aUrlListener, aURL, messageIdentifierList, + return DiddleFlags(aClientEventTarget, aImapMailFolder, aUrlListener, aURL, messageIdentifierList, "setmsgflags", flags, messageIdsAreUID); } -nsresult nsImapService::DiddleFlags(nsIEventQueue * aClientEventQueue, +nsresult nsImapService::DiddleFlags(nsIEventTarget * aClientEventTarget, nsIMsgFolder * aImapMailFolder, nsIUrlListener * aUrlListener, nsIURI ** aURL, @@ -1634,9 +1609,9 @@ nsresult nsImapService::DiddleFlags(nsIEventQueue * aClientEventQueue, // create a protocol instance to handle the request. // NOTE: once we start working with multiple connections, this step will be much more complicated...but for now // just create a connection and process the request. - NS_ASSERTION (aImapMailFolder && aClientEventQueue, + NS_ASSERTION (aImapMailFolder && aClientEventTarget, "Oops ... null pointer"); - if (!aImapMailFolder || !aClientEventQueue) + if (!aImapMailFolder || !aClientEventTarget) return NS_ERROR_NULL_POINTER; nsCOMPtr imapUrl; @@ -1671,7 +1646,7 @@ nsresult nsImapService::DiddleFlags(nsIEventQueue * aClientEventQueue, urlSpec.AppendInt(flags); rv = uri->SetSpec(urlSpec); if (NS_SUCCEEDED(rv)) - rv = GetImapConnectionAndLoadUrl(aClientEventQueue, imapUrl, + rv = GetImapConnectionAndLoadUrl(aClientEventTarget, imapUrl, nsnull, aURL); } } @@ -1720,15 +1695,15 @@ nsImapService::SetImapUrlSink(nsIMsgFolder* aMsgFolder, } NS_IMETHODIMP -nsImapService::DiscoverAllFolders(nsIEventQueue* aClientEventQueue, +nsImapService::DiscoverAllFolders(nsIEventTarget* aClientEventTarget, nsIMsgFolder* aImapMailFolder, nsIUrlListener* aUrlListener, nsIMsgWindow * aMsgWindow, nsIURI** aURL) { - NS_ASSERTION (aImapMailFolder && aClientEventQueue, - "Oops ... null aClientEventQueue or aImapMailFolder"); - if (!aImapMailFolder || ! aClientEventQueue) + NS_ASSERTION (aImapMailFolder && aClientEventTarget, + "Oops ... null aClientEventTarget or aImapMailFolder"); + if (!aImapMailFolder || ! aClientEventTarget) return NS_ERROR_NULL_POINTER; nsCOMPtr imapUrl; @@ -1752,7 +1727,7 @@ nsImapService::DiscoverAllFolders(nsIEventQueue* aClientEventQueue, nsCOMPtr url = do_QueryInterface(imapUrl, &rv); rv = uri->SetSpec(urlSpec); if (NS_SUCCEEDED(rv)) - rv = GetImapConnectionAndLoadUrl(aClientEventQueue, imapUrl, + rv = GetImapConnectionAndLoadUrl(aClientEventTarget, imapUrl, nsnull, aURL); } } @@ -1760,14 +1735,14 @@ nsImapService::DiscoverAllFolders(nsIEventQueue* aClientEventQueue, } NS_IMETHODIMP -nsImapService::DiscoverAllAndSubscribedFolders(nsIEventQueue* aClientEventQueue, +nsImapService::DiscoverAllAndSubscribedFolders(nsIEventTarget* aClientEventTarget, nsIMsgFolder* aImapMailFolder, nsIUrlListener* aUrlListener, nsIURI** aURL) { - NS_ASSERTION (aImapMailFolder && aClientEventQueue, - "Oops ... null aClientEventQueue or aImapMailFolder"); - if (!aImapMailFolder || ! aClientEventQueue) + NS_ASSERTION (aImapMailFolder && aClientEventTarget, + "Oops ... null aClientEventTarget or aImapMailFolder"); + if (!aImapMailFolder || ! aClientEventTarget) return NS_ERROR_NULL_POINTER; nsCOMPtr aImapUrl; @@ -1788,7 +1763,7 @@ nsImapService::DiscoverAllAndSubscribedFolders(nsIEventQueue* aClientEventQueue, urlSpec.Append("/discoverallandsubscribedboxes"); rv = uri->SetSpec(urlSpec); if (NS_SUCCEEDED(rv)) - rv = GetImapConnectionAndLoadUrl(aClientEventQueue, aImapUrl, + rv = GetImapConnectionAndLoadUrl(aClientEventTarget, aImapUrl, nsnull, aURL); } } @@ -1796,15 +1771,15 @@ nsImapService::DiscoverAllAndSubscribedFolders(nsIEventQueue* aClientEventQueue, } NS_IMETHODIMP -nsImapService::DiscoverChildren(nsIEventQueue* aClientEventQueue, +nsImapService::DiscoverChildren(nsIEventTarget* aClientEventTarget, nsIMsgFolder* aImapMailFolder, nsIUrlListener* aUrlListener, const char *folderPath, nsIURI** aURL) { - NS_ASSERTION (aImapMailFolder && aClientEventQueue, - "Oops ... null aClientEventQueue or aImapMailFolder"); - if (!aImapMailFolder || ! aClientEventQueue) + NS_ASSERTION (aImapMailFolder && aClientEventTarget, + "Oops ... null aClientEventTarget or aImapMailFolder"); + if (!aImapMailFolder || ! aClientEventTarget) return NS_ERROR_NULL_POINTER; nsCOMPtr aImapUrl; @@ -1842,7 +1817,7 @@ nsImapService::DiscoverChildren(nsIEventQueue* aClientEventQueue, if (NS_SUCCEEDED(rv)) - rv = GetImapConnectionAndLoadUrl(aClientEventQueue, + rv = GetImapConnectionAndLoadUrl(aClientEventTarget, aImapUrl, nsnull, aURL); } @@ -1857,7 +1832,7 @@ nsImapService::DiscoverChildren(nsIEventQueue* aClientEventQueue, NS_IMETHODIMP -nsImapService::OnlineMessageCopy(nsIEventQueue* aClientEventQueue, +nsImapService::OnlineMessageCopy(nsIEventTarget* aClientEventTarget, nsIMsgFolder* aSrcFolder, const char* messageIds, nsIMsgFolder* aDstFolder, @@ -1868,9 +1843,9 @@ nsImapService::OnlineMessageCopy(nsIEventQueue* aClientEventQueue, nsISupports* copyState, nsIMsgWindow *aMsgWindow) { - NS_ASSERTION(aSrcFolder && aDstFolder && messageIds && aClientEventQueue, + NS_ASSERTION(aSrcFolder && aDstFolder && messageIds && aClientEventTarget, "Fatal ... missing key parameters"); - if (!aClientEventQueue || !aSrcFolder || !aDstFolder || !messageIds || + if (!aClientEventTarget || !aSrcFolder || !aDstFolder || !messageIds || *messageIds == 0) return NS_ERROR_NULL_POINTER; @@ -1936,7 +1911,7 @@ nsImapService::OnlineMessageCopy(nsIEventQueue* aClientEventQueue, rv = uri->SetSpec(urlSpec); if (NS_SUCCEEDED(rv)) - rv = GetImapConnectionAndLoadUrl(aClientEventQueue, imapUrl, + rv = GetImapConnectionAndLoadUrl(aClientEventTarget, imapUrl, nsnull, aURL); } return rv; @@ -2056,7 +2031,7 @@ nsresult nsImapService::OfflineAppendFromFile(nsIFileSpec* aFileSpec, /* imap://HOST>appendmsgfromfile>DESTINATIONMAILBOXPATH */ /* imap://HOST>appenddraftfromfile>DESTINATIONMAILBOXPATH>UID>messageId */ NS_IMETHODIMP -nsImapService::AppendMessageFromFile(nsIEventQueue* aClientEventQueue, +nsImapService::AppendMessageFromFile(nsIEventTarget* aClientEventTarget, nsIFileSpec* aFileSpec, nsIMsgFolder* aDstFolder, const char* messageId, // te be replaced @@ -2068,7 +2043,7 @@ nsImapService::AppendMessageFromFile(nsIEventQueue* aClientEventQueue, nsIMsgWindow *aMsgWindow) { nsresult rv = NS_ERROR_NULL_POINTER; - if (!aClientEventQueue || !aFileSpec || !aDstFolder) + if (!aClientEventTarget || !aFileSpec || !aDstFolder) return rv; nsCOMPtr imapUrl; @@ -2122,14 +2097,14 @@ nsImapService::AppendMessageFromFile(nsIEventQueue* aClientEventQueue, // handle offline append to drafts or templates folder here. } if (NS_SUCCEEDED(rv)) - rv = GetImapConnectionAndLoadUrl(aClientEventQueue, imapUrl, + rv = GetImapConnectionAndLoadUrl(aClientEventTarget, imapUrl, nsnull, aURL); } return rv; } nsresult -nsImapService::GetImapConnectionAndLoadUrl(nsIEventQueue* aClientEventQueue, +nsImapService::GetImapConnectionAndLoadUrl(nsIEventTarget* aClientEventTarget, nsIImapUrl* aImapUrl, nsISupports* aConsumer, nsIURI** aURL) @@ -2160,20 +2135,20 @@ nsImapService::GetImapConnectionAndLoadUrl(nsIEventQueue* aClientEventQueue, { nsCOMPtr aImapServer(do_QueryInterface(aMsgIncomingServer, &rv)); if (NS_SUCCEEDED(rv) && aImapServer) - rv = aImapServer->GetImapConnectionAndLoadUrl(aClientEventQueue, + rv = aImapServer->GetImapConnectionAndLoadUrl(aClientEventTarget, aImapUrl, aConsumer); } return rv; } NS_IMETHODIMP -nsImapService::MoveFolder(nsIEventQueue* eventQueue, nsIMsgFolder* srcFolder, +nsImapService::MoveFolder(nsIEventTarget* eventTarget, nsIMsgFolder* srcFolder, nsIMsgFolder* dstFolder, nsIUrlListener* urlListener, nsIMsgWindow *msgWindow, nsIURI** url) { - NS_ASSERTION(eventQueue && srcFolder && dstFolder, + NS_ASSERTION(eventTarget && srcFolder && dstFolder, "Oops ... null pointer"); - if (!eventQueue || !srcFolder || !dstFolder) + if (!eventTarget || !srcFolder || !dstFolder) return NS_ERROR_NULL_POINTER; nsCOMPtr imapUrl; @@ -2210,7 +2185,7 @@ nsImapService::MoveFolder(nsIEventQueue* eventQueue, nsIMsgFolder* srcFolder, if (NS_SUCCEEDED(rv)) { GetFolderName(srcFolder, getter_Copies(folderName)); - rv = GetImapConnectionAndLoadUrl(eventQueue, imapUrl, + rv = GetImapConnectionAndLoadUrl(eventTarget, imapUrl, nsnull, url); } @@ -2220,13 +2195,13 @@ nsImapService::MoveFolder(nsIEventQueue* eventQueue, nsIMsgFolder* srcFolder, } NS_IMETHODIMP -nsImapService::RenameLeaf(nsIEventQueue* eventQueue, nsIMsgFolder* srcFolder, +nsImapService::RenameLeaf(nsIEventTarget* eventTarget, nsIMsgFolder* srcFolder, const PRUnichar* newLeafName, nsIUrlListener* urlListener, nsIMsgWindow *msgWindow, nsIURI** url) { - NS_ASSERTION(eventQueue && srcFolder && newLeafName && *newLeafName, + NS_ASSERTION(eventTarget && srcFolder && newLeafName && *newLeafName, "Oops ... [RenameLeaf] null pointers"); - if (!eventQueue || !srcFolder || !newLeafName || !*newLeafName) + if (!eventTarget || !srcFolder || !newLeafName || !*newLeafName) return NS_ERROR_NULL_POINTER; nsCOMPtr imapUrl; @@ -2277,7 +2252,7 @@ nsImapService::RenameLeaf(nsIEventQueue* eventQueue, nsIMsgFolder* srcFolder, rv = uri->SetSpec(urlSpec); if (NS_SUCCEEDED(rv)) { - rv = GetImapConnectionAndLoadUrl(eventQueue, imapUrl, + rv = GetImapConnectionAndLoadUrl(eventTarget, imapUrl, nsnull, url); } } // if (NS_SUCCEEDED(rv)) @@ -2286,13 +2261,13 @@ nsImapService::RenameLeaf(nsIEventQueue* eventQueue, nsIMsgFolder* srcFolder, } NS_IMETHODIMP -nsImapService::CreateFolder(nsIEventQueue* eventQueue, nsIMsgFolder* parent, +nsImapService::CreateFolder(nsIEventTarget* eventTarget, nsIMsgFolder* parent, const PRUnichar* newFolderName, nsIUrlListener* urlListener, nsIURI** url) { - NS_ASSERTION(eventQueue && parent && newFolderName && *newFolderName, + NS_ASSERTION(eventTarget && parent && newFolderName && *newFolderName, "Oops ... [CreateFolder] null pointers"); - if (!eventQueue || !parent || !newFolderName || !*newFolderName) + if (!eventTarget || !parent || !newFolderName || !*newFolderName) return NS_ERROR_NULL_POINTER; nsCOMPtr imapUrl; @@ -2330,7 +2305,7 @@ nsImapService::CreateFolder(nsIEventQueue* eventQueue, nsIMsgFolder* parent, rv = uri->SetSpec(urlSpec); if (NS_SUCCEEDED(rv)) - rv = GetImapConnectionAndLoadUrl(eventQueue, imapUrl, + rv = GetImapConnectionAndLoadUrl(eventTarget, imapUrl, nsnull, url); } // if (NS_SUCCEEDED(rv)) @@ -2339,13 +2314,13 @@ nsImapService::CreateFolder(nsIEventQueue* eventQueue, nsIMsgFolder* parent, } NS_IMETHODIMP -nsImapService::EnsureFolderExists(nsIEventQueue* eventQueue, nsIMsgFolder* parent, +nsImapService::EnsureFolderExists(nsIEventTarget* eventTarget, nsIMsgFolder* parent, const PRUnichar* newFolderName, nsIUrlListener* urlListener, nsIURI** url) { - NS_ASSERTION(eventQueue && parent && newFolderName && *newFolderName, + NS_ASSERTION(eventTarget && parent && newFolderName && *newFolderName, "Oops ... [EnsureExists] null pointers"); - if (!eventQueue || !parent || !newFolderName || !*newFolderName) + if (!eventTarget || !parent || !newFolderName || !*newFolderName) return NS_ERROR_NULL_POINTER; nsCOMPtr imapUrl; @@ -2378,7 +2353,7 @@ nsImapService::EnsureFolderExists(nsIEventQueue* eventQueue, nsIMsgFolder* paren rv = uri->SetSpec(urlSpec); if (NS_SUCCEEDED(rv)) - rv = GetImapConnectionAndLoadUrl(eventQueue, imapUrl, + rv = GetImapConnectionAndLoadUrl(eventTarget, imapUrl, nsnull, url); } // if (NS_SUCCEEDED(rv)) @@ -2388,12 +2363,12 @@ nsImapService::EnsureFolderExists(nsIEventQueue* eventQueue, nsIMsgFolder* paren NS_IMETHODIMP -nsImapService::ListFolder(nsIEventQueue* aClientEventQueue, +nsImapService::ListFolder(nsIEventTarget* aClientEventTarget, nsIMsgFolder* aImapMailFolder, nsIUrlListener* aUrlListener, nsIURI** aURL) { - return FolderCommand(aClientEventQueue, aImapMailFolder, aUrlListener, + return FolderCommand(aClientEventTarget, aImapMailFolder, aUrlListener, "/listfolder>", nsIImapUrl::nsImapListFolder, aURL); } @@ -2944,15 +2919,6 @@ nsImapService::GetListOfFoldersWithPath(nsIImapIncomingServer *aServer, nsIMsgWi if (NS_FAILED(rv)) return rv; if (!listener) return NS_ERROR_FAILURE; - nsCOMPtr queue; - // get the Event Queue for this thread... - nsCOMPtr pEventQService = - do_GetService(kEventQueueServiceCID, &rv); - if (NS_FAILED(rv)) return rv; - - rv = pEventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(queue)); - if (NS_FAILED(rv)) return rv; - // Locate the folder so that the correct hierarchical delimiter is used in the folder // pathnames, otherwise root's (ie, '^') is used and this is wrong. nsCOMPtr msgFolder; @@ -2983,7 +2949,8 @@ nsImapService::GetListOfFoldersWithPath(nsIImapIncomingServer *aServer, nsIMsgWi rv = rootMsgFolder->FindSubFolder(changedStr, getter_AddRefs(msgFolder)); } - rv = DiscoverChildren(queue, msgFolder, listener, folderPath, nsnull); + nsCOMPtr thread = do_GetCurrentThread(); + rv = DiscoverChildren(thread, msgFolder, listener, folderPath, nsnull); if (NS_FAILED(rv)) return rv; return NS_OK; @@ -3007,38 +2974,30 @@ nsImapService::GetListOfFoldersOnServer(nsIImapIncomingServer *aServer, nsIMsgWi if (NS_FAILED(rv)) return rv; if (!listener) return NS_ERROR_FAILURE; - nsCOMPtr queue; - // get the Event Queue for this thread... - nsCOMPtr pEventQService = - do_GetService(kEventQueueServiceCID, &rv); - if (NS_FAILED(rv)) return rv; - - rv = pEventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(queue)); - if (NS_FAILED(rv)) return rv; - - rv = DiscoverAllAndSubscribedFolders(queue, rootMsgFolder, listener, nsnull); + nsCOMPtr thread = do_GetCurrentThread(); + rv = DiscoverAllAndSubscribedFolders(thread, rootMsgFolder, listener, nsnull); if (NS_FAILED(rv)) return rv; return NS_OK; } NS_IMETHODIMP -nsImapService::SubscribeFolder(nsIEventQueue* eventQueue, +nsImapService::SubscribeFolder(nsIEventTarget* eventTarget, nsIMsgFolder* aFolder, const PRUnichar* aFolderName, nsIUrlListener* urlListener, nsIURI** url) { - return ChangeFolderSubscription(eventQueue, aFolder, aFolderName, + return ChangeFolderSubscription(eventTarget, aFolder, aFolderName, "/subscribe>", urlListener, url); } -nsresult nsImapService::ChangeFolderSubscription(nsIEventQueue* eventQueue, +nsresult nsImapService::ChangeFolderSubscription(nsIEventTarget* eventTarget, nsIMsgFolder* folder, const PRUnichar* folderName, const char *command, nsIUrlListener* urlListener, nsIURI** url) { - NS_ENSURE_ARG_POINTER(eventQueue); + NS_ENSURE_ARG_POINTER(eventTarget); NS_ENSURE_ARG_POINTER(folder); NS_ENSURE_ARG_POINTER(folderName); @@ -3064,7 +3023,7 @@ nsresult nsImapService::ChangeFolderSubscription(nsIEventQueue* eventQueue, nsCRT::free(escapedFolderName); rv = uri->SetSpec(urlSpec); if (NS_SUCCEEDED(rv)) - rv = GetImapConnectionAndLoadUrl(eventQueue, imapUrl, + rv = GetImapConnectionAndLoadUrl(eventTarget, imapUrl, nsnull, url); } } @@ -3072,35 +3031,35 @@ nsresult nsImapService::ChangeFolderSubscription(nsIEventQueue* eventQueue, } NS_IMETHODIMP -nsImapService::UnsubscribeFolder(nsIEventQueue* aEventQueue, +nsImapService::UnsubscribeFolder(nsIEventTarget* aEventTarget, nsIMsgFolder* aFolder, const PRUnichar* aFolderName, nsIUrlListener* aUrlListener, nsIURI** aUrl) { - return ChangeFolderSubscription(aEventQueue, aFolder, aFolderName, + return ChangeFolderSubscription(aEventTarget, aFolder, aFolderName, "/unsubscribe>", aUrlListener, aUrl); } NS_IMETHODIMP -nsImapService::GetFolderAdminUrl(nsIEventQueue *aClientEventQueue, +nsImapService::GetFolderAdminUrl(nsIEventTarget *aClientEventTarget, nsIMsgFolder *aImapMailFolder, nsIMsgWindow *aMsgWindow, nsIUrlListener *aUrlListener, nsIURI** aURL) { - return FolderCommand(aClientEventQueue, aImapMailFolder, aUrlListener, + return FolderCommand(aClientEventTarget, aImapMailFolder, aUrlListener, "/refreshfolderurls>", nsIImapUrl::nsImapRefreshFolderUrls, aURL); } NS_IMETHODIMP -nsImapService::IssueCommandOnMsgs(nsIEventQueue *aClientEventQueue, +nsImapService::IssueCommandOnMsgs(nsIEventTarget *aClientEventTarget, nsIMsgFolder *anImapFolder, nsIMsgWindow *aMsgWindow, const char *aCommand, const char *uids, nsIURI** aURL) { - NS_ENSURE_ARG_POINTER(aClientEventQueue); + NS_ENSURE_ARG_POINTER(aClientEventTarget); NS_ENSURE_ARG_POINTER(anImapFolder); NS_ENSURE_ARG_POINTER(aMsgWindow); nsCOMPtr imapUrl; @@ -3135,7 +3094,7 @@ nsImapService::IssueCommandOnMsgs(nsIEventQueue *aClientEventQueue, urlSpec.Append(uids); rv = mailNewsUrl->SetSpec(urlSpec); if (NS_SUCCEEDED(rv)) - rv = GetImapConnectionAndLoadUrl(aClientEventQueue, + rv = GetImapConnectionAndLoadUrl(aClientEventTarget, imapUrl, nsnull, aURL); @@ -3146,14 +3105,14 @@ nsImapService::IssueCommandOnMsgs(nsIEventQueue *aClientEventQueue, } NS_IMETHODIMP -nsImapService::FetchCustomMsgAttribute(nsIEventQueue *aClientEventQueue, +nsImapService::FetchCustomMsgAttribute(nsIEventTarget *aClientEventTarget, nsIMsgFolder *anImapFolder, nsIMsgWindow *aMsgWindow, const char *aAttribute, const char *uids, nsIURI** aURL) { - NS_ENSURE_ARG_POINTER(aClientEventQueue); + NS_ENSURE_ARG_POINTER(aClientEventTarget); NS_ENSURE_ARG_POINTER(anImapFolder); NS_ENSURE_ARG_POINTER(aMsgWindow); nsCOMPtr imapUrl; @@ -3186,7 +3145,7 @@ nsImapService::FetchCustomMsgAttribute(nsIEventQueue *aClientEventQueue, urlSpec.Append(aAttribute); rv = mailNewsUrl->SetSpec(urlSpec); if (NS_SUCCEEDED(rv)) - rv = GetImapConnectionAndLoadUrl(aClientEventQueue, + rv = GetImapConnectionAndLoadUrl(aClientEventTarget, imapUrl, nsnull, aURL); @@ -3197,7 +3156,7 @@ nsImapService::FetchCustomMsgAttribute(nsIEventQueue *aClientEventQueue, } NS_IMETHODIMP -nsImapService::StoreCustomKeywords(nsIEventQueue *aClientEventQueue, +nsImapService::StoreCustomKeywords(nsIEventTarget *aClientEventTarget, nsIMsgFolder *anImapFolder, nsIMsgWindow *aMsgWindow, const char *flagsToAdd, @@ -3205,7 +3164,7 @@ nsImapService::StoreCustomKeywords(nsIEventQueue *aClientEventQueue, const char *uids, nsIURI** aURL) { - NS_ENSURE_ARG_POINTER(aClientEventQueue); + NS_ENSURE_ARG_POINTER(aClientEventTarget); NS_ENSURE_ARG_POINTER(anImapFolder); nsCOMPtr imapUrl; nsCAutoString urlSpec; @@ -3239,7 +3198,7 @@ nsImapService::StoreCustomKeywords(nsIEventQueue *aClientEventQueue, urlSpec.Append(flagsToSubtract); rv = mailNewsUrl->SetSpec(urlSpec); if (NS_SUCCEEDED(rv)) - rv = GetImapConnectionAndLoadUrl(aClientEventQueue, + rv = GetImapConnectionAndLoadUrl(aClientEventTarget, imapUrl, nsnull, aURL); diff --git a/mozilla/mailnews/imap/src/nsImapService.h b/mozilla/mailnews/imap/src/nsImapService.h index c15c62dd700..5a93d8e9c29 100644 --- a/mozilla/mailnews/imap/src/nsImapService.h +++ b/mozilla/mailnews/imap/src/nsImapService.h @@ -98,7 +98,7 @@ protected: nsIUrlListener * aUrlListener, nsCString & urlSpec, PRUnichar &hierarchyDelimiter); - nsresult GetImapConnectionAndLoadUrl(nsIEventQueue* aClientEventQueue, + nsresult GetImapConnectionAndLoadUrl(nsIEventTarget* aClientEventTarget, nsIImapUrl* aImapUrl, nsISupports* aConsumer, nsIURI** aURL); @@ -114,20 +114,20 @@ protected: const char *messageIdentifierList, const char *mimePart); - nsresult FolderCommand(nsIEventQueue * clientEventQueue, + nsresult FolderCommand(nsIEventTarget * clientEventTarget, nsIMsgFolder * imapMailFolder, nsIUrlListener * urlListener, const char *command, nsImapAction imapAction, nsIURI ** url); - nsresult ChangeFolderSubscription(nsIEventQueue* eventQueue, + nsresult ChangeFolderSubscription(nsIEventTarget* eventTarget, nsIMsgFolder* folder, const PRUnichar* folderName, const char *command, nsIUrlListener* urlListener, nsIURI** url); - nsresult DiddleFlags(nsIEventQueue * aClientEventQueue, + nsresult DiddleFlags(nsIEventTarget * aClientEventTarget, nsIMsgFolder * aImapMailFolder, nsIUrlListener * aUrlListener, nsIURI ** aURL, diff --git a/mozilla/mailnews/imap/src/nsImapUndoTxn.cpp b/mozilla/mailnews/imap/src/nsImapUndoTxn.cpp index 42ea58a9b58..fa06b483a6e 100644 --- a/mozilla/mailnews/imap/src/nsImapUndoTxn.cpp +++ b/mozilla/mailnews/imap/src/nsImapUndoTxn.cpp @@ -54,11 +54,11 @@ nsImapMoveCopyMsgTxn::nsImapMoveCopyMsgTxn( nsIMsgFolder* srcFolder, nsMsgKeyArray* srcKeyArray, const char* srcMsgIdString, nsIMsgFolder* dstFolder, PRBool idsAreUids, PRBool isMove, - nsIEventQueue* eventQueue, nsIUrlListener* urlListener) : + nsIEventTarget* eventTarget, nsIUrlListener* urlListener) : m_idsAreUids(PR_FALSE), m_isMove(PR_FALSE), m_srcIsPop3(PR_FALSE) { Init(srcFolder, srcKeyArray, srcMsgIdString, dstFolder, idsAreUids, - isMove, eventQueue, urlListener); + isMove, eventTarget, urlListener); } nsresult @@ -66,7 +66,7 @@ nsImapMoveCopyMsgTxn::Init( nsIMsgFolder* srcFolder, nsMsgKeyArray* srcKeyArray, const char* srcMsgIdString, nsIMsgFolder* dstFolder, PRBool idsAreUids, PRBool isMove, - nsIEventQueue* eventQueue, nsIUrlListener* urlListener) + nsIEventTarget* eventTarget, nsIUrlListener* urlListener) { nsresult rv; NS_NewISupportsArray(getter_AddRefs(m_srcHdrs)); @@ -75,7 +75,7 @@ nsImapMoveCopyMsgTxn::Init( m_isMove = isMove; m_srcFolder = do_GetWeakReference(srcFolder); m_dstFolder = do_GetWeakReference(dstFolder); - m_eventQueue = do_QueryInterface(eventQueue, &rv); + m_eventTarget = eventTarget; if (urlListener) m_urlListener = do_QueryInterface(urlListener, &rv); m_srcKeyArray.CopyArray(srcKeyArray); @@ -179,7 +179,7 @@ nsImapMoveCopyMsgTxn::UndoTransaction(void) return rv; // ** make sure we are in the selected state; use lite select // folder so we won't hit performance hard - rv = imapService->LiteSelectFolder(m_eventQueue, srcFolder, + rv = imapService->LiteSelectFolder(m_eventTarget, srcFolder, srcListener, nsnull); if (NS_FAILED(rv)) return rv; @@ -198,11 +198,11 @@ nsImapMoveCopyMsgTxn::UndoTransaction(void) if (deletedMsgs) rv = imapService->SubtractMessageFlags( - m_eventQueue, srcFolder, srcListener, nsnull, + m_eventTarget, srcFolder, srcListener, nsnull, m_srcMsgIdString.get(), kImapMsgDeletedFlag, m_idsAreUids); else - rv = imapService->AddMessageFlags(m_eventQueue, srcFolder, + rv = imapService->AddMessageFlags(m_eventTarget, srcFolder, srcListener, nsnull, m_srcMsgIdString.get(), kImapMsgDeletedFlag, @@ -211,7 +211,7 @@ nsImapMoveCopyMsgTxn::UndoTransaction(void) return rv; if (deleteModel != nsMsgImapDeleteModels::IMAPDelete) - rv = imapService->GetHeaders(m_eventQueue, srcFolder, + rv = imapService->GetHeaders(m_eventTarget, srcFolder, srcListener, nsnull, m_srcMsgIdString.get(), PR_TRUE); @@ -228,10 +228,10 @@ nsImapMoveCopyMsgTxn::UndoTransaction(void) if (NS_FAILED(rv)) return rv; // ** make sure we are in the selected state; use lite select folder // so we won't potentially download a bunch of headers. - rv = imapService->LiteSelectFolder(m_eventQueue, dstFolder, + rv = imapService->LiteSelectFolder(m_eventTarget, dstFolder, dstListener, nsnull); if (NS_FAILED(rv)) return rv; - rv = imapService->AddMessageFlags(m_eventQueue, dstFolder, + rv = imapService->AddMessageFlags(m_eventTarget, dstFolder, dstListener, nsnull, m_dstMsgIdString.get(), kImapMsgDeletedFlag, @@ -279,17 +279,17 @@ nsImapMoveCopyMsgTxn::RedoTransaction(void) // ** make sire we are in the selected state; use lite select // folder so we won't hit preformace hard - rv = imapService->LiteSelectFolder(m_eventQueue, srcFolder, + rv = imapService->LiteSelectFolder(m_eventTarget, srcFolder, srcListener, nsnull); if (NS_FAILED(rv)) return rv; if (deletedMsgs) - rv = imapService->SubtractMessageFlags(m_eventQueue, srcFolder, + rv = imapService->SubtractMessageFlags(m_eventTarget, srcFolder, srcListener, nsnull, m_srcMsgIdString.get(), kImapMsgDeletedFlag, m_idsAreUids); else - rv = imapService->AddMessageFlags(m_eventQueue, srcFolder, + rv = imapService->AddMessageFlags(m_eventTarget, srcFolder, srcListener, nsnull, m_srcMsgIdString.get(), kImapMsgDeletedFlag, m_idsAreUids); } @@ -306,11 +306,11 @@ nsImapMoveCopyMsgTxn::RedoTransaction(void) return rv; // ** make sure we are in the selected state; use lite select // folder so we won't hit preformace hard - rv = imapService->LiteSelectFolder(m_eventQueue, dstFolder, + rv = imapService->LiteSelectFolder(m_eventTarget, dstFolder, dstListener, nsnull); if (NS_FAILED(rv)) return rv; - rv = imapService->SubtractMessageFlags(m_eventQueue, dstFolder, + rv = imapService->SubtractMessageFlags(m_eventTarget, dstFolder, dstListener, nsnull, m_dstMsgIdString.get(), kImapMsgDeletedFlag, @@ -320,7 +320,7 @@ nsImapMoveCopyMsgTxn::RedoTransaction(void) nsMsgImapDeleteModel deleteModel; rv = GetImapDeleteModel(dstFolder, &deleteModel); if (NS_FAILED(rv) || deleteModel == nsMsgImapDeleteModels::MoveToTrash) - rv = imapService->GetHeaders(m_eventQueue, dstFolder, + rv = imapService->GetHeaders(m_eventTarget, dstFolder, dstListener, nsnull, m_dstMsgIdString.get(), PR_TRUE); @@ -451,10 +451,10 @@ nsresult nsImapMoveCopyMsgTxn::GetImapDeleteModel(nsIMsgFolder *aFolder, nsMsgIm nsImapOfflineTxn::nsImapOfflineTxn(nsIMsgFolder* srcFolder, nsMsgKeyArray* srcKeyArray, nsIMsgFolder* dstFolder, PRBool isMove, nsOfflineImapOperationType opType, nsIMsgDBHdr *srcHdr, - nsIEventQueue* eventQueue, nsIUrlListener* urlListener) + nsIEventTarget* eventTarget, nsIUrlListener* urlListener) { Init(srcFolder, srcKeyArray, nsnull, dstFolder, PR_TRUE, - isMove, eventQueue, urlListener); + isMove, eventTarget, urlListener); m_opType = opType; m_flags = 0; diff --git a/mozilla/mailnews/imap/src/nsImapUndoTxn.h b/mozilla/mailnews/imap/src/nsImapUndoTxn.h index f55b2435318..a80d73b3cfd 100644 --- a/mozilla/mailnews/imap/src/nsImapUndoTxn.h +++ b/mozilla/mailnews/imap/src/nsImapUndoTxn.h @@ -43,7 +43,7 @@ #include "nsIImapService.h" #include "nsIImapIncomingServer.h" #include "nsIUrlListener.h" -#include "nsIEventQueue.h" +#include "nsIEventTarget.h" #include "nsMsgTxn.h" #include "nsMsgKeyArray.h" #include "nsIMsgOfflineImapOperation.h" @@ -64,7 +64,7 @@ public: nsImapMoveCopyMsgTxn(nsIMsgFolder* srcFolder, nsMsgKeyArray* srcKeyArray, const char* srcMsgIdString, nsIMsgFolder* dstFolder, PRBool idsAreUids, PRBool isMove, - nsIEventQueue *eventQueue, + nsIEventTarget *eventTarget, nsIUrlListener *urlListener); virtual ~nsImapMoveCopyMsgTxn(); @@ -82,7 +82,7 @@ public: nsresult Init(nsIMsgFolder* srcFolder, nsMsgKeyArray* srcKeyArray, const char* srcMsgIdString, nsIMsgFolder* dstFolder, PRBool idsAreUids, PRBool isMove, - nsIEventQueue *eventQueue, + nsIEventTarget *eventTarget, nsIUrlListener *urlListener); protected: @@ -94,7 +94,7 @@ protected: nsCString m_srcMsgIdString; nsWeakPtr m_dstFolder; nsCString m_dstMsgIdString; - nsCOMPtr m_eventQueue; + nsCOMPtr m_eventTarget; nsCOMPtr m_urlListener; PRBool m_idsAreUids; PRBool m_isMove; @@ -114,7 +114,7 @@ public: PRBool isMove, nsOfflineImapOperationType opType, nsIMsgDBHdr *srcHdr, - nsIEventQueue *eventQueue, + nsIEventTarget *eventTarget, nsIUrlListener *urlListener); virtual ~nsImapOfflineTxn(); diff --git a/mozilla/mailnews/imap/src/nsImapUrl.cpp b/mozilla/mailnews/imap/src/nsImapUrl.cpp index 7243040204b..7fe006ae3f7 100644 --- a/mozilla/mailnews/imap/src/nsImapUrl.cpp +++ b/mozilla/mailnews/imap/src/nsImapUrl.cpp @@ -39,8 +39,6 @@ #include "msgCore.h" // precompiled header... #include "nsMsgImapCID.h" -#include "nsIEventQueueService.h" - #include "nsIURL.h" #include "nsImapUrl.h" #include "nsIMsgMailSession.h" diff --git a/mozilla/mailnews/import/comm4x/src/nsComm4xMailImport.cpp b/mozilla/mailnews/import/comm4x/src/nsComm4xMailImport.cpp index 17507e0aa49..95759127efa 100644 --- a/mozilla/mailnews/import/comm4x/src/nsComm4xMailImport.cpp +++ b/mozilla/mailnews/import/comm4x/src/nsComm4xMailImport.cpp @@ -74,8 +74,6 @@ #include "nsIProxyObjectManager.h" #include "nsProxiedService.h" -static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); - #define COMM4XMAIL_MSGS_URL "chrome://messenger/locale/comm4xMailImportMsgs.properties" PRLogModuleInfo *COMM4XLOGMODULE = nsnull; @@ -172,7 +170,7 @@ NS_IMETHODIMP nsComm4xMailImport::GetImportInterface(const char *pImportType, ns NS_ENSURE_SUCCESS(rv,rv); nameString->SetData(name); pGeneric->SetData("name", nameString); - rv = pGeneric->QueryInterface(kISupportsIID, (void **)ppInterface); + rv = CallQueryInterface(pGeneric, ppInterface); } } } @@ -196,13 +194,14 @@ nsresult ImportComm4xMailImpl::Initialize() nsCOMPtr pBundle; pBundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv); - if (NS_SUCCEEDED(rv) && (pBundleService)) + if (NS_SUCCEEDED(rv) && (pBundleService)) { pBundleService->CreateBundle(COMM4XMAIL_MSGS_URL, getter_AddRefs(pBundle)); - nsCOMPtr proxyMgr(do_GetService(NS_XPCOMPROXY_CONTRACTID, &rv)); - if (NS_SUCCEEDED(rv)) { - rv = proxyMgr->GetProxyForObject( NS_UI_THREAD_EVENTQ, NS_GET_IID(nsIStringBundle), - pBundle, PROXY_SYNC | PROXY_ALWAYS, getter_AddRefs(m_pBundleProxy)); + rv = NS_GetProxyForObject( NS_PROXY_TO_MAIN_THREAD, + NS_GET_IID(nsIStringBundle), + pBundle, + NS_PROXY_SYNC | NS_PROXY_ALWAYS, + getter_AddRefs(m_pBundleProxy)); } return rv; } diff --git a/mozilla/mailnews/import/src/nsImportAddressBooks.cpp b/mozilla/mailnews/import/src/nsImportAddressBooks.cpp index 56f045330ed..4fae34ac0f3 100644 --- a/mozilla/mailnews/import/src/nsImportAddressBooks.cpp +++ b/mozilla/mailnews/import/src/nsImportAddressBooks.cpp @@ -747,7 +747,9 @@ nsIAddrDatabase *GetAddressBookFromUri( const char *pUri) nsIAddrDatabase * pDatabase = nsnull; if (pUri) { nsresult rv = NS_OK; - NS_WITH_PROXIED_SERVICE(nsIAddressBook, addressBook, NS_ADDRESSBOOK_CONTRACTID, NS_UI_THREAD_EVENTQ, &rv); + NS_WITH_PROXIED_SERVICE(nsIAddressBook, addressBook, + NS_ADDRESSBOOK_CONTRACTID, + NS_PROXY_TO_MAIN_THREAD, &rv); if (addressBook) rv = addressBook->GetAbDatabaseFromURI(pUri, &pDatabase); } @@ -767,19 +769,14 @@ nsIAddrDatabase *GetAddressBook( const PRUnichar *name, PRBool makeNew) IMPORT_LOG0( "In GetAddressBook\n"); - nsCOMPtr proxyMgr = - do_GetService(kProxyObjectManagerCID, &rv); - if (NS_FAILED( rv)) { - IMPORT_LOG0( "*** Error: Unable to get proxy manager\n"); - return( nsnull); - } - nsIAddrDatabase * pDatabase = nsnull; /* Get the profile directory */ nsCOMPtr dbPath; - NS_WITH_PROXIED_SERVICE(nsIAddrBookSession, abSession, NS_ADDRBOOKSESSION_CONTRACTID, NS_UI_THREAD_EVENTQ, &rv); + NS_WITH_PROXIED_SERVICE(nsIAddrBookSession, abSession, + NS_ADDRBOOKSESSION_CONTRACTID, + NS_PROXY_TO_MAIN_THREAD, &rv); if (NS_SUCCEEDED(rv)) rv = abSession->GetUserProfileDirectory(getter_AddRefs(dbPath)); @@ -793,7 +790,9 @@ nsIAddrDatabase *GetAddressBook( const PRUnichar *name, PRBool makeNew) if (NS_SUCCEEDED(rv)) { IMPORT_LOG0( "Getting the address database factory\n"); - NS_WITH_PROXIED_SERVICE(nsIAddrDatabase, addrDBFactory, NS_ADDRDATABASE_CONTRACTID, NS_UI_THREAD_EVENTQ, &rv); + NS_WITH_PROXIED_SERVICE(nsIAddrDatabase, addrDBFactory, + NS_ADDRDATABASE_CONTRACTID, + NS_PROXY_TO_MAIN_THREAD, &rv); if (NS_SUCCEEDED(rv) && addrDBFactory) { IMPORT_LOG0( "Opening the new address book\n"); rv = addrDBFactory->Open( dbPath, PR_TRUE, PR_TRUE, &pDatabase); @@ -811,7 +810,8 @@ nsIAddrDatabase *GetAddressBook( const PRUnichar *name, PRBool makeNew) // This is major bogosity again! Why doesn't the address book // just handle this properly for me? Uggggg... - NS_WITH_PROXIED_SERVICE(nsIRDFService, rdfService, kRDFServiceCID, NS_UI_THREAD_EVENTQ, &rv); + NS_WITH_PROXIED_SERVICE(nsIRDFService, rdfService, kRDFServiceCID, + NS_PROXY_TO_MAIN_THREAD, &rv); if (NS_SUCCEEDED(rv)) { nsCOMPtr parentResource; rv = rdfService->GetResource(NS_LITERAL_CSTRING(kAllDirectoryRoot), @@ -828,8 +828,11 @@ nsIAddrDatabase *GetAddressBook( const PRUnichar *name, PRBool makeNew) * a thread other than the UI thread. * */ - rv = proxyMgr->GetProxyForObject( NS_UI_THREAD_EVENTQ, NS_GET_IID( nsIAbDirectory), - parentResource, PROXY_SYNC | PROXY_ALWAYS, getter_AddRefs( parentDir)); + rv = NS_GetProxyForObject( NS_PROXY_TO_MAIN_THREAD, + NS_GET_IID( nsIAbDirectory), + parentResource, + NS_PROXY_SYNC | NS_PROXY_ALWAYS, + getter_AddRefs( parentDir)); if (parentDir) { nsCAutoString URI("moz-abmdbdirectory://"); @@ -907,10 +910,10 @@ PR_STATIC_CALLBACK( void) ImportAddressThread( void *stuff) } nsCOMPtr proxyAddrDatabase; - rv = NS_GetProxyForObject(NS_UI_THREAD_EVENTQ, + rv = NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD, NS_GET_IID(nsIAddrDatabase), pDestDB, - PROXY_SYNC | PROXY_ALWAYS, + NS_PROXY_SYNC | NS_PROXY_ALWAYS, getter_AddRefs(proxyAddrDatabase)); if (NS_FAILED(rv)) return; diff --git a/mozilla/mailnews/import/src/nsImportMail.cpp b/mozilla/mailnews/import/src/nsImportMail.cpp index 463d88e0f2b..7ab3dfb2f64 100644 --- a/mozilla/mailnews/import/src/nsImportMail.cpp +++ b/mozilla/mailnews/import/src/nsImportMail.cpp @@ -769,24 +769,17 @@ ImportMailThread( void *stuff) nsCOMPtr bundle( dont_AddRef( nsImportStringBundle::GetStringBundleProxy())); // Initialize the curFolder proxy object - nsCOMPtr proxyMgr = - do_GetService(kProxyObjectManagerCID, &rv); - if (NS_SUCCEEDED(rv)) { - rv = proxyMgr->GetProxyForObject( NS_UI_THREAD_EVENTQ, NS_GET_IID(nsIMsgFolder), - curFolder, PROXY_SYNC | PROXY_ALWAYS, getter_AddRefs( curProxy)); - - if (NS_SUCCEEDED(rv)) - // GetSubfolders() will initialize folders if they are not already initialized. - curProxy->GetSubFolders(getter_AddRefs(enumerator)); - else - IMPORT_LOG1( "*** ImportMailThread: Can't get the destination root folder proxy. rv=(0x%lx)", (long) rv); + rv = NS_GetProxyForObject( NS_PROXY_TO_MAIN_THREAD, + NS_GET_IID(nsIMsgFolder), + curFolder, + NS_PROXY_SYNC | NS_PROXY_ALWAYS, + getter_AddRefs( curProxy)); + if (NS_SUCCEEDED(rv)) { + // GetSubfolders() will initialize folders if they are not already initialized. + curProxy->GetSubFolders(getter_AddRefs(enumerator)); + } else { + IMPORT_LOG1( "*** ImportMailThread: Can't get the destination root folder proxy. rv=(0x%lx)", (long) rv); } - else { - IMPORT_LOG0("*** ImportMailThread: Unable to obtain proxy service to do the import."); - nsImportStringBundle::GetStringByID( IMPORT_ERROR_MB_NOPROXY, error, bundle); - pData->abort = PR_TRUE; - } - IMPORT_LOG1("ImportMailThread: Total number of folders to import = %d.", count); @@ -817,8 +810,11 @@ ImportMailThread( void *stuff) break; } - rv = proxyMgr->GetProxyForObject( NS_UI_THREAD_EVENTQ, NS_GET_IID(nsIMsgFolder), - subFolder, PROXY_SYNC | PROXY_ALWAYS, getter_AddRefs( curProxy)); + rv = NS_GetProxyForObject( NS_PROXY_TO_MAIN_THREAD, + NS_GET_IID(nsIMsgFolder), + subFolder, + NS_PROXY_SYNC | NS_PROXY_ALWAYS, + getter_AddRefs( curProxy)); if (NS_FAILED( rv)) { IMPORT_LOG1("*** ImportMailThread: Failed to get the proxy interface for child folder '%s'.", NS_ConvertUTF16toUTF8(lastName).get()); nsImportStringBundle::GetStringByID( IMPORT_ERROR_MB_NOPROXY, error, bundle); @@ -841,8 +837,11 @@ ImportMailThread( void *stuff) break; } - rv = proxyMgr->GetProxyForObject( NS_UI_THREAD_EVENTQ, NS_GET_IID(nsIMsgFolder), - parFolder, PROXY_SYNC | PROXY_ALWAYS, getter_AddRefs( curProxy)); + rv = NS_GetProxyForObject( NS_PROXY_TO_MAIN_THREAD, + NS_GET_IID(nsIMsgFolder), + parFolder, + NS_PROXY_SYNC | NS_PROXY_ALWAYS, + getter_AddRefs( curProxy)); depth--; } if (NS_FAILED( rv)) { diff --git a/mozilla/mailnews/import/src/nsImportStringBundle.cpp b/mozilla/mailnews/import/src/nsImportStringBundle.cpp index 0ddc283d382..c9af0e406b9 100644 --- a/mozilla/mailnews/import/src/nsImportStringBundle.cpp +++ b/mozilla/mailnews/import/src/nsImportStringBundle.cpp @@ -76,15 +76,12 @@ nsIStringBundle *nsImportStringBundle::GetStringBundleProxy( void) return( nsnull); nsIStringBundle *strProxy = nsnull; - nsresult rv; // create a proxy object if we aren't on the same thread? - nsCOMPtr proxyMgr = - do_GetService(kProxyObjectManagerCID, &rv); - if (NS_SUCCEEDED(rv)) { - rv = proxyMgr->GetProxyForObject( NS_UI_THREAD_EVENTQ, NS_GET_IID(nsIStringBundle), - m_pBundle, PROXY_SYNC | PROXY_ALWAYS, (void **) &strProxy); - } - + NS_GetProxyForObject( NS_PROXY_TO_MAIN_THREAD, + NS_GET_IID(nsIStringBundle), + m_pBundle, + NS_PROXY_SYNC | NS_PROXY_ALWAYS, + (void **) &strProxy); return( strProxy); } diff --git a/mozilla/mailnews/import/text/src/nsTextStringBundle.cpp b/mozilla/mailnews/import/text/src/nsTextStringBundle.cpp index 2bdeec051ce..b27c2c2eb0a 100644 --- a/mozilla/mailnews/import/text/src/nsTextStringBundle.cpp +++ b/mozilla/mailnews/import/text/src/nsTextStringBundle.cpp @@ -79,14 +79,12 @@ nsIStringBundle *nsTextStringBundle::GetStringBundleProxy( void) return( nsnull); nsIStringBundle *strProxy = nsnull; - nsresult rv; // create a proxy object if we aren't on the same thread? - nsCOMPtr proxyMgr = - do_GetService(kProxyObjectManagerCID, &rv); - if (NS_SUCCEEDED(rv)) { - rv = proxyMgr->GetProxyForObject( NS_UI_THREAD_EVENTQ, NS_GET_IID(nsIStringBundle), - m_pBundle, PROXY_SYNC | PROXY_ALWAYS, (void **) &strProxy); - } + NS_GetProxyForObject( NS_PROXY_TO_MAIN_THREAD, + NS_GET_IID(nsIStringBundle), + m_pBundle, + NS_PROXY_SYNC | NS_PROXY_ALWAYS, + (void **) &strProxy); return( strProxy); } diff --git a/mozilla/mailnews/local/src/nsLocalUndoTxn.cpp b/mozilla/mailnews/local/src/nsLocalUndoTxn.cpp index 0928e8d423e..610b0402ca1 100644 --- a/mozilla/mailnews/local/src/nsLocalUndoTxn.cpp +++ b/mozilla/mailnews/local/src/nsLocalUndoTxn.cpp @@ -44,10 +44,8 @@ #include "nsIImapService.h" #include "nsIUrlListener.h" #include "nsIMsgLocalMailFolder.h" -#include "nsIEventQueueService.h" #include "nsIMsgMailSession.h" - -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); +#include "nsThreadUtils.h" nsLocalMoveCopyMsgTxn::nsLocalMoveCopyMsgTxn() : m_isMove(PR_FALSE), m_srcIsImap4(PR_FALSE) @@ -190,36 +188,29 @@ nsLocalMoveCopyMsgTxn::UndoImapDeleteFlag(nsIMsgFolder* folder, msgIds.Append(','); msgIds.AppendInt((PRInt32) keyArray.GetAt(i)); } - nsCOMPtr eventQueue; - nsCOMPtr pEventQService = - do_GetService(kEventQueueServiceCID, &rv); - if (NS_SUCCEEDED(rv) && pEventQService) + nsCOMPtr thread = do_GetCurrentThread(); + if (thread) { - pEventQService->GetThreadEventQueue(NS_CURRENT_THREAD, - getter_AddRefs(eventQueue)); - if (eventQueue) - { - // This is to make sure that we are in the selected state - // when executing the imap url; we don't want to load the - // folder so use lite select to do the trick - rv = imapService->LiteSelectFolder(eventQueue, folder, - urlListener, nsnull); - if (!deleteFlag) - rv =imapService->AddMessageFlags(eventQueue, folder, - urlListener, nsnull, - msgIds.get(), - kImapMsgDeletedFlag, - PR_TRUE); - else - rv = imapService->SubtractMessageFlags(eventQueue, - folder, - urlListener, nsnull, - msgIds.get(), - kImapMsgDeletedFlag, - PR_TRUE); - if (NS_SUCCEEDED(rv) && m_msgWindow) - folder->UpdateFolder(m_msgWindow); - } + // This is to make sure that we are in the selected state + // when executing the imap url; we don't want to load the + // folder so use lite select to do the trick + rv = imapService->LiteSelectFolder(thread, folder, + urlListener, nsnull); + if (!deleteFlag) + rv =imapService->AddMessageFlags(thread, folder, + urlListener, nsnull, + msgIds.get(), + kImapMsgDeletedFlag, + PR_TRUE); + else + rv = imapService->SubtractMessageFlags(thread, + folder, + urlListener, nsnull, + msgIds.get(), + kImapMsgDeletedFlag, + PR_TRUE); + if (NS_SUCCEEDED(rv) && m_msgWindow) + folder->UpdateFolder(m_msgWindow); } } rv = NS_OK; // always return NS_OK to indicate that the src is imap diff --git a/mozilla/modules/libpr0n/src/imgLoader.cpp b/mozilla/modules/libpr0n/src/imgLoader.cpp index 9136997e632..24930a8fb7f 100644 --- a/mozilla/modules/libpr0n/src/imgLoader.cpp +++ b/mozilla/modules/libpr0n/src/imgLoader.cpp @@ -46,6 +46,7 @@ #include "nsICachingChannel.h" #include "nsIProxyObjectManager.h" #include "nsIServiceManager.h" +#include "nsThreadUtils.h" #include "nsXPIDLString.h" #include "nsCRT.h" @@ -359,23 +360,9 @@ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI, // Get the current EventQueue... This is used as a cacheId to prevent // sharing requests which are being loaded across multiple event queues... // - nsCOMPtr eventQService; - nsCOMPtr activeQ; + nsCOMPtr thread = do_GetCurrentThread(); - eventQService = do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv); - if (NS_FAILED(rv)) { - NS_IF_RELEASE(request); - return rv; - } - - rv = eventQService->ResolveEventQueue(NS_CURRENT_EVENTQ, - getter_AddRefs(activeQ)); - if (NS_FAILED(rv)) { - NS_IF_RELEASE(request); - return rv; - } - - void *cacheId = activeQ.get(); + void *cacheId = thread.get(); if (request && !request->IsReusable(cacheId)) { // // The current request is still being loaded and lives on a different @@ -627,19 +614,10 @@ NS_IMETHODIMP imgLoader::LoadImageWithChannel(nsIChannel *channel, imgIDecoderOb *listener = nsnull; // give them back a null nsIStreamListener } else { // - // Get the current EventQueue... This is used as a cacheId to prevent - // sharing requests which are being loaded across multiple event queues... + // Get the current Thread... This is used as a cacheId to prevent sharing + // requests which are being loaded across multiple threads... // - nsCOMPtr eventQService; - nsCOMPtr activeQ; - - eventQService = do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv); - if (NS_FAILED(rv)) - return rv; - - rv = eventQService->ResolveEventQueue(NS_CURRENT_EVENTQ, getter_AddRefs(activeQ)); - if (NS_FAILED(rv)) - return rv; + nsCOMPtr thread = do_GetCurrentThread(); NS_NEWXPCOM(request, imgRequest); if (!request) return NS_ERROR_OUT_OF_MEMORY; @@ -648,7 +626,7 @@ NS_IMETHODIMP imgLoader::LoadImageWithChannel(nsIChannel *channel, imgIDecoderOb imgCache::Put(uri, request, getter_AddRefs(entry)); - request->Init(channel, entry, activeQ.get(), aCX); + request->Init(channel, entry, thread.get(), aCX); ProxyListener *pl = new ProxyListener(NS_STATIC_CAST(nsIStreamListener *, request)); if (!pl) { @@ -966,13 +944,7 @@ NS_IMETHODIMP imgCacheValidator::OnStartRequest(nsIRequest *aRequest, nsISupport mRequest->mValidator = nsnull; NS_RELEASE(mRequest); // assigns null - nsresult rv; - nsCOMPtr eventQService = do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr activeQ; - rv = eventQService->ResolveEventQueue(NS_CURRENT_EVENTQ, getter_AddRefs(activeQ)); - if (NS_FAILED(rv)) return rv; + nsCOMPtr thread = do_GetCurrentThread(); imgRequest *request; NS_NEWXPCOM(request, imgRequest); @@ -981,7 +953,7 @@ NS_IMETHODIMP imgCacheValidator::OnStartRequest(nsIRequest *aRequest, nsISupport imgCache::Put(uri, request, getter_AddRefs(entry)); - request->Init(channel, entry, activeQ.get(), mContext); + request->Init(channel, entry, thread.get(), mContext); ProxyListener *pl = new ProxyListener(NS_STATIC_CAST(nsIStreamListener *, request)); if (!pl) { diff --git a/mozilla/modules/oji/public/Makefile.in b/mozilla/modules/oji/public/Makefile.in index d8971cbfe7e..1b7f7e38661 100644 --- a/mozilla/modules/oji/public/Makefile.in +++ b/mozilla/modules/oji/public/Makefile.in @@ -64,7 +64,7 @@ EXPORTS = \ nsISymantecDebugger.h \ nsISecureEnv.h \ ProxyJNI.h \ - nsIThreadManager.h \ + nsIJVMThreadManager.h \ nsILiveConnectManager.h \ $(NULL) diff --git a/mozilla/modules/oji/public/nsjvm.h b/mozilla/modules/oji/public/nsjvm.h index 623bbaf4b39..768e9470e82 100644 --- a/mozilla/modules/oji/public/nsjvm.h +++ b/mozilla/modules/oji/public/nsjvm.h @@ -58,7 +58,7 @@ #include "nsISymantecDebugManager.h" #include "nsISymantecDebugger.h" #include "nsILiveconnect.h" -#include "nsIThreadManager.h" +#include "nsIJVMThreadManager.h" //////////////////////////////////////////////////////////////////////////////// diff --git a/mozilla/modules/oji/src/Makefile.in b/mozilla/modules/oji/src/Makefile.in index 02e69776902..73e099404e5 100644 --- a/mozilla/modules/oji/src/Makefile.in +++ b/mozilla/modules/oji/src/Makefile.in @@ -101,13 +101,14 @@ CPPSRCS += \ $(NULL) endif +DEFINES += -DNS_OJI_IMPL=1 + EXPORTS = \ jvmmgr.h \ nsJVMManager.h \ nsJVMPluginTagInfo.h \ $(NULL) - EXTRA_DSO_LDOPTS = \ $(LIBS_DIR) \ $(EXTRA_DSO_LIBS) \ diff --git a/mozilla/modules/oji/src/lcglue.h b/mozilla/modules/oji/src/lcglue.h index 1b8135bea44..3300e859608 100644 --- a/mozilla/modules/oji/src/lcglue.h +++ b/mozilla/modules/oji/src/lcglue.h @@ -43,7 +43,7 @@ #include "jsdbgapi.h" #include "nsError.h" -#include "nsIThreadManager.h" +#include "nsIJVMThreadManager.h" #include "nsISecurityContext.h" /** diff --git a/mozilla/modules/oji/src/nsJVMManager.cpp b/mozilla/modules/oji/src/nsJVMManager.cpp index 75926128e84..f53548df831 100644 --- a/mozilla/modules/oji/src/nsJVMManager.cpp +++ b/mozilla/modules/oji/src/nsJVMManager.cpp @@ -1,5 +1,6 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* vim:set ts=4 sw=4 sts=4 ci et: */ +/* * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -60,7 +61,8 @@ #include "ProxyJNI.h" #include "nsIPluginHost.h" #include "nsIServiceManager.h" -#include "nsIEventQueueService.h" +#include "nsIThreadManager.h" +#include "nsIThread.h" // All these interfaces are necessary just to get the damn // nsIWebBrowserChrome to send the "Starting Java" message to the status @@ -104,8 +106,6 @@ static NS_DEFINE_CID(kJVMManagerCID, NS_JVMMANAGER_CID); static NS_DEFINE_CID(kPluginManagerCID, NS_PLUGINMANAGER_CID); -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); - // FIXME -- need prototypes for these functions!!! XXX #ifdef XP_MAC extern "C" { @@ -117,7 +117,7 @@ void stopAsyncCursors(void); static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); static NS_DEFINE_IID(kIJVMManagerIID, NS_IJVMMANAGER_IID); -static NS_DEFINE_IID(kIThreadManagerIID, NS_ITHREADMANAGER_IID); +static NS_DEFINE_IID(kIJVMThreadManagerIID, NS_IJVMTHREADMANAGER_IID); static NS_DEFINE_IID(kILiveConnectManagerIID, NS_ILIVECONNECTMANAGER_IID); static NS_DEFINE_IID(kIJVMPluginIID, NS_IJVMPLUGIN_IID); @@ -291,57 +291,22 @@ nsJVMManager::CreateThread(PRThread **outThread, nsIRunnable* runnable) return (thread != NULL ? NS_OK : NS_ERROR_FAILURE); } -struct JVMRunnableEvent : PLEvent { - JVMRunnableEvent(nsIRunnable* runnable); - ~JVMRunnableEvent(); - - nsIRunnable* mRunnable; -}; - -static void PR_CALLBACK -handleRunnableEvent(JVMRunnableEvent* aEvent) -{ - aEvent->mRunnable->Run(); -} - -static void PR_CALLBACK -destroyRunnableEvent(JVMRunnableEvent* aEvent) -{ - delete aEvent; -} - -JVMRunnableEvent::JVMRunnableEvent(nsIRunnable* runnable) - : mRunnable(runnable) -{ - NS_ADDREF(mRunnable); - PL_InitEvent(this, nsnull, PLHandleEventProc(handleRunnableEvent), PLDestroyEventProc(&destroyRunnableEvent)); -} - -JVMRunnableEvent::~JVMRunnableEvent() -{ - NS_RELEASE(mRunnable); -} - NS_METHOD -nsJVMManager::PostEvent(PRThread* thread, nsIRunnable* runnable, PRBool async) +nsJVMManager::PostEvent(PRThread* prthread, nsIRunnable* runnable, PRBool async) { nsresult rv; - nsCOMPtr eventService = - do_GetService(kEventQueueServiceCID, &rv); + nsCOMPtr mgr = + do_GetService(NS_THREADMANAGER_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; - nsCOMPtr eventQueue = NULL; - rv = eventService->GetThreadEventQueue(thread, getter_AddRefs(eventQueue)); + nsCOMPtr thread; + rv = mgr->GetThreadFromPRThread(prthread, getter_AddRefs(thread)); if (NS_FAILED(rv)) return rv; - JVMRunnableEvent* runnableEvent = new JVMRunnableEvent(runnable); - if (runnableEvent == nsnull) - return NS_ERROR_OUT_OF_MEMORY; - if (async) - eventQueue->PostEvent(runnableEvent); - else - eventQueue->PostSynchronousEvent(runnableEvent, nsnull); - return rv; + NS_ENSURE_STATE(thread); + + return thread->Dispatch(runnable, async ? NS_DISPATCH_NORMAL + : NS_DISPATCH_SYNC); } nsJVMManager::nsJVMManager(nsISupports* outer) @@ -386,8 +351,8 @@ nsJVMManager::AggregatedQueryInterface(const nsIID& aIID, void** aInstancePtr) NS_ADDREF_THIS(); return NS_OK; } - if (aIID.Equals(kIThreadManagerIID)) { - *aInstancePtr = (void*) NS_STATIC_CAST(nsIThreadManager*, this); + if (aIID.Equals(kIJVMThreadManagerIID)) { + *aInstancePtr = (void*) NS_STATIC_CAST(nsIJVMThreadManager*, this); NS_ADDREF_THIS(); return NS_OK; } diff --git a/mozilla/modules/oji/src/nsJVMManager.h b/mozilla/modules/oji/src/nsJVMManager.h index 56619840399..679cbed5bbe 100644 --- a/mozilla/modules/oji/src/nsJVMManager.h +++ b/mozilla/modules/oji/src/nsJVMManager.h @@ -62,7 +62,8 @@ class nsIWebBrowserChrome; * nsIJVMManager is the more limited interface what the JVM plugin sees. ******************************************************************************/ -struct nsJVMManager : public nsIJVMManager, public nsIThreadManager, public nsILiveConnectManager, public nsIObserver { +struct nsJVMManager : public nsIJVMManager, public nsIJVMThreadManager, + public nsILiveConnectManager, public nsIObserver { public: NS_DECL_AGGREGATED @@ -71,7 +72,7 @@ public: NS_DECL_NSIOBSERVER - /* from nsIThreadManager: */ + /* from nsIJVMThreadManager: */ /** * Returns a unique identifier for the "current" system thread. diff --git a/mozilla/modules/plugin/base/src/nsPluginHostImpl.cpp b/mozilla/modules/plugin/base/src/nsPluginHostImpl.cpp index 7dbe5c43871..7d706334b06 100644 --- a/mozilla/modules/plugin/base/src/nsPluginHostImpl.cpp +++ b/mozilla/modules/plugin/base/src/nsPluginHostImpl.cpp @@ -122,9 +122,7 @@ #include "nsIDOMMimeType.h" #include "nsMimeTypes.h" #include "prprf.h" -#include "plevent.h" -#include "nsIEventQueueService.h" -#include "nsIEventQueue.h" +#include "nsThreadUtils.h" #include "nsIInputStreamTee.h" #include "nsIInterfaceInfoManager.h" #include "xptinfo.h" @@ -222,7 +220,6 @@ static NS_DEFINE_CID(kStreamConverterServiceCID, NS_STREAMCONVERTERSERVICE_CID); static const char kDirectoryServiceContractID[] = "@mozilla.org/file/directory_service;1"; // for the dialog static NS_DEFINE_IID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID); -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); static NS_DEFINE_CID(kCPluginManagerCID, NS_PLUGINMANAGER_CID); // needed for NS_TRY_SAFE_CALL //////////////////////////////////////////////////////////////////////// @@ -302,13 +299,14 @@ PRBool ReadSectionHeader(nsPluginManifestLineReader& reader, const char *token) // Little helper struct to asynchronously reframe any presentations (embedded) // or reload any documents (full-page), that contained plugins // which were shutdown as a result of a plugins.refresh(1) -struct nsPluginDocReframeEvent: public PLEvent { - nsPluginDocReframeEvent (nsISupportsArray* aDocs) { mDocs = aDocs; } - nsresult HandlePluginDocReframeEvent(); +class nsPluginDocReframeEvent: public nsRunnable { +public: + nsPluginDocReframeEvent(nsISupportsArray* aDocs) { mDocs = aDocs; } + NS_IMETHOD Run(); nsCOMPtr mDocs; }; -nsresult nsPluginDocReframeEvent::HandlePluginDocReframeEvent() { +NS_IMETHODIMP nsPluginDocReframeEvent::Run() { NS_ENSURE_TRUE(mDocs, NS_ERROR_FAILURE); PRUint32 c; @@ -345,25 +343,6 @@ nsresult nsPluginDocReframeEvent::HandlePluginDocReframeEvent() { return mDocs->Clear(); } - - - -//---------------------------------------------------------------------- -static void* PR_CALLBACK HandlePluginDocReframePLEvent(PLEvent* aEvent) -{ - nsPluginDocReframeEvent* event = - NS_STATIC_CAST(nsPluginDocReframeEvent*, aEvent); - event->HandlePluginDocReframeEvent(); - return nsnull; -} -static void PR_CALLBACK DestroyPluginDocReframePLEvent(PLEvent* aEvent) -{ - nsPluginDocReframeEvent* event = - NS_STATIC_CAST(nsPluginDocReframeEvent*, aEvent); - delete event; -} - - //////////////////////////////////////////////////////////////////////// nsActivePlugin::nsActivePlugin(nsPluginTag* aPluginTag, nsIPluginInstance* aInstance, @@ -976,55 +955,31 @@ void nsPluginTag::SetHost(nsPluginHostImpl * aHost) //---------------------------------------------------------------------- // helper struct for asynchronous handeling of plugin unloading -struct nsPluginUnloadEvent: public PLEvent { - nsPluginUnloadEvent (PRLibrary* aLibrary); +class nsPluginUnloadEvent : public nsRunnable { +public: + nsPluginUnloadEvent(PRLibrary* aLibrary) + : mLibrary(aLibrary) + {} - void HandleEvent() { - if (mLibrary) - NS_TRY_SAFE_CALL_VOID(PR_UnloadLibrary(mLibrary), nsnull, nsnull); // put our unload call in a saftey wrapper - else + NS_IMETHOD Run() { + if (mLibrary) { + // put our unload call in a saftey wrapper + NS_TRY_SAFE_CALL_VOID(PR_UnloadLibrary(mLibrary), nsnull, nsnull); + } else { NS_WARNING("missing library from nsPluginUnloadEvent"); + } + return NS_OK; } PRLibrary* mLibrary; }; -nsPluginUnloadEvent::nsPluginUnloadEvent (PRLibrary* aLibrary) -{ - mLibrary = aLibrary; -} -//---------------------------------------------------------------------- -// helper static callback functions for plugin unloading PLEvents -static void* PR_CALLBACK HandlePluginUnloadPLEvent(PLEvent* aEvent) -{ - nsPluginUnloadEvent *event = NS_STATIC_CAST(nsPluginUnloadEvent*, aEvent); - event->HandleEvent(); - return nsnull; -} -static void PR_CALLBACK DestroyPluginUnloadPLEvent(PLEvent* aEvent) -{ - nsPluginUnloadEvent *event = NS_STATIC_CAST(nsPluginUnloadEvent*, aEvent); - delete event; -} // unload plugin asynchronously if possible, otherwise just unload now -nsresult PostPluginUnloadEvent (PRLibrary* aLibrary) +nsresult PostPluginUnloadEvent(PRLibrary* aLibrary) { - nsCOMPtr eventService(do_GetService(kEventQueueServiceCID)); - if (eventService) { - nsCOMPtr eventQueue; - eventService->GetThreadEventQueue(PR_GetCurrentThread(), getter_AddRefs(eventQueue)); - if (eventQueue) { - nsPluginUnloadEvent * ev = new nsPluginUnloadEvent(aLibrary); - if (ev) { - - PL_InitEvent(ev, nsnull, ::HandlePluginUnloadPLEvent, ::DestroyPluginUnloadPLEvent); - if (NS_SUCCEEDED(eventQueue->PostEvent(ev))) - return NS_OK; - else NS_WARNING("failed to post event onto queue"); - - } else NS_WARNING("not able to create plugin unload event"); - } else NS_WARNING("couldn't get event queue"); - } else NS_WARNING("couldn't get event queue service"); + nsCOMPtr ev = new nsPluginUnloadEvent(aLibrary); + if (ev && NS_SUCCEEDED(NS_DispatchToCurrentThread(ev))) + return NS_OK; // failure case NS_TRY_SAFE_CALL_VOID(PR_UnloadLibrary(aLibrary), nsnull, nsnull); @@ -2753,19 +2708,9 @@ nsresult nsPluginHostImpl::ReloadPlugins(PRBool reloadPages) instsToReload && NS_SUCCEEDED(instsToReload->Count(&c)) && c > 0) { - nsCOMPtr eventService(do_GetService(kEventQueueServiceCID)); - if (eventService) { - nsCOMPtr eventQueue; - eventService->GetThreadEventQueue(PR_GetCurrentThread(), getter_AddRefs(eventQueue)); - if (eventQueue) { - nsPluginDocReframeEvent * ev = new nsPluginDocReframeEvent(instsToReload); - if (ev) { - PL_InitEvent(ev, nsnull, HandlePluginDocReframePLEvent, DestroyPluginDocReframePLEvent); - eventQueue->PostEvent(ev); - } - } - } - + nsCOMPtr ev = new nsPluginDocReframeEvent(instsToReload); + if (ev) + NS_DispatchToCurrentThread(ev); } PLUGIN_LOG(PLUGIN_LOG_NORMAL, diff --git a/mozilla/modules/plugin/base/src/nsPluginNativeWindowWin.cpp b/mozilla/modules/plugin/base/src/nsPluginNativeWindowWin.cpp index 5a8e888fd1a..1108cb3000c 100644 --- a/mozilla/modules/plugin/base/src/nsPluginNativeWindowWin.cpp +++ b/mozilla/modules/plugin/base/src/nsPluginNativeWindowWin.cpp @@ -50,37 +50,41 @@ #include "nsDebug.h" -#include "plevent.h" -#include "nsIEventQueueService.h" #include "nsGUIEvent.h" #include "nsIPluginInstancePeer.h" #include "nsIPluginInstanceInternal.h" #include "nsPluginSafety.h" #include "nsPluginNativeWindow.h" +#include "nsThreadUtils.h" +#include "nsAutoPtr.h" +#include "nsTWeakRef.h" -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); static NS_DEFINE_CID(kCPluginManagerCID, NS_PLUGINMANAGER_CID); // needed for NS_TRY_SAFE_CALL #define NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION "MozillaPluginWindowPropertyAssociation" +typedef nsTWeakRef PluginWindowWeakRef; + /** * PLEvent handling code */ -class PluginWindowEvent : public PLEvent { +class PluginWindowEvent : public nsRunnable { public: PluginWindowEvent(); - void Init(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + void Init(const PluginWindowWeakRef &ref, HWND hWnd, UINT msg, WPARAM wParam, + LPARAM lParam); void Clear(); HWND GetWnd() { return mWnd; }; UINT GetMsg() { return mMsg; }; WPARAM GetWParam() { return mWParam; }; LPARAM GetLParam() { return mLParam; }; - PRBool GetIsAlloced() { return mIsAlloced; }; - void SetIsAlloced(PRBool aIsAlloced) { mIsAlloced = aIsAlloced; }; - PRBool InUse() { return (mWnd!=NULL || mMsg!=0); }; + PRBool InUse() { return (mWnd!=NULL || mMsg!=0); }; + + NS_IMETHOD Run(); protected: + PluginWindowWeakRef mPluginWindowRef; HWND mWnd; UINT mMsg; WPARAM mWParam; @@ -101,10 +105,12 @@ void PluginWindowEvent::Clear() mLParam = 0; } -void PluginWindowEvent::Init(HWND aWnd, UINT aMsg, WPARAM aWParam, LPARAM aLParam) +void PluginWindowEvent::Init(const PluginWindowWeakRef &ref, HWND aWnd, + UINT aMsg, WPARAM aWParam, LPARAM aLParam) { NS_ASSERTION(aWnd!=NULL && aMsg!=0, "invalid plugin event value"); NS_ASSERTION(mWnd==NULL && mMsg==0 && mWParam==0 && mLParam==0,"event already in use"); + mPluginWindowRef = ref; mWnd = aWnd; mMsg = aMsg; mWParam = aWParam; @@ -139,14 +145,13 @@ public: // locals WNDPROC GetPrevWindowProc(); WNDPROC GetWindowProc(); - nsIEventQueueService *GetEventService(); PluginWindowEvent * GetPluginWindowEvent(HWND aWnd, UINT aMsg, WPARAM aWParam, LPARAM aLParam); private: WNDPROC mPrevWinProc; WNDPROC mPluginWinProc; - nsCOMPtr mEventService; - PluginWindowEvent mPluginWindowEvent; + PluginWindowWeakRef mWeakRef; + nsRefPtr mCachedPluginWindowEvent; public: nsPluginType mPluginType; @@ -164,43 +169,27 @@ static PRBool ProcessFlashMessageDelayed(nsPluginNativeWindowWin * aWin, return PR_FALSE; // no need to delay // do stuff - nsIEventQueueService *eventService = aWin->GetEventService(); - if (eventService) { - nsCOMPtr eventQueue; - eventService->GetThreadEventQueue(PR_GetCurrentThread(), - getter_AddRefs(eventQueue)); - if (eventQueue) { - PluginWindowEvent *pwe = aWin->GetPluginWindowEvent(hWnd, msg, wParam, lParam); - if (pwe) { - eventQueue->PostEvent(pwe); - return PR_TRUE; - } - } + nsCOMPtr pwe = aWin->GetPluginWindowEvent(hWnd, msg, wParam, lParam); + if (pwe) { + NS_DispatchToCurrentThread(pwe); + return PR_TRUE; } return PR_FALSE; } -PR_STATIC_CALLBACK(void*) -DelayedPopupsEnabledEvent_Handle(PLEvent *event) +class nsDelayedPopupsEnabledEvent : public nsRunnable { - nsIPluginInstanceInternal *instInternal = - (nsIPluginInstanceInternal *)event->owner; - - instInternal->PushPopupsEnabledState(PR_FALSE); - - return nsnull; -} - -PR_STATIC_CALLBACK(void) -DelayedPopupsEnabledEvent_Destroy(PLEvent *event) -{ - nsIPluginInstanceInternal *instInternal = - (nsIPluginInstanceInternal *)event->owner; - - NS_RELEASE(instInternal); - - delete event; -} +public: + nsDelayedPopupsEnabledEvent(nsIPluginInstanceInternal *inst) + : mInst(inst) + {} + NS_IMETHOD Run() { + mInst->PushPopupsEnabledState(PR_FALSE); + return NS_OK; + } +private: + nsCOMPtr mInst; +}; /** * New plugin window procedure @@ -375,26 +364,10 @@ static LRESULT CALLBACK PluginWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM // code will pop any popup state pushed by this plugin on // destruction. - nsIEventQueueService *eventService = win->GetEventService(); - if (eventService) { - nsCOMPtr eventQueue; - eventService->GetThreadEventQueue(PR_GetCurrentThread(), - getter_AddRefs(eventQueue)); - if (eventQueue) { - PLEvent *event = new PLEvent; - - if (event) { - nsIPluginInstanceInternal *eventInst = instInternal; - - // Make the event own the plugin instance. - NS_ADDREF(eventInst); - - PL_InitEvent(event, eventInst, DelayedPopupsEnabledEvent_Handle, - DelayedPopupsEnabledEvent_Destroy); - - eventQueue->PostEvent(event); - } - } + nsCOMPtr event = + new nsDelayedPopupsEnabledEvent(instInternal); + if (event) { + NS_DispatchToCurrentThread(event); } } @@ -415,21 +388,14 @@ nsPluginNativeWindowWin::nsPluginNativeWindowWin() : nsPluginNativeWindow() mPrevWinProc = NULL; mPluginWinProc = NULL; - mPluginWindowEvent.SetIsAlloced(PR_FALSE); mPluginType = nsPluginType_Unknown; } nsPluginNativeWindowWin::~nsPluginNativeWindowWin() { - // clear any pending events to avoid dangling pointers - nsCOMPtr eventService(do_GetService(kEventQueueServiceCID)); - if (eventService) { - nsCOMPtr eventQueue; - eventService->GetThreadEventQueue(PR_GetCurrentThread(), getter_AddRefs(eventQueue)); - if (eventQueue) { - eventQueue->RevokeEvents(this); - } - } + // clear weak reference to self to prevent any pending events from + // dereferencing this. + mWeakRef.forget(); } WNDPROC nsPluginNativeWindowWin::GetPrevWindowProc() @@ -442,61 +408,39 @@ WNDPROC nsPluginNativeWindowWin::GetWindowProc() return mPluginWinProc; } -PR_STATIC_CALLBACK(void*) -PluginWindowEvent_Handle(PLEvent* self) +NS_IMETHODIMP PluginWindowEvent::Run() { - if (!self) - return nsnull; + nsPluginNativeWindowWin *win = mPluginWindowRef.get(); + if (!win) + return NS_OK; - PluginWindowEvent *event = NS_STATIC_CAST(PluginWindowEvent*, self); - - HWND hWnd = event->GetWnd(); + HWND hWnd = GetWnd(); if (!hWnd) - return nsnull; + return NS_OK; - nsPluginNativeWindowWin * win = (nsPluginNativeWindowWin *)::GetProp(hWnd, NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION); - if (win) { - nsCOMPtr inst; - win->GetPluginInstance(inst); - NS_TRY_SAFE_CALL_VOID(::CallWindowProc(win->GetWindowProc(), - hWnd, - event->GetMsg(), - event->GetWParam(), - event->GetLParam()), - nsnull, inst); - } - - return nsnull; -} - -PR_STATIC_CALLBACK(void) -PluginWindowEvent_Destroy(PLEvent* self) -{ - if (!self) - return; - - PluginWindowEvent *event = NS_STATIC_CAST(PluginWindowEvent*, self); - if (event->GetIsAlloced()) { - delete event; - } - else - event->Clear(); -} - -nsIEventQueueService *nsPluginNativeWindowWin::GetEventService() -{ - if (!mEventService) { - mEventService = do_GetService(kEventQueueServiceCID); - } - - return mEventService; + nsCOMPtr inst; + win->GetPluginInstance(inst); + NS_TRY_SAFE_CALL_VOID(::CallWindowProc(win->GetWindowProc(), + hWnd, + GetMsg(), + GetWParam(), + GetLParam()), + nsnull, inst); + Clear(); + return NS_OK; } PluginWindowEvent* nsPluginNativeWindowWin::GetPluginWindowEvent(HWND aWnd, UINT aMsg, WPARAM aWParam, LPARAM aLParam) { + if (!mWeakRef) { + mWeakRef = this; + if (!mWeakRef) + return nsnull; + } + PluginWindowEvent *event; - if (mPluginWindowEvent.InUse()) { + if (!mCachedPluginWindowEvent || mCachedPluginWindowEvent->InUse()) { // We have the ability to alloc if needed in case in the future some plugin // should post multiple PostMessages. However, this could lead to many // alloc's per second which could become a performance issue. If/when this @@ -505,15 +449,13 @@ nsPluginNativeWindowWin::GetPluginWindowEvent(HWND aWnd, UINT aMsg, WPARAM aWPar event = new PluginWindowEvent(); if (!event) return nsnull; - - event->SetIsAlloced(PR_TRUE); } else { - event = &mPluginWindowEvent; + event = mCachedPluginWindowEvent; } + NS_ADDREF(event); - event->Init(aWnd, aMsg, aWParam, aLParam); - PL_InitEvent(event, (void *)this, &PluginWindowEvent_Handle, PluginWindowEvent_Destroy); + event->Init(mWeakRef, aWnd, aMsg, aWParam, aLParam); return event; } diff --git a/mozilla/netwerk/base/public/Makefile.in b/mozilla/netwerk/base/public/Makefile.in index acc6ce308ef..c12a32de0fa 100644 --- a/mozilla/netwerk/base/public/Makefile.in +++ b/mozilla/netwerk/base/public/Makefile.in @@ -91,7 +91,6 @@ XPIDLSRCS = \ nsIServerSocket.idl \ nsIResumableChannel.idl \ nsIRequestObserverProxy.idl \ - nsIStreamListenerProxy.idl \ nsIStreamListenerTee.idl \ nsISimpleStreamListener.idl \ nsIStreamTransportService.idl \ diff --git a/mozilla/netwerk/base/public/nsIAsyncStreamCopier.idl b/mozilla/netwerk/base/public/nsIAsyncStreamCopier.idl index cc8a7cdb401..febfcef8cc7 100644 --- a/mozilla/netwerk/base/public/nsIAsyncStreamCopier.idl +++ b/mozilla/netwerk/base/public/nsIAsyncStreamCopier.idl @@ -42,7 +42,7 @@ interface nsIOutputStream; interface nsIRequestObserver; interface nsIEventTarget; -[scriptable, uuid(eaa49141-c21c-4fe8-a79b-77860a3910aa)] +[scriptable, uuid(72e515de-a91e-4154-bb78-e5244cbaae74)] interface nsIAsyncStreamCopier : nsIRequest { /** @@ -67,12 +67,12 @@ interface nsIAsyncStreamCopier : nsIRequest * * NOTE: at least one of the streams must be buffered. */ - void init(in nsIInputStream aSource, - in nsIOutputStream aSink, - in nsIEventTarget aTarget, - in boolean aSourceBuffered, - in boolean aSinkBuffered, - in unsigned long aChunkSize); + void init(in nsIInputStream aSource, + in nsIOutputStream aSink, + in nsIEventTarget aTarget, + in boolean aSourceBuffered, + in boolean aSinkBuffered, + in unsigned long aChunkSize); /** * asyncCopy triggers the start of the copy. The observer will be notified diff --git a/mozilla/netwerk/base/public/nsIInputStreamPump.idl b/mozilla/netwerk/base/public/nsIInputStreamPump.idl index 026429ca720..5505e389821 100644 --- a/mozilla/netwerk/base/public/nsIInputStreamPump.idl +++ b/mozilla/netwerk/base/public/nsIInputStreamPump.idl @@ -46,7 +46,7 @@ interface nsIStreamListener; * * This interface provides a means to configure and use a input stream pump * instance. The input stream pump will asynchronously read from a input - * stream, and push data to a nsIStreamListener instance. It utilizes the + * stream, and push data to a nsIStreamListener instance. It utilizes the * current thread's nsIEventTarget in order to make reading from the stream * asynchronous. * diff --git a/mozilla/netwerk/base/public/nsIRequestObserverProxy.idl b/mozilla/netwerk/base/public/nsIRequestObserverProxy.idl index a819e1c830c..81033885630 100644 --- a/mozilla/netwerk/base/public/nsIRequestObserverProxy.idl +++ b/mozilla/netwerk/base/public/nsIRequestObserverProxy.idl @@ -38,25 +38,25 @@ #include "nsIRequestObserver.idl" -interface nsIEventQueue; +interface nsIEventTarget; /** - * A request observer proxy is used to ship data over to another thread specified - * by the thread's event queue. The "true" request observer's methods are - * invoked on the other thread. + * A request observer proxy is used to ship data over to another thread + * specified by the thread's dispatch target. The "true" request observer's + * methods are invoked on the other thread. * - * This interface only provides the initialization needed after construction. Otherwise, - * these objects are used simply as nsIRequestObserver's. + * This interface only provides the initialization needed after construction. + * Otherwise, these objects are used simply as nsIRequestObserver's. */ -[scriptable, uuid(3c9b532e-db84-4ecf-aa6a-4d38a9c4c5f0)] +[scriptable, uuid(7df8845f-938a-4437-9ea4-b11b850048f1)] interface nsIRequestObserverProxy : nsIRequestObserver { /** * Initializes an nsIRequestObserverProxy. * * @param observer - receives observer notifications on the other thread - * @param eventQ - may be NULL indicating the calling thread's event queue + * @param target - may be NULL indicating the calling thread's event target */ void init(in nsIRequestObserver observer, - in nsIEventQueue eventQ); + in nsIEventTarget target); }; diff --git a/mozilla/netwerk/base/public/nsITransport.idl b/mozilla/netwerk/base/public/nsITransport.idl index c38ef247611..40f1c3267ad 100644 --- a/mozilla/netwerk/base/public/nsITransport.idl +++ b/mozilla/netwerk/base/public/nsITransport.idl @@ -57,7 +57,7 @@ interface nsIEventTarget; * socket transport, these events can include status about the connection. * See nsISocketTransport for more info about socket transport specifics. */ -[scriptable, uuid(cbb0baeb-5fcb-408b-a2be-9f8fc98d0af1)] +[scriptable, uuid(d8786c64-eb49-4a0b-b42c-0936a745fbe8)] interface nsITransport : nsISupports { /** diff --git a/mozilla/netwerk/base/public/nsNetUtil.h b/mozilla/netwerk/base/public/nsNetUtil.h index d1defd28e76..a19b3ff1c0d 100644 --- a/mozilla/netwerk/base/public/nsNetUtil.h +++ b/mozilla/netwerk/base/public/nsNetUtil.h @@ -54,7 +54,6 @@ #include "nsISafeOutputStream.h" #include "nsIStreamListener.h" #include "nsIRequestObserverProxy.h" -#include "nsIStreamListenerProxy.h" // XXX for nsIAsyncStreamListener #include "nsISimpleStreamListener.h" #include "nsILoadGroup.h" #include "nsIInterfaceRequestor.h" @@ -533,13 +532,13 @@ NS_ImplementChannelOpen(nsIChannel *channel, inline nsresult NS_NewRequestObserverProxy(nsIRequestObserver **result, nsIRequestObserver *observer, - nsIEventQueue *eventQ = nsnull) + nsIEventTarget *target = nsnull) { nsresult rv; nsCOMPtr proxy = do_CreateInstance(NS_REQUESTOBSERVERPROXY_CONTRACTID, &rv); if (NS_SUCCEEDED(rv)) { - rv = proxy->Init(observer, eventQ); + rv = proxy->Init(observer, target); if (NS_SUCCEEDED(rv)) NS_ADDREF(*result = proxy); // cannot use nsCOMPtr::swap } @@ -562,22 +561,6 @@ NS_NewSimpleStreamListener(nsIStreamListener **result, return rv; } -inline nsresult -NS_NewAsyncStreamListener(nsIStreamListener **result, - nsIStreamListener *receiver, - nsIEventQueue *eventQ) -{ - nsresult rv; - nsCOMPtr lsnr = - do_CreateInstance(NS_ASYNCSTREAMLISTENER_CONTRACTID, &rv); - if (NS_SUCCEEDED(rv)) { - rv = lsnr->Init(receiver, eventQ); - if (NS_SUCCEEDED(rv)) - NS_ADDREF(*result = lsnr); // cannot use nsCOMPtr::swap - } - return rv; -} - inline nsresult NS_CheckPortSafety(PRInt32 port, const char *scheme, diff --git a/mozilla/netwerk/base/src/Makefile.in b/mozilla/netwerk/base/src/Makefile.in index 3856b308dc6..b5657ff9b42 100644 --- a/mozilla/netwerk/base/src/Makefile.in +++ b/mozilla/netwerk/base/src/Makefile.in @@ -56,10 +56,8 @@ REQUIRES = xpcom \ $(NULL) CPPSRCS = \ - nsIOThreadPool.cpp \ nsTransportUtils.cpp \ nsAsyncStreamCopier.cpp \ - nsAsyncStreamListener.cpp \ nsBaseChannel.cpp \ nsBaseContentStream.cpp \ nsBufferedStreams.cpp \ diff --git a/mozilla/netwerk/base/src/nsAsyncStreamCopier.cpp b/mozilla/netwerk/base/src/nsAsyncStreamCopier.cpp index 7e060938167..5430d15187b 100644 --- a/mozilla/netwerk/base/src/nsAsyncStreamCopier.cpp +++ b/mozilla/netwerk/base/src/nsAsyncStreamCopier.cpp @@ -36,6 +36,7 @@ * ***** END LICENSE BLOCK ***** */ #include "nsAsyncStreamCopier.h" +#include "nsIEventTarget.h" #include "nsStreamUtils.h" #include "nsNetSegmentUtils.h" #include "nsNetUtil.h" @@ -245,7 +246,7 @@ nsAsyncStreamCopier::Init(nsIInputStream *source, mTarget = target; else { nsresult rv; - mTarget = do_GetService(NS_IOTHREADPOOL_CONTRACTID, &rv); + mTarget = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; } return NS_OK; diff --git a/mozilla/netwerk/base/src/nsBaseContentStream.cpp b/mozilla/netwerk/base/src/nsBaseContentStream.cpp index 900c26bf0d5..3e6ab49e8f8 100644 --- a/mozilla/netwerk/base/src/nsBaseContentStream.cpp +++ b/mozilla/netwerk/base/src/nsBaseContentStream.cpp @@ -138,8 +138,9 @@ nsBaseContentStream::CloseWithStatus(nsresult status) } NS_IMETHODIMP -nsBaseContentStream::AsyncWait(nsIInputStreamCallback *callback, PRUint32 flags, - PRUint32 requestedCount, nsIEventTarget *target) +nsBaseContentStream::AsyncWait(nsIInputStreamCallback *callback, + PRUint32 flags, PRUint32 requestedCount, + nsIEventTarget *target) { // Our _only_ consumer is nsInputStreamPump, so we simplify things here by // making assumptions about how we will be called. diff --git a/mozilla/netwerk/base/src/nsBaseContentStream.h b/mozilla/netwerk/base/src/nsBaseContentStream.h index 1660a7e9f35..bca954ebf48 100644 --- a/mozilla/netwerk/base/src/nsBaseContentStream.h +++ b/mozilla/netwerk/base/src/nsBaseContentStream.h @@ -84,7 +84,7 @@ public: // Called to test if the stream has a pending callback. PRBool HasPendingCallback() { return mCallback != nsnull; } - // The current event target (may be null) for the pending callback if any. + // The current dispatch target (may be null) for the pending callback if any. nsIEventTarget *CallbackTarget() { return mCallbackTarget; } // Called to dispatch a pending callback. If there is no pending callback, diff --git a/mozilla/netwerk/base/src/nsIOService.cpp b/mozilla/netwerk/base/src/nsIOService.cpp index 36f60c86607..598d759bc46 100644 --- a/mozilla/netwerk/base/src/nsIOService.cpp +++ b/mozilla/netwerk/base/src/nsIOService.cpp @@ -41,7 +41,6 @@ #include "nsIFileProtocolHandler.h" #include "nscore.h" #include "nsIServiceManager.h" -#include "nsIEventQueueService.h" #include "nsIURI.h" #include "nsIStreamListener.h" #include "prprf.h" @@ -181,13 +180,6 @@ nsIOService::Init() { nsresult rv; - // Hold onto the eventQueue service. We do not want any eventqueues to go away - // when we shutdown until we process all remaining transports - - mEventQueueService = do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv); - if (NS_FAILED(rv)) - NS_WARNING("failed to get event queue service"); - // We need to get references to these services so that we can shut them // down later. If we wait until the nsIOService is being shut down, // GetService will fail at that point. diff --git a/mozilla/netwerk/base/src/nsIOService.h b/mozilla/netwerk/base/src/nsIOService.h index a55b8793abf..ede37d61207 100644 --- a/mozilla/netwerk/base/src/nsIOService.h +++ b/mozilla/netwerk/base/src/nsIOService.h @@ -49,7 +49,6 @@ #include "nsCOMPtr.h" #include "nsURLHelper.h" #include "nsWeakPtr.h" -#include "nsIEventQueueService.h" #include "nsIURLParser.h" #include "nsSupportsArray.h" #include "nsIObserver.h" @@ -130,7 +129,6 @@ private: nsCOMPtr mSocketTransportService; nsCOMPtr mDNSService; nsCOMPtr mProxyService; - nsCOMPtr mEventQueueService; // Cached protocol handlers nsWeakPtr mWeakHandler[NS_N(gScheme)]; diff --git a/mozilla/netwerk/base/src/nsInputStreamPump.cpp b/mozilla/netwerk/base/src/nsInputStreamPump.cpp index 200f8d5f069..529a35fcba6 100644 --- a/mozilla/netwerk/base/src/nsInputStreamPump.cpp +++ b/mozilla/netwerk/base/src/nsInputStreamPump.cpp @@ -42,7 +42,7 @@ #include "nsISeekableStream.h" #include "nsITransport.h" #include "nsNetUtil.h" -#include "nsEventQueueUtils.h" +#include "nsThreadUtils.h" #include "nsNetSegmentUtils.h" #include "nsCOMPtr.h" #include "prlog.h" @@ -142,7 +142,7 @@ nsInputStreamPump::EnsureWaiting() // on only one thread. if (!mWaiting) { - nsresult rv = mAsyncStream->AsyncWait(this, 0, 0, mEventQ); + nsresult rv = mAsyncStream->AsyncWait(this, 0, 0, mTargetThread); if (NS_FAILED(rv)) { NS_ERROR("AsyncWait failed"); return rv; @@ -346,7 +346,7 @@ nsInputStreamPump::AsyncRead(nsIStreamListener *listener, nsISupports *ctxt) // grab event queue (we must do this here by contract, since all notifications // must go to the thread which called AsyncRead) - rv = NS_GetCurrentEventQ(getter_AddRefs(mEventQ)); + mTargetThread = do_GetCurrentThread(); if (NS_FAILED(rv)) return rv; rv = EnsureWaiting(); @@ -560,7 +560,7 @@ nsInputStreamPump::OnStateStop() mAsyncStream->Close(); mAsyncStream = 0; - mEventQ = 0; + mTargetThread = 0; mIsPending = PR_FALSE; mListener->OnStopRequest(this, mListenerContext, mStatus); diff --git a/mozilla/netwerk/base/src/nsInputStreamPump.h b/mozilla/netwerk/base/src/nsInputStreamPump.h index 4cce57730dc..28a9f04b96a 100644 --- a/mozilla/netwerk/base/src/nsInputStreamPump.h +++ b/mozilla/netwerk/base/src/nsInputStreamPump.h @@ -46,7 +46,7 @@ #include "nsIInterfaceRequestor.h" #include "nsIProgressEventSink.h" #include "nsIAsyncInputStream.h" -#include "nsIEventQueue.h" +#include "nsIThread.h" #include "nsCOMPtr.h" class nsInputStreamPump : public nsIInputStreamPump @@ -102,7 +102,7 @@ protected: nsCOMPtr mLoadGroup; nsCOMPtr mListener; nsCOMPtr mListenerContext; - nsCOMPtr mEventQ; + nsCOMPtr mTargetThread; nsCOMPtr mStream; nsCOMPtr mAsyncStream; PRUint64 mStreamOffset; diff --git a/mozilla/netwerk/base/src/nsLoadGroup.cpp b/mozilla/netwerk/base/src/nsLoadGroup.cpp index 9425799e6ea..49c17601df4 100644 --- a/mozilla/netwerk/base/src/nsLoadGroup.cpp +++ b/mozilla/netwerk/base/src/nsLoadGroup.cpp @@ -41,7 +41,6 @@ #include "nsISupportsArray.h" #include "nsEnumeratorUtils.h" #include "nsIServiceManager.h" -#include "nsIEventQueueService.h" #include "nsCOMPtr.h" #include "nsIURI.h" #include "prlog.h" diff --git a/mozilla/netwerk/base/src/nsPACMan.cpp b/mozilla/netwerk/base/src/nsPACMan.cpp index 1ebdc2f7d8d..f88d3a5a59f 100644 --- a/mozilla/netwerk/base/src/nsPACMan.cpp +++ b/mozilla/netwerk/base/src/nsPACMan.cpp @@ -37,10 +37,10 @@ * ***** END LICENSE BLOCK ***** */ #include "nsPACMan.h" +#include "nsThreadUtils.h" #include "nsIDNSService.h" #include "nsIDNSListener.h" #include "nsICancelable.h" -#include "nsEventQueueUtils.h" #include "nsNetUtil.h" #include "nsAutoLock.h" #include "nsAutoPtr.h" @@ -97,12 +97,12 @@ PendingPACQuery::Start() if (NS_FAILED(rv)) return rv; - nsCOMPtr eventQ; - rv = NS_GetCurrentEventQ(getter_AddRefs(eventQ)); + nsCOMPtr thread; + rv = NS_GetCurrentThread(getter_AddRefs(thread)); if (NS_FAILED(rv)) return rv; - rv = dns->AsyncResolve(host, 0, this, eventQ, getter_AddRefs(mDNSRequest)); + rv = dns->AsyncResolve(host, 0, this, thread, getter_AddRefs(mDNSRequest)); if (NS_FAILED(rv)) NS_WARNING("DNS AsyncResolve failed"); @@ -152,7 +152,7 @@ PendingPACQuery::OnLookupComplete(nsICancelable *request, //----------------------------------------------------------------------------- nsPACMan::nsPACMan() - : mLoadEvent(nsnull) + : mLoadPending(PR_FALSE) , mShutdown(PR_FALSE) { PR_INIT_CLIST(&mPendingQ); @@ -226,6 +226,7 @@ nsPACMan::AsyncGetProxyForURI(nsIURI *uri, nsPACManCallback *callback) return rv; } +/* void *PR_CALLBACK nsPACMan::LoadEvent_Handle(PLEvent *ev) { @@ -241,6 +242,15 @@ nsPACMan::LoadEvent_Destroy(PLEvent *ev) self->Release(); delete ev; } +*/ + +NS_IMETHODIMP +nsPACMan::Run() +{ + mLoadPending = PR_FALSE; + StartLoading(); + return NS_OK; +} nsresult nsPACMan::LoadPACFromURI(nsIURI *pacURI) @@ -257,20 +267,11 @@ nsPACMan::LoadPACFromURI(nsIURI *pacURI) // But, we need to flag ourselves as loading, so that we queue up any PAC // queries the enter between now and when we actually load the PAC file. - if (!mLoadEvent) { - mLoadEvent = new PLEvent; - if (!mLoadEvent) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF_THIS(); - PL_InitEvent(mLoadEvent, this, LoadEvent_Handle, LoadEvent_Destroy); - - nsCOMPtr eventQ; - nsresult rv = NS_GetCurrentEventQ(getter_AddRefs(eventQ)); - if (NS_FAILED(rv) || NS_FAILED(rv = eventQ->PostEvent(mLoadEvent))) { - PL_DestroyEvent(mLoadEvent); + if (!mLoadPending) { + nsresult rv; + if (NS_FAILED(rv = NS_DispatchToCurrentThread(this))) return rv; - } + mLoadPending = PR_TRUE; } CancelExistingLoad(); diff --git a/mozilla/netwerk/base/src/nsPACMan.h b/mozilla/netwerk/base/src/nsPACMan.h index 00dfcc6c4b2..8e9deb014de 100644 --- a/mozilla/netwerk/base/src/nsPACMan.h +++ b/mozilla/netwerk/base/src/nsPACMan.h @@ -43,11 +43,11 @@ #include "nsIInterfaceRequestor.h" #include "nsIChannelEventSink.h" #include "nsIProxyAutoConfig.h" +#include "nsIRunnable.h" #include "nsIURI.h" #include "nsCOMPtr.h" #include "nsString.h" #include "prclist.h" -#include "plevent.h" /** * This class defines a callback interface used by AsyncGetProxyForURI. @@ -74,6 +74,7 @@ public: class nsPACMan : public nsIStreamLoaderObserver , public nsIInterfaceRequestor , public nsIChannelEventSink + , public nsIRunnable { public: NS_DECL_ISUPPORTS @@ -132,6 +133,7 @@ private: NS_DECL_NSISTREAMLOADEROBSERVER NS_DECL_NSIINTERFACEREQUESTOR NS_DECL_NSICHANNELEVENTSINK + NS_DECL_NSIRUNNABLE ~nsPACMan(); @@ -163,16 +165,18 @@ private: /** * Event fu for calling StartLoading asynchronously. */ + /*XXX PR_STATIC_CALLBACK(void *) LoadEvent_Handle(PLEvent *); PR_STATIC_CALLBACK(void) LoadEvent_Destroy(PLEvent *); + */ private: nsCOMPtr mPAC; nsCOMPtr mPACURI; PRCList mPendingQ; nsCOMPtr mLoader; - PLEvent *mLoadEvent; - PRBool mShutdown; + PRPackedBool mLoadPending; + PRPackedBool mShutdown; }; #endif // nsPACMan_h__ diff --git a/mozilla/netwerk/base/src/nsProtocolProxyService.cpp b/mozilla/netwerk/base/src/nsProtocolProxyService.cpp index 452ca9527cd..96e0e3d7c6c 100644 --- a/mozilla/netwerk/base/src/nsProtocolProxyService.cpp +++ b/mozilla/netwerk/base/src/nsProtocolProxyService.cpp @@ -43,7 +43,6 @@ #include "nsXPIDLString.h" #include "nsIProxyAutoConfig.h" #include "nsAutoLock.h" -#include "nsEventQueueUtils.h" #include "nsIIOService.h" #include "nsIObserverService.h" #include "nsIProtocolHandler.h" @@ -53,11 +52,11 @@ #include "nsIPrefService.h" #include "nsIPrefBranch2.h" #include "nsReadableUtils.h" +#include "nsThreadUtils.h" #include "nsString.h" #include "nsNetUtil.h" #include "nsCRT.h" #include "prnetdb.h" -#include "nsEventQueueUtils.h" #include "nsPACMan.h" //---------------------------------------------------------------------------- @@ -79,7 +78,7 @@ struct nsProtocolInfo { //---------------------------------------------------------------------------- -class nsAsyncResolveRequest : public PLEvent +class nsAsyncResolveRequest : public nsIRunnable , public nsPACManCallback , public nsICancelable { @@ -95,7 +94,6 @@ public: , mCallback(callback) { NS_ASSERTION(mCallback, "null callback"); - PL_InitEvent(this, nsnull, HandleEvent, CleanupEvent); } void SetResult(nsresult status, nsIProxyInfo *pi) @@ -104,6 +102,13 @@ public: mProxyInfo = pi; } + NS_IMETHOD Run() + { + if (mCallback) + DoCallback(); + return NS_OK; + } + NS_IMETHOD Cancel(nsresult reason) { NS_ENSURE_ARG(NS_FAILED(reason)); @@ -121,21 +126,12 @@ public: if (mDispatched) // Only need to dispatch once return NS_OK; - nsCOMPtr eventQ; - nsresult rv = NS_GetCurrentEventQ(getter_AddRefs(eventQ)); + nsresult rv = NS_DispatchToCurrentThread(this); if (NS_FAILED(rv)) - NS_WARNING("could not get current event queue"); + NS_WARNING("unable to dispatch callback event"); else { - NS_ADDREF_THIS(); - rv = eventQ->PostEvent(this); - if (NS_FAILED(rv)) { - NS_WARNING("unable to dispatch callback event"); - PL_DestroyEvent(this); - } - else { - mDispatched = PR_TRUE; - return NS_OK; - } + mDispatched = PR_TRUE; + return NS_OK; } mCallback = nsnull; // break possible reference cycle @@ -184,22 +180,6 @@ private: mCallback = nsnull; // in case the callback holds an owning ref to us } - PR_STATIC_CALLBACK(void *) HandleEvent(PLEvent *ev) - { - nsAsyncResolveRequest *self = - NS_STATIC_CAST(nsAsyncResolveRequest *, ev); - if (self->mCallback) - self->DoCallback(); - return nsnull; - } - - PR_STATIC_CALLBACK(void) CleanupEvent(PLEvent *ev) - { - nsAsyncResolveRequest *self = - NS_STATIC_CAST(nsAsyncResolveRequest *, ev); - NS_RELEASE(self); // balance AddRef in DispatchCallback - } - private: nsresult mStatus; diff --git a/mozilla/netwerk/base/src/nsProtocolProxyService.h b/mozilla/netwerk/base/src/nsProtocolProxyService.h index ba7d53c902e..c84571e3a0b 100644 --- a/mozilla/netwerk/base/src/nsProtocolProxyService.h +++ b/mozilla/netwerk/base/src/nsProtocolProxyService.h @@ -39,7 +39,6 @@ #ifndef nsProtocolProxyService_h__ #define nsProtocolProxyService_h__ -#include "plevent.h" #include "nsString.h" #include "nsCOMPtr.h" #include "nsAutoPtr.h" @@ -283,8 +282,6 @@ protected: NS_HIDDEN_(PRBool) CanUseProxy(nsIURI *uri, PRInt32 defaultPort); static PRBool PR_CALLBACK CleanupFilterArray(void *aElement, void *aData); - static void* PR_CALLBACK HandlePACLoadEvent(PLEvent* aEvent); - static void PR_CALLBACK DestroyPACLoadEvent(PLEvent* aEvent); public: // The Sun Forte compiler and others implement older versions of the diff --git a/mozilla/netwerk/base/src/nsRequestObserverProxy.cpp b/mozilla/netwerk/base/src/nsRequestObserverProxy.cpp index 47dfe325a00..0f7f8fb58bd 100644 --- a/mozilla/netwerk/base/src/nsRequestObserverProxy.cpp +++ b/mozilla/netwerk/base/src/nsRequestObserverProxy.cpp @@ -39,8 +39,9 @@ #include "nscore.h" #include "nsRequestObserverProxy.h" #include "nsIRequest.h" -#include "nsIEventQueueService.h" #include "nsIServiceManager.h" +#include "nsProxyRelease.h" +#include "nsAutoPtr.h" #include "nsString.h" #include "prlog.h" @@ -50,44 +51,6 @@ static PRLogModuleInfo *gRequestObserverProxyLog; #define LOG(args) PR_LOG(gRequestObserverProxyLog, PR_LOG_DEBUG, args) -static NS_DEFINE_CID(kEventQueueService, NS_EVENTQUEUESERVICE_CID); - -//----------------------------------------------------------------------------- -// ProxyRelease -//----------------------------------------------------------------------------- - -static void *PR_CALLBACK -ProxyRelease_EventHandlerFunc(PLEvent *ev) -{ - nsIRequestObserver *obs = - NS_STATIC_CAST(nsIRequestObserver *, PL_GetEventOwner(ev)); - NS_RELEASE(obs); - return nsnull; -} - -static void PR_CALLBACK -ProxyRelease_EventCleanupFunc(PLEvent *ev) -{ - delete ev; -} - -static void -ProxyRelease(nsIEventQueue *eventQ, nsIRequestObserver *obs) -{ - PLEvent *ev = new PLEvent; - if (!ev) { - NS_ERROR("failed to allocate PLEvent"); - return; - } - - PL_InitEvent(ev, (void *) obs, - ProxyRelease_EventHandlerFunc, - ProxyRelease_EventCleanupFunc); - - nsresult rv = eventQ->PostEvent(ev); - NS_ASSERTION(NS_SUCCEEDED(rv), "PostEvent failed"); -} - //----------------------------------------------------------------------------- // nsARequestObserverEvent internal class... //----------------------------------------------------------------------------- @@ -98,31 +61,6 @@ nsARequestObserverEvent::nsARequestObserverEvent(nsIRequest *request, , mContext(context) { NS_PRECONDITION(mRequest, "null pointer"); - - PL_InitEvent(&mEvent, nsnull, - nsARequestObserverEvent::HandlePLEvent, - nsARequestObserverEvent::DestroyPLEvent); -} - -void* PR_CALLBACK -nsARequestObserverEvent::HandlePLEvent(PLEvent *plev) -{ - nsARequestObserverEvent *ev = FromPLEvent(plev); - NS_ASSERTION(ev, "null event"); - - // Pass control to the real event handler - if (ev) - ev->HandleEvent(); - - return nsnull; -} - -void PR_CALLBACK -nsARequestObserverEvent::DestroyPLEvent(PLEvent *plev) -{ - nsARequestObserverEvent *ev = FromPLEvent(plev); - NS_ASSERTION(ev, "null event"); - delete ev; } //----------------------------------------------------------------------------- @@ -131,7 +69,7 @@ nsARequestObserverEvent::DestroyPLEvent(PLEvent *plev) class nsOnStartRequestEvent : public nsARequestObserverEvent { - nsRequestObserverProxy *mProxy; + nsRefPtr mProxy; public: nsOnStartRequestEvent(nsRequestObserverProxy *proxy, nsIRequest *request, @@ -140,23 +78,17 @@ public: , mProxy(proxy) { NS_PRECONDITION(mProxy, "null pointer"); - MOZ_COUNT_CTOR(nsOnStartRequestEvent); - NS_ADDREF(mProxy); } - ~nsOnStartRequestEvent() - { - MOZ_COUNT_DTOR(nsOnStartRequestEvent); - NS_RELEASE(mProxy); - } + virtual ~nsOnStartRequestEvent() {} - void HandleEvent() + NS_IMETHOD Run() { LOG(("nsOnStartRequestEvent::HandleEvent [req=%x]\n", mRequest.get())); if (!mProxy->mObserver) { NS_NOTREACHED("already handled onStopRequest event (observer is null)"); - return; + return NS_OK; } LOG(("handle startevent=%8lX\n",(long)this)); @@ -166,6 +98,8 @@ public: rv = mRequest->Cancel(rv); NS_ASSERTION(NS_SUCCEEDED(rv), "Cancel failed for request!"); } + + return NS_OK; } }; @@ -175,7 +109,7 @@ public: class nsOnStopRequestEvent : public nsARequestObserverEvent { - nsRequestObserverProxy *mProxy; + nsRefPtr mProxy; public: nsOnStopRequestEvent(nsRequestObserverProxy *proxy, nsIRequest *request, nsISupports *context) @@ -183,17 +117,11 @@ public: , mProxy(proxy) { NS_PRECONDITION(mProxy, "null pointer"); - MOZ_COUNT_CTOR(nsOnStopRequestEvent); - NS_ADDREF(mProxy); } - ~nsOnStopRequestEvent() - { - MOZ_COUNT_DTOR(nsOnStopRequestEvent); - NS_RELEASE(mProxy); - } + virtual ~nsOnStopRequestEvent() {} - void HandleEvent() + NS_IMETHOD Run() { nsresult rv, status = NS_OK; @@ -202,7 +130,7 @@ public: nsCOMPtr observer = mProxy->mObserver; if (!observer) { NS_NOTREACHED("already handled onStopRequest event (observer is null)"); - return; + return NS_OK; } // Do not allow any more events to be handled after OnStopRequest mProxy->mObserver = 0; @@ -212,6 +140,8 @@ public: LOG(("handle stopevent=%8lX\n",(long)this)); (void) observer->OnStopRequest(mRequest, mContext, status); + + return NS_OK; } }; @@ -228,7 +158,7 @@ nsRequestObserverProxy::~nsRequestObserverProxy() nsIRequestObserver *obs = mObserver; NS_ADDREF(obs); mObserver = 0; - ProxyRelease(mEventQ, obs); + NS_ProxyRelease(mTarget, obs); } } @@ -255,7 +185,7 @@ nsRequestObserverProxy::OnStartRequest(nsIRequest *request, if (!ev) return NS_ERROR_OUT_OF_MEMORY; - LOG(("post startevent=%8lX queue=%8lX\n",(long)ev,(long)mEventQ.get())); + LOG(("post startevent=%p queue=%p\n", ev, mTarget.get())); nsresult rv = FireEvent(ev); if (NS_FAILED(rv)) delete ev; @@ -280,7 +210,7 @@ nsRequestObserverProxy::OnStopRequest(nsIRequest *request, if (!ev) return NS_ERROR_OUT_OF_MEMORY; - LOG(("post stopevent=%8lX queue=%8lX\n",(long)ev,(long)mEventQ.get())); + LOG(("post stopevent=%p queue=%p\n", ev, mTarget.get())); nsresult rv = FireEvent(ev); if (NS_FAILED(rv)) delete ev; @@ -293,7 +223,7 @@ nsRequestObserverProxy::OnStopRequest(nsIRequest *request, NS_IMETHODIMP nsRequestObserverProxy::Init(nsIRequestObserver *observer, - nsIEventQueue *eventQ) + nsIEventTarget *target) { NS_ENSURE_ARG_POINTER(observer); @@ -304,7 +234,15 @@ nsRequestObserverProxy::Init(nsIRequestObserver *observer, mObserver = observer; - return SetEventQueue(eventQ); + nsCOMPtr thread; + if (!target) { + thread = do_GetCurrentThread(); + target = thread; + NS_ENSURE_STATE(target); + } + + SetTarget(target); + return NS_OK; } //----------------------------------------------------------------------------- @@ -314,21 +252,6 @@ nsRequestObserverProxy::Init(nsIRequestObserver *observer, nsresult nsRequestObserverProxy::FireEvent(nsARequestObserverEvent *event) { - NS_ENSURE_TRUE(mEventQ, NS_ERROR_NOT_INITIALIZED); - - return mEventQ->PostEvent(event->GetPLEvent()); -} - -nsresult -nsRequestObserverProxy::SetEventQueue(nsIEventQueue *eq) -{ - nsresult rv = NS_OK; - if ((eq == NS_CURRENT_EVENTQ) || (eq == NS_UI_THREAD_EVENTQ)) { - nsCOMPtr serv = do_GetService(kEventQueueService, &rv); - if (NS_FAILED(rv)) return rv; - rv = serv->GetSpecialEventQueue(NS_PTR_TO_INT32(eq), getter_AddRefs(mEventQ)); - } - else - mEventQ = eq; - return rv; + NS_ENSURE_TRUE(mTarget, NS_ERROR_NOT_INITIALIZED); + return mTarget->Dispatch(event, NS_DISPATCH_NORMAL); } diff --git a/mozilla/netwerk/base/src/nsRequestObserverProxy.h b/mozilla/netwerk/base/src/nsRequestObserverProxy.h index 294c54df1de..83a2f054f18 100644 --- a/mozilla/netwerk/base/src/nsRequestObserverProxy.h +++ b/mozilla/netwerk/base/src/nsRequestObserverProxy.h @@ -41,8 +41,8 @@ #include "nsIRequestObserver.h" #include "nsIRequestObserverProxy.h" -#include "nsIEventQueue.h" #include "nsIRequest.h" +#include "nsThreadUtils.h" #include "nsCOMPtr.h" class nsARequestObserverEvent; @@ -54,44 +54,31 @@ public: NS_DECL_NSIREQUESTOBSERVER NS_DECL_NSIREQUESTOBSERVERPROXY - nsRequestObserverProxy() { } - virtual ~nsRequestObserverProxy(); + nsRequestObserverProxy() {} nsIRequestObserver *Observer() { return mObserver; } nsresult FireEvent(nsARequestObserverEvent *); - nsIEventQueue *EventQueue() { return mEventQ.get(); } // debugging aid - nsresult SetEventQueue(nsIEventQueue *); + nsIEventTarget *Target() { return mTarget; } // debugging aid + void SetTarget(nsIEventTarget *target) { mTarget = target; } protected: + virtual ~nsRequestObserverProxy(); + nsCOMPtr mObserver; - nsCOMPtr mEventQ; + nsCOMPtr mTarget; friend class nsOnStartRequestEvent; friend class nsOnStopRequestEvent; }; -class nsARequestObserverEvent +class nsARequestObserverEvent : public nsRunnable { public: nsARequestObserverEvent(nsIRequest *, nsISupports *); - virtual ~nsARequestObserverEvent() {} - - static nsARequestObserverEvent *FromPLEvent(PLEvent *p) - { return (nsARequestObserverEvent *) - ( (char *) p - offsetof(nsARequestObserverEvent, mEvent) ); } - PLEvent *GetPLEvent() { return &mEvent; } - - /** - * Implement this method to add code to handle the event - */ - virtual void HandleEvent() = 0; protected: - static void* PR_CALLBACK HandlePLEvent(PLEvent *); - static void PR_CALLBACK DestroyPLEvent(PLEvent *); - - PLEvent mEvent; // this _must_ be the first data member + virtual ~nsARequestObserverEvent() {} nsCOMPtr mRequest; nsCOMPtr mContext; diff --git a/mozilla/netwerk/base/src/nsServerSocket.cpp b/mozilla/netwerk/base/src/nsServerSocket.cpp index c56cd721a8d..a29bc7f827d 100644 --- a/mozilla/netwerk/base/src/nsServerSocket.cpp +++ b/mozilla/netwerk/base/src/nsServerSocket.cpp @@ -52,47 +52,32 @@ static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID); typedef void (nsServerSocket:: *nsServerSocketFunc)(void); -struct nsServerSocketEvent : PLEvent +class nsServerSocketEvent : public nsRunnable { +public: nsServerSocketEvent(nsServerSocket *s, nsServerSocketFunc f) - : func(f) - { - NS_ADDREF(s); - PL_InitEvent(this, s, EventHandler, EventCleanup); - } + : mServerSocket(s) + , mFunc(f) + {} - PR_STATIC_CALLBACK(void *) - EventHandler(PLEvent *ev) + NS_IMETHOD Run() { - nsServerSocket *s = (nsServerSocket *) ev->owner; - nsServerSocketEvent *event = (nsServerSocketEvent *) ev; - nsServerSocketFunc func = event->func; - (s->*func)(); + (mServerSocket->*mFunc)(); return nsnull; } - PR_STATIC_CALLBACK(void) - EventCleanup(PLEvent *ev) - { - nsServerSocket *s = (nsServerSocket *) ev->owner; - NS_RELEASE(s); - delete (nsServerSocketEvent *) ev; - } - - nsServerSocketFunc func; + nsRefPtr mServerSocket; + nsServerSocketFunc mFunc; }; static nsresult PostEvent(nsServerSocket *s, nsServerSocketFunc func) { - nsServerSocketEvent *ev = new nsServerSocketEvent(s, func); + nsRefPtr ev = new nsServerSocketEvent(s, func); if (!ev) return NS_ERROR_OUT_OF_MEMORY; - nsresult rv = gSocketTransportService->PostEvent(ev); - if (NS_FAILED(rv)) - PL_DestroyEvent(ev); - return rv; + return gSocketTransportService->Dispatch(ev, NS_DISPATCH_NORMAL); } //----------------------------------------------------------------------------- @@ -182,16 +167,14 @@ nsServerSocket::TryAttach() // if (!gSocketTransportService->CanAttachSocket()) { - PLEvent *event = new nsServerSocketEvent(this, &nsServerSocket::OnMsgAttach); + nsCOMPtr event = + new nsServerSocketEvent(this, &nsServerSocket::OnMsgAttach); if (!event) return NS_ERROR_OUT_OF_MEMORY; nsresult rv = gSocketTransportService->NotifyWhenCanAttachSocket(event); if (NS_FAILED(rv)) - { - PL_DestroyEvent(event); return rv; - } } // @@ -400,10 +383,10 @@ nsServerSocket::AsyncListen(nsIServerSocketListener *aListener) NS_ENSURE_TRUE(mListener == nsnull, NS_ERROR_IN_PROGRESS); { nsAutoLock lock(mLock); - nsresult rv = NS_GetProxyForObject(NS_CURRENT_EVENTQ, + nsresult rv = NS_GetProxyForObject(NS_PROXY_TO_CURRENT_THREAD, NS_GET_IID(nsIServerSocketListener), aListener, - PROXY_ASYNC | PROXY_ALWAYS, + NS_PROXY_ASYNC | NS_PROXY_ALWAYS, getter_AddRefs(mListener)); if (NS_FAILED(rv)) return rv; diff --git a/mozilla/netwerk/base/src/nsSocketTransport2.cpp b/mozilla/netwerk/base/src/nsSocketTransport2.cpp index 2216e1412f1..5143ed3614b 100644 --- a/mozilla/netwerk/base/src/nsSocketTransport2.cpp +++ b/mozilla/netwerk/base/src/nsSocketTransport2.cpp @@ -50,6 +50,7 @@ #include "nsProxyInfo.h" #include "nsNetCID.h" #include "nsAutoLock.h" +#include "nsAutoPtr.h" #include "nsCOMPtr.h" #include "netCore.h" #include "nsInt64.h" @@ -78,37 +79,26 @@ static NS_DEFINE_CID(kDNSServiceCID, NS_DNSSERVICE_CID); //----------------------------------------------------------------------------- -class nsSocketEvent : public PLEvent +class nsSocketEvent : public nsRunnable { public: nsSocketEvent(nsSocketTransport *transport, PRUint32 type, nsresult status = NS_OK, nsISupports *param = nsnull) - : mType(type) + : mTransport(transport) + , mType(type) , mStatus(status) , mParam(param) - { - NS_ADDREF(transport); - PL_InitEvent(this, transport, HandleEvent, DestroyEvent); - } + {} - PR_STATIC_CALLBACK(void*) - HandleEvent(PLEvent *event) + NS_IMETHOD Run() { - nsSocketTransport *trans = (nsSocketTransport *) event->owner; - nsSocketEvent *se = (nsSocketEvent *) event; - trans->OnSocketEvent(se->mType, se->mStatus, se->mParam); - return nsnull; - } - - PR_STATIC_CALLBACK(void) - DestroyEvent(PLEvent *event) - { - nsSocketTransport *trans = (nsSocketTransport *) event->owner; - NS_RELEASE(trans); - delete (nsSocketEvent *) event; + mTransport->OnSocketEvent(mType, mStatus, mParam); + return NS_OK; } private: + nsRefPtr mTransport; + PRUint32 mType; nsresult mStatus; nsCOMPtr mParam; @@ -854,15 +844,11 @@ nsSocketTransport::PostEvent(PRUint32 type, nsresult status, nsISupports *param) LOG(("nsSocketTransport::PostEvent [this=%p type=%u status=%x param=%p]\n", this, type, status, param)); - PLEvent *event = new nsSocketEvent(this, type, status, param); + nsCOMPtr event = new nsSocketEvent(this, type, status, param); if (!event) return NS_ERROR_OUT_OF_MEMORY; - nsresult rv = gSocketTransportService->PostEvent(event); - if (NS_FAILED(rv)) - PL_DestroyEvent(event); - - return rv; + return gSocketTransportService->Dispatch(event, NS_DISPATCH_NORMAL); } void @@ -1061,13 +1047,11 @@ nsSocketTransport::InitiateSocket() // 194402 for more info. // if (!gSocketTransportService->CanAttachSocket()) { - PLEvent *event = new nsSocketEvent(this, MSG_RETRY_INIT_SOCKET); + nsCOMPtr event = + new nsSocketEvent(this, MSG_RETRY_INIT_SOCKET); if (!event) return NS_ERROR_OUT_OF_MEMORY; - rv = gSocketTransportService->NotifyWhenCanAttachSocket(event); - if (NS_FAILED(rv)) - PL_DestroyEvent(event); - return rv; + return gSocketTransportService->NotifyWhenCanAttachSocket(event); } // diff --git a/mozilla/netwerk/base/src/nsSocketTransportService2.cpp b/mozilla/netwerk/base/src/nsSocketTransportService2.cpp index e3a15b6d5e5..e997ecda193 100644 --- a/mozilla/netwerk/base/src/nsSocketTransportService2.cpp +++ b/mozilla/netwerk/base/src/nsSocketTransportService2.cpp @@ -57,31 +57,16 @@ PRLogModuleInfo *gSocketTransportLog = nsnull; nsSocketTransportService *gSocketTransportService = nsnull; PRThread *gSocketThread = nsnull; -#define PLEVENT_FROM_LINK(_link) \ - ((PLEvent*) ((char*) (_link) - offsetof(PLEvent, link))) - -static inline void -MoveCList(PRCList &from, PRCList &to) -{ - if (!PR_CLIST_IS_EMPTY(&from)) { - to.next = from.next; - to.prev = from.prev; - to.next->prev = &to; - to.prev->next = &to; - PR_INIT_CLIST(&from); - } -} - //----------------------------------------------------------------------------- // ctor/dtor (called on the main/UI thread by the service manager) nsSocketTransportService::nsSocketTransportService() - : mInitialized(PR_FALSE) - , mThread(nsnull) + : mThread(nsnull) , mThreadEvent(nsnull) , mAutodialEnabled(PR_FALSE) + , mLock(PR_NewLock()) + , mInitialized(PR_FALSE) , mShuttingDown(PR_FALSE) - , mEventQLock(PR_NewLock()) , mActiveCount(0) , mIdleCount(0) { @@ -89,10 +74,7 @@ nsSocketTransportService::nsSocketTransportService() gSocketTransportLog = PR_NewLogModule("nsSocketTransport"); #endif - NS_ASSERTION(nsIThread::IsMainThread(), "wrong thread"); - - PR_INIT_CLIST(&mEventQ); - PR_INIT_CLIST(&mPendingSocketQ); + NS_ASSERTION(NS_IsMainThread(), "wrong thread"); NS_ASSERTION(!gSocketTransportService, "must not instantiate twice"); gSocketTransportService = this; @@ -100,10 +82,10 @@ nsSocketTransportService::nsSocketTransportService() nsSocketTransportService::~nsSocketTransportService() { - NS_ASSERTION(nsIThread::IsMainThread(), "wrong thread"); + NS_ASSERTION(NS_IsMainThread(), "wrong thread"); NS_ASSERTION(!mInitialized, "not shutdown properly"); - PR_DestroyLock(mEventQLock); + PR_DestroyLock(mLock); if (mThreadEvent) PR_DestroyPollableEvent(mThreadEvent); @@ -115,43 +97,26 @@ nsSocketTransportService::~nsSocketTransportService() // event queue (any thread) NS_IMETHODIMP -nsSocketTransportService::PostEvent(PLEvent *event) +nsSocketTransportService::Dispatch(nsIRunnable *event, PRUint32 flags) { - LOG(("nsSocketTransportService::PostEvent [event=%p]\n", event)); + LOG(("STS dispatch [%p]\n", event)); - NS_ASSERTION(event, "null event"); - - nsAutoLock lock(mEventQLock); - if (!mInitialized) { - // Allow socket detach handlers to post events - if (!mShuttingDown || (PR_GetCurrentThread() != gSocketThread)) { - NS_WARN_IF_FALSE(PR_GetCurrentThread() != gSocketThread, - "Rejecting event posted to uninitialized sts"); - return NS_ERROR_OFFLINE; - } - - } - - PR_APPEND_LINK(&event->link, &mEventQ); - - if (mThreadEvent) - PR_SetPollableEvent(mThreadEvent); - // else wait for Poll timeout - return NS_OK; + NS_ENSURE_TRUE(mThread, NS_ERROR_NOT_INITIALIZED); + return mThread->Dispatch(event, flags); } NS_IMETHODIMP nsSocketTransportService::IsOnCurrentThread(PRBool *result) { - *result = (PR_GetCurrentThread() == gSocketThread); - return NS_OK; + NS_ENSURE_TRUE(mThread, NS_ERROR_NOT_INITIALIZED); + return mThread->IsOnCurrentThread(result); } //----------------------------------------------------------------------------- // socket api (socket thread only) nsresult -nsSocketTransportService::NotifyWhenCanAttachSocket(PLEvent *event) +nsSocketTransportService::NotifyWhenCanAttachSocket(nsIRunnable *event) { LOG(("nsSocketTransportService::NotifyWhenCanAttachSocket\n")); @@ -159,10 +124,10 @@ nsSocketTransportService::NotifyWhenCanAttachSocket(PLEvent *event) if (CanAttachSocket()) { NS_WARNING("should have called CanAttachSocket"); - return PostEvent(event); + return Dispatch(event, NS_DISPATCH_NORMAL); } - PR_APPEND_LINK(&event->link, &mPendingSocketQ); + mPendingSocketQ.PutEvent(event); return NS_OK; } @@ -208,11 +173,10 @@ nsSocketTransportService::DetachSocket(SocketContext *sock) // // notify the first element on the pending socket queue... // - if (!PR_CLIST_IS_EMPTY(&mPendingSocketQ)) { - // move event from pending queue to event queue - PLEvent *event = PLEVENT_FROM_LINK(PR_LIST_HEAD(&mPendingSocketQ)); - PR_REMOVE_AND_INIT_LINK(&event->link); - PostEvent(event); + nsCOMPtr event; + if (mPendingSocketQ.GetPendingEvent(getter_AddRefs(event))) { + // move event from pending queue to dispatch queue + return Dispatch(event, NS_DISPATCH_NORMAL); } return NS_OK; } @@ -332,7 +296,7 @@ nsSocketTransportService::PollTimeout() } PRInt32 -nsSocketTransportService::Poll(PRUint32 *interval) +nsSocketTransportService::Poll(PRBool wait, PRUint32 *interval) { PRPollDesc *pollList; PRUint32 pollCount; @@ -354,6 +318,9 @@ nsSocketTransportService::Poll(PRUint32 *interval) pollTimeout = PR_MillisecondsToInterval(25); } + if (!wait) + pollTimeout = PR_INTERVAL_NO_WAIT; + PRIntervalTime ts = PR_IntervalNow(); PRInt32 rv = PR_Poll(pollList, pollCount, pollTimeout); @@ -362,40 +329,13 @@ nsSocketTransportService::Poll(PRUint32 *interval) return rv; } -PRBool -nsSocketTransportService::ServiceEventQ() -{ - PRBool keepGoing; - - // grab the event queue - PRCList eq; - PR_INIT_CLIST(&eq); - { - nsAutoLock lock(mEventQLock); - - MoveCList(mEventQ, eq); - - // check to see if we're supposed to shutdown - keepGoing = mInitialized; - } - // service the event queue - PLEvent *event; - while (!PR_CLIST_IS_EMPTY(&eq)) { - event = PLEVENT_FROM_LINK(PR_LIST_HEAD(&eq)); - PR_REMOVE_AND_INIT_LINK(&event->link); - - PL_HandleEvent(event); - } - return keepGoing; -} - - //----------------------------------------------------------------------------- // xpcom api -NS_IMPL_THREADSAFE_ISUPPORTS4(nsSocketTransportService, +NS_IMPL_THREADSAFE_ISUPPORTS5(nsSocketTransportService, nsISocketTransportService, nsIEventTarget, + nsIThreadObserver, nsIRunnable, nsPISocketTransportService) @@ -403,7 +343,7 @@ NS_IMPL_THREADSAFE_ISUPPORTS4(nsSocketTransportService, NS_IMETHODIMP nsSocketTransportService::Init() { - NS_ASSERTION(nsIThread::IsMainThread(), "wrong thread"); + NS_ENSURE_STATE(NS_IsMainThread()); if (mInitialized) return NS_OK; @@ -424,7 +364,7 @@ nsSocketTransportService::Init() "running socket transport thread without a pollable event"); } - nsresult rv = NS_NewThread(&mThread, this, 0, PR_JOINABLE_THREAD); + nsresult rv = NS_NewThread(&mThread, this, "net.socket"); if (NS_FAILED(rv)) return rv; mInitialized = PR_TRUE; @@ -437,16 +377,16 @@ nsSocketTransportService::Shutdown() { LOG(("nsSocketTransportService::Shutdown\n")); - NS_ASSERTION(nsIThread::IsMainThread(), "wrong thread"); + NS_ENSURE_STATE(NS_IsMainThread()); if (!mInitialized) return NS_OK; { - nsAutoLock lock(mEventQLock); + nsAutoLock lock(mLock); - // signal uninitialized to block further events - mInitialized = PR_FALSE; + // signal the socket thread to shutdown + mShuttingDown = PR_TRUE; if (mThreadEvent) PR_SetPollableEvent(mThreadEvent); @@ -454,9 +394,12 @@ nsSocketTransportService::Shutdown() } // join with thread - mThread->Join(); + mThread->Shutdown(); NS_RELEASE(mThread); + mInitialized = PR_FALSE; + mShuttingDown = PR_FALSE; + return NS_OK; } @@ -500,144 +443,181 @@ nsSocketTransportService::SetAutodialEnabled(PRBool value) return NS_OK; } +NS_IMETHODIMP +nsSocketTransportService::OnDispatchedEvent(nsIThreadInternal *thread) +{ + if (mThreadEvent) + PR_SetPollableEvent(mThreadEvent); + return NS_OK; +} + +NS_IMETHODIMP +nsSocketTransportService::OnProcessNextEvent(nsIThreadInternal *thread, + PRBool mayWait) +{ + // Favor processing existing sockets before other events. + DoPollIteration(PR_FALSE); + + PRBool val; + while (mayWait && NS_SUCCEEDED(thread->HasPendingEvents(&val)) && !val) + DoPollIteration(PR_TRUE); + + return NS_OK; +} + NS_IMETHODIMP nsSocketTransportService::Run() { - LOG(("nsSocketTransportService::Run")); + LOG(("STS thread init\n")); gSocketThread = PR_GetCurrentThread(); - // // add thread event to poll list (mThreadEvent may be NULL) - // mPollList[0].fd = mThreadEvent; mPollList[0].in_flags = PR_POLL_READ; + nsCOMPtr thread = do_GetCurrentThread(); + + // hook ourselves up to observe event processing for this thread + nsCOMPtr threadInt = do_QueryInterface(mThread); + threadInt->SetObserver(this); + + for (;;) { + // process all pending events + NS_ProcessPendingEvents(thread); + + // now that our event queue is empty, check to see if we should exit + { + nsAutoLock lock(mLock); + if (mShuttingDown) + break; + } + + // wait for and process the next pending event + thread->ProcessNextEvent(); + } + + LOG(("STS shutting down thread\n")); + + // detach any sockets + PRInt32 i; + for (i=mActiveCount-1; i>=0; --i) + DetachSocket(&mActiveList[i]); + for (i=mIdleCount-1; i>=0; --i) + DetachSocket(&mIdleList[i]); + + // Final pass over the event queue. This makes sure that events posted by + // socket detach handlers get processed. + NS_ProcessPendingEvents(thread); + + gSocketThread = nsnull; + + LOG(("STS thread exit\n")); + return NS_OK; +} + +nsresult +nsSocketTransportService::DoPollIteration(PRBool wait) +{ + LOG(("STS poll iter [%d]\n", wait)); + PRInt32 i, count; // // poll loop // - PRBool active = PR_TRUE; - while (active) { - // - // walk active list backwards to see if any sockets should actually be - // idle, then walk the idle list backwards to see if any idle sockets - // should become active. take care to check only idle sockets that - // were idle to begin with ;-) - // - count = mIdleCount; - for (i=mActiveCount-1; i>=0; --i) { - //--- - LOG((" active [%u] { handler=%x condition=%x pollflags=%hu }\n", i, - mActiveList[i].mHandler, - mActiveList[i].mHandler->mCondition, - mActiveList[i].mHandler->mPollFlags)); - //--- - if (NS_FAILED(mActiveList[i].mHandler->mCondition)) - DetachSocket(&mActiveList[i]); - else { - PRUint16 in_flags = mActiveList[i].mHandler->mPollFlags; - if (in_flags == 0) - MoveToIdleList(&mActiveList[i]); - else { - // update poll flags - mPollList[i+1].in_flags = in_flags; - mPollList[i+1].out_flags = 0; - } - } - } - for (i=count-1; i>=0; --i) { - //--- - LOG((" idle [%u] { handler=%x condition=%x pollflags=%hu }\n", i, - mIdleList[i].mHandler, - mIdleList[i].mHandler->mCondition, - mIdleList[i].mHandler->mPollFlags)); - //--- - if (NS_FAILED(mIdleList[i].mHandler->mCondition)) - DetachSocket(&mIdleList[i]); - else if (mIdleList[i].mHandler->mPollFlags != 0) - MoveToPollList(&mIdleList[i]); - } + PRBool pollError = PR_FALSE; - LOG((" calling PR_Poll [active=%u idle=%u]\n", mActiveCount, mIdleCount)); - - // Measures seconds spent while blocked on PR_Poll - PRUint32 pollInterval; - - PRInt32 n = Poll(&pollInterval); - if (n < 0) { - LOG((" PR_Poll error [%d]\n", PR_GetError())); - active = PR_FALSE; - } + // + // walk active list backwards to see if any sockets should actually be + // idle, then walk the idle list backwards to see if any idle sockets + // should become active. take care to check only idle sockets that + // were idle to begin with ;-) + // + count = mIdleCount; + for (i=mActiveCount-1; i>=0; --i) { + //--- + LOG((" active [%u] { handler=%x condition=%x pollflags=%hu }\n", i, + mActiveList[i].mHandler, + mActiveList[i].mHandler->mCondition, + mActiveList[i].mHandler->mPollFlags)); + //--- + if (NS_FAILED(mActiveList[i].mHandler->mCondition)) + DetachSocket(&mActiveList[i]); else { - // - // service "active" sockets... - // - for (i=0; i 0 && desc.out_flags != 0) { - s.mElapsedTime = 0; - s.mHandler->OnSocketReady(desc.fd, desc.out_flags); - } - // check for timeout errors unless disabled... - else if (s.mHandler->mPollTimeout != PR_UINT16_MAX) { - // update elapsed time counter - if (NS_UNLIKELY(pollInterval > (PR_UINT16_MAX - s.mElapsedTime))) - s.mElapsedTime = PR_UINT16_MAX; - else - s.mElapsedTime += PRUint16(pollInterval); - // check for timeout expiration - if (s.mElapsedTime >= s.mHandler->mPollTimeout) { - s.mElapsedTime = 0; - s.mHandler->OnSocketReady(desc.fd, -1); - } - } - } - - // - // check for "dead" sockets and remove them (need to do this in - // reverse order obviously). - // - for (i=mActiveCount-1; i>=0; --i) { - if (NS_FAILED(mActiveList[i].mHandler->mCondition)) - DetachSocket(&mActiveList[i]); - } - - // - // service the event queue (mPollList[0].fd == mThreadEvent) - // - if (n == 0) - active = ServiceEventQ(); - else if (mPollList[0].out_flags == PR_POLL_READ) { - // acknowledge pollable event (wait should not block) - PR_WaitForPollableEvent(mThreadEvent); - active = ServiceEventQ(); + PRUint16 in_flags = mActiveList[i].mHandler->mPollFlags; + if (in_flags == 0) + MoveToIdleList(&mActiveList[i]); + else { + // update poll flags + mPollList[i+1].in_flags = in_flags; + mPollList[i+1].out_flags = 0; } } } + for (i=count-1; i>=0; --i) { + //--- + LOG((" idle [%u] { handler=%x condition=%x pollflags=%hu }\n", i, + mIdleList[i].mHandler, + mIdleList[i].mHandler->mCondition, + mIdleList[i].mHandler->mPollFlags)); + //--- + if (NS_FAILED(mIdleList[i].mHandler->mCondition)) + DetachSocket(&mIdleList[i]); + else if (mIdleList[i].mHandler->mPollFlags != 0) + MoveToPollList(&mIdleList[i]); + } - // - // shutdown thread - // - - LOG(("shutting down socket transport thread...\n")); + LOG((" calling PR_Poll [active=%u idle=%u]\n", mActiveCount, mIdleCount)); - mShuttingDown = PR_TRUE; + // Measures seconds spent while blocked on PR_Poll + PRUint32 pollInterval; - // detach any sockets - for (i=mActiveCount-1; i>=0; --i) - DetachSocket(&mActiveList[i]); - for (i=mIdleCount-1; i>=0; --i) - DetachSocket(&mIdleList[i]); + PRInt32 n = Poll(wait, &pollInterval); + if (n < 0) { + LOG((" PR_Poll error [%d]\n", PR_GetError())); + pollError = PR_TRUE; + } + else { + // + // service "active" sockets... + // + for (i=0; i 0 && desc.out_flags != 0) { + s.mElapsedTime = 0; + s.mHandler->OnSocketReady(desc.fd, desc.out_flags); + } + // check for timeout errors unless disabled... + else if (s.mHandler->mPollTimeout != PR_UINT16_MAX) { + // update elapsed time counter + if (NS_UNLIKELY(pollInterval > (PR_UINT16_MAX - s.mElapsedTime))) + s.mElapsedTime = PR_UINT16_MAX; + else + s.mElapsedTime += PRUint16(pollInterval); + // check for timeout expiration + if (s.mElapsedTime >= s.mHandler->mPollTimeout) { + s.mElapsedTime = 0; + s.mHandler->OnSocketReady(desc.fd, -1); + } + } + } - mShuttingDown = PR_FALSE; + // + // check for "dead" sockets and remove them (need to do this in + // reverse order obviously). + // + for (i=mActiveCount-1; i>=0; --i) { + if (NS_FAILED(mActiveList[i].mHandler->mCondition)) + DetachSocket(&mActiveList[i]); + } - // Final pass over the event queue. This makes sure that events posted by - // socket detach handlers get processed. - ServiceEventQ(); + if (n != 0 && mPollList[0].out_flags == PR_POLL_READ) { + // acknowledge pollable event (wait should not block) + PR_WaitForPollableEvent(mThreadEvent); + } + } - gSocketThread = nsnull; return NS_OK; } diff --git a/mozilla/netwerk/base/src/nsSocketTransportService2.h b/mozilla/netwerk/base/src/nsSocketTransportService2.h index cd13f3c8df9..3d268c58738 100644 --- a/mozilla/netwerk/base/src/nsSocketTransportService2.h +++ b/mozilla/netwerk/base/src/nsSocketTransportService2.h @@ -1,3 +1,4 @@ +/* vim:set ts=4 sw=4 sts=4 ci et: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -39,9 +40,9 @@ #define nsSocketTransportService2_h__ #include "nsPISocketTransportService.h" -#include "nsIEventTarget.h" -#include "nsIRunnable.h" -#include "nsIThread.h" +#include "nsIThreadInternal.h" +#include "nsThreadUtils.h" +#include "nsEventQueue.h" #include "nsCOMPtr.h" #include "pldhash.h" #include "prinrval.h" @@ -125,6 +126,7 @@ public: class nsSocketTransportService : public nsPISocketTransportService , public nsIEventTarget + , public nsIThreadObserver , public nsIRunnable { public: @@ -132,6 +134,7 @@ public: NS_DECL_NSPISOCKETTRANSPORTSERVICE NS_DECL_NSISOCKETTRANSPORTSERVICE NS_DECL_NSIEVENTTARGET + NS_DECL_NSITHREADOBSERVER NS_DECL_NSIRUNNABLE nsSocketTransportService(); @@ -143,15 +146,17 @@ public: // AttachSocket will fail if the limit is exceeded. consumers should // call CanAttachSocket and check the result before creating a socket. // - PRBool CanAttachSocket() { return mActiveCount + mIdleCount < NS_SOCKET_MAX_COUNT; } + PRBool CanAttachSocket() { + return mActiveCount + mIdleCount < NS_SOCKET_MAX_COUNT; + } // - // if the number of sockets is at the limit, then consumers can be notified - // when the number of sockets becomes less than the limit. the notification - // is asynchronous, delivered via the given PLEvent instance on the socket - // transport thread. + // if the number of sockets reaches the limit, then consumers can be + // notified when the number of sockets becomes less than the limit. the + // notification is asynchronous, delivered via the given nsIRunnable + // instance on the socket transport thread. // - nsresult NotifyWhenCanAttachSocket(PLEvent *); + nsresult NotifyWhenCanAttachSocket(nsIRunnable *); // // add a new socket to the list of controlled sockets. returns a socket @@ -173,25 +178,20 @@ private: // misc (any thread) //------------------------------------------------------------------------- - PRBool mInitialized; nsIThread *mThread; PRFileDesc *mThreadEvent; - - // pref to control autodial code PRBool mAutodialEnabled; + // pref to control autodial code //------------------------------------------------------------------------- - // misc (socket thread only) + // initialization and shutdown (any thread) //------------------------------------------------------------------------- - // indicates whether we are currently in the process of shutting down + + PRLock *mLock; + PRBool mInitialized; PRBool mShuttingDown; - - //------------------------------------------------------------------------- - // event queue (any thread) - //------------------------------------------------------------------------- - - PRCList mEventQ; // list of PLEvent objects - PRLock *mEventQLock; + // indicates whether we are currently in the + // process of shutting down //------------------------------------------------------------------------- // socket lists (socket thread only) @@ -225,9 +225,6 @@ private: void MoveToIdleList(SocketContext *sock); void MoveToPollList(SocketContext *sock); - // returns PR_FALSE to stop processing the main loop - PRBool ServiceEventQ(); - //------------------------------------------------------------------------- // poll list (socket thread only) // @@ -238,7 +235,10 @@ private: PRPollDesc mPollList[ NS_SOCKET_MAX_COUNT + 1 ]; PRIntervalTime PollTimeout(); // computes ideal poll timeout - PRInt32 Poll(PRUint32 *interval); // calls PR_Poll. the out param + nsresult DoPollIteration(PRBool wait); + // perfoms a single poll iteration + PRInt32 Poll(PRBool wait, PRUint32 *interval); + // calls PR_Poll. the out param // interval indicates the poll // duration in seconds. @@ -246,7 +246,7 @@ private: // pending socket queue - see NotifyWhenCanAttachSocket //------------------------------------------------------------------------- - PRCList mPendingSocketQ; // list of PLEvent objects + nsEventQueue mPendingSocketQ; // queue of nsIRunnable objects }; extern nsSocketTransportService *gSocketTransportService; diff --git a/mozilla/netwerk/base/src/nsStreamTransportService.cpp b/mozilla/netwerk/base/src/nsStreamTransportService.cpp index 02983999a06..a7023224cb3 100644 --- a/mozilla/netwerk/base/src/nsStreamTransportService.cpp +++ b/mozilla/netwerk/base/src/nsStreamTransportService.cpp @@ -51,8 +51,7 @@ #include "nsIPipe.h" #include "nsITransport.h" #include "nsIRunnable.h" -#include "nsIProxyObjectManager.h" -#include "nsIEventTarget.h" +#include "nsIObserverService.h" //----------------------------------------------------------------------------- // nsInputStreamTransport @@ -120,7 +119,7 @@ nsInputStreamTransport::OpenInputStream(PRUint32 flags, nsresult rv; nsCOMPtr target = - do_GetService(NS_IOTHREADPOOL_CONTRACTID, &rv); + do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; // XXX if the caller requests an unbuffered stream, then perhaps @@ -333,7 +332,7 @@ nsOutputStreamTransport::OpenOutputStream(PRUint32 flags, nsresult rv; nsCOMPtr target = - do_GetService(NS_IOTHREADPOOL_CONTRACTID, &rv); + do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; // XXX if the caller requests an unbuffered stream, then perhaps @@ -468,7 +467,47 @@ nsOutputStreamTransport::IsNonBlocking(PRBool *result) // nsStreamTransportService //----------------------------------------------------------------------------- -NS_IMPL_THREADSAFE_ISUPPORTS1(nsStreamTransportService, nsIStreamTransportService) +nsStreamTransportService::~nsStreamTransportService() +{ + NS_ASSERTION(!mPool, "thread pool wasn't shutdown"); +} + +nsresult +nsStreamTransportService::Init() +{ + mPool = do_CreateInstance(NS_THREADPOOL_CONTRACTID); + NS_ENSURE_STATE(mPool); + + // Configure the pool + mPool->SetThreadLimit(4); + mPool->SetIdleThreadLimit(1); + mPool->SetIdleThreadTimeout(PR_SecondsToInterval(60)); + + nsCOMPtr obsSvc = + do_GetService("@mozilla.org/observer-service;1"); + if (obsSvc) + obsSvc->AddObserver(this, "xpcom-shutdown-threads", PR_FALSE); + return NS_OK; +} + +NS_IMPL_THREADSAFE_ISUPPORTS3(nsStreamTransportService, + nsIStreamTransportService, + nsIEventTarget, + nsIObserver) + +NS_IMETHODIMP +nsStreamTransportService::Dispatch(nsIRunnable *task, PRUint32 flags) +{ + NS_ENSURE_TRUE(mPool, NS_ERROR_NOT_INITIALIZED); + return mPool->Dispatch(task, flags); +} + +NS_IMETHODIMP +nsStreamTransportService::IsOnCurrentThread(PRBool *result) +{ + NS_ENSURE_TRUE(mPool, NS_ERROR_NOT_INITIALIZED); + return mPool->IsOnCurrentThread(result); +} NS_IMETHODIMP nsStreamTransportService::CreateInputTransport(nsIInputStream *stream, @@ -499,3 +538,16 @@ nsStreamTransportService::CreateOutputTransport(nsIOutputStream *stream, NS_ADDREF(*result = trans); return NS_OK; } + +NS_IMETHODIMP +nsStreamTransportService::Observe(nsISupports *subject, const char *topic, + const PRUnichar *data) +{ + NS_ASSERTION(strcmp(topic, "xpcom-shutdown-threads") == 0, "oops"); + + if (mPool) { + mPool->Shutdown(); + mPool = nsnull; + } + return NS_OK; +} diff --git a/mozilla/netwerk/base/src/nsStreamTransportService.h b/mozilla/netwerk/base/src/nsStreamTransportService.h index b467115108b..4dac770ecf1 100644 --- a/mozilla/netwerk/base/src/nsStreamTransportService.h +++ b/mozilla/netwerk/base/src/nsStreamTransportService.h @@ -36,13 +36,27 @@ * ***** END LICENSE BLOCK ***** */ #include "nsIStreamTransportService.h" +#include "nsIEventTarget.h" +#include "nsIThreadPool.h" +#include "nsIObserver.h" +#include "nsCOMPtr.h" class nsStreamTransportService : public nsIStreamTransportService + , public nsIEventTarget + , public nsIObserver { public: NS_DECL_ISUPPORTS NS_DECL_NSISTREAMTRANSPORTSERVICE + NS_DECL_NSIEVENTTARGET + NS_DECL_NSIOBSERVER + + nsresult Init(); nsStreamTransportService() {} - virtual ~nsStreamTransportService() {} + +private: + ~nsStreamTransportService(); + + nsCOMPtr mPool; }; diff --git a/mozilla/netwerk/base/src/nsSyncStreamListener.cpp b/mozilla/netwerk/base/src/nsSyncStreamListener.cpp index 76a88b0723b..28479cd3aa4 100644 --- a/mozilla/netwerk/base/src/nsSyncStreamListener.cpp +++ b/mozilla/netwerk/base/src/nsSyncStreamListener.cpp @@ -36,7 +36,6 @@ #include "nsSyncStreamListener.h" #include "nsIPipe.h" -#include "nsEventQueueUtils.h" #include "nsNetSegmentUtils.h" nsresult @@ -55,19 +54,15 @@ nsSyncStreamListener::WaitForData() { nsresult rv; - if (!mEventQ) { - rv = NS_GetCurrentEventQ(getter_AddRefs(mEventQ)); + if (!mThread) { + rv = NS_GetCurrentThread(getter_AddRefs(mThread)); if (NS_FAILED(rv)) return rv; } mKeepWaiting = PR_TRUE; - PLEvent *ev; while (mKeepWaiting) { - rv = mEventQ->WaitForEvent(&ev); - if (NS_FAILED(rv)) return rv; - - rv = mEventQ->HandleEvent(ev); + rv = mThread->ProcessNextEvent(); if (NS_FAILED(rv)) return rv; } diff --git a/mozilla/netwerk/base/src/nsSyncStreamListener.h b/mozilla/netwerk/base/src/nsSyncStreamListener.h index ecfd65f13f9..eeb0eee0f84 100644 --- a/mozilla/netwerk/base/src/nsSyncStreamListener.h +++ b/mozilla/netwerk/base/src/nsSyncStreamListener.h @@ -40,7 +40,7 @@ #include "nsISyncStreamListener.h" #include "nsIInputStream.h" #include "nsIOutputStream.h" -#include "nsIEventQueue.h" +#include "nsThreadUtils.h" #include "nsCOMPtr.h" //----------------------------------------------------------------------------- @@ -59,17 +59,17 @@ public: : mStatus(NS_OK) , mKeepWaiting(PR_FALSE) , mDone(PR_FALSE) {} - virtual ~nsSyncStreamListener() {} nsresult Init(); private: + ~nsSyncStreamListener() {} nsresult WaitForData(); nsCOMPtr mPipeIn; nsCOMPtr mPipeOut; - nsCOMPtr mEventQ; + nsCOMPtr mThread; nsresult mStatus; PRPackedBool mKeepWaiting; PRPackedBool mDone; diff --git a/mozilla/netwerk/base/src/nsTransportUtils.cpp b/mozilla/netwerk/base/src/nsTransportUtils.cpp index fb325b048a9..529a8d5e380 100644 --- a/mozilla/netwerk/base/src/nsTransportUtils.cpp +++ b/mozilla/netwerk/base/src/nsTransportUtils.cpp @@ -36,11 +36,11 @@ #include "nsTransportUtils.h" #include "nsITransport.h" -#include "nsIEventTarget.h" #include "nsProxyRelease.h" +#include "nsThreadUtils.h" #include "nsAutoLock.h" +#include "nsAutoPtr.h" #include "nsCOMPtr.h" -#include "plevent.h" //----------------------------------------------------------------------------- @@ -81,7 +81,7 @@ public: PRBool mCoalesceAll; }; -class nsTransportStatusEvent : public PLEvent +class nsTransportStatusEvent : public nsRunnable { public: nsTransportStatusEvent(nsTransportEventSinkProxy *proxy, @@ -89,46 +89,31 @@ public: nsresult status, PRUint64 progress, PRUint64 progressMax) - : mTransport(transport) + : mProxy(proxy) + , mTransport(transport) , mStatus(status) , mProgress(progress) , mProgressMax(progressMax) - { - NS_ADDREF(proxy); - PL_InitEvent(this, proxy, HandleEvent, DestroyEvent); - } + {} - ~nsTransportStatusEvent() - { - nsTransportEventSinkProxy *proxy = - (nsTransportEventSinkProxy *) owner; - NS_RELEASE(proxy); - } + ~nsTransportStatusEvent() {} - PR_STATIC_CALLBACK(void*) HandleEvent(PLEvent *event) + NS_IMETHOD Run() { - nsTransportStatusEvent *self = (nsTransportStatusEvent *) event; - nsTransportEventSinkProxy *proxy = (nsTransportEventSinkProxy *) event->owner; - // since this event is being handled, we need to clear the proxy's ref. // if not coalescing all, then last event may not equal self! { - nsAutoLock lock(proxy->mLock); - if (proxy->mLastEvent == self) - proxy->mLastEvent = nsnull; + nsAutoLock lock(mProxy->mLock); + if (mProxy->mLastEvent == this) + mProxy->mLastEvent = nsnull; } - proxy->mSink->OnTransportStatus(self->mTransport, - self->mStatus, - self->mProgress, - self->mProgressMax); + mProxy->mSink->OnTransportStatus(mTransport, mStatus, mProgress, + mProgressMax); return nsnull; } - PR_STATIC_CALLBACK(void) DestroyEvent(PLEvent *event) - { - delete (nsTransportStatusEvent *) event; - } + nsRefPtr mProxy; // parameters to OnTransportStatus nsCOMPtr mTransport; @@ -146,7 +131,7 @@ nsTransportEventSinkProxy::OnTransportStatus(nsITransport *transport, PRUint64 progressMax) { nsresult rv = NS_OK; - PLEvent *event; + nsRefPtr event; { nsAutoLock lock(mLock); @@ -155,21 +140,19 @@ nsTransportEventSinkProxy::OnTransportStatus(nsITransport *transport, mLastEvent->mStatus = status; mLastEvent->mProgress = progress; mLastEvent->mProgressMax = progressMax; - event = nsnull; } else { event = new nsTransportStatusEvent(this, transport, status, progress, progressMax); if (!event) rv = NS_ERROR_OUT_OF_MEMORY; - mLastEvent = (nsTransportStatusEvent *) event; + mLastEvent = event; // weak ref } } if (event) { - rv = mTarget->PostEvent(event); + rv = mTarget->Dispatch(event, NS_DISPATCH_NORMAL); if (NS_FAILED(rv)) { NS_WARNING("unable to post transport status event"); - PL_DestroyEvent(event); nsAutoLock lock(mLock); // cleanup.. don't reference anymore! mLastEvent = nsnull; diff --git a/mozilla/netwerk/build/nsNetCID.h b/mozilla/netwerk/build/nsNetCID.h index a8d10c0b6f8..e8d33c24924 100644 --- a/mozilla/netwerk/build/nsNetCID.h +++ b/mozilla/netwerk/build/nsNetCID.h @@ -61,20 +61,6 @@ #define NS_NETUTIL_CONTRACTID \ "@mozilla.org/network/util;1" -// service implementing nsIEventTarget. events dispatched to this event -// target will be executed on one of necko's background i/o threads. -#define NS_IOTHREADPOOL_CLASSNAME \ - "nsIOThreadPool" -#define NS_IOTHREADPOOL_CONTRACTID \ - "@mozilla.org/network/io-thread-pool;1" -#define NS_IOTHREADPOOL_CID \ -{ /* f1d62b49-5051-48e2-9155-c3509428461e */ \ - 0xf1d62b49, \ - 0x5051, \ - 0x48e2, \ - {0x91, 0x55, 0xc3, 0x50, 0x94, 0x28, 0x46, 0x1e} \ -} - // service implementing nsIProtocolProxyService and nsPIProtocolProxyService. #define NS_PROTOCOLPROXYSERVICE_CLASSNAME \ "nsProtocolProxyService" diff --git a/mozilla/netwerk/build/nsNetModule.cpp b/mozilla/netwerk/build/nsNetModule.cpp index 4270f1dcc2d..b47f2746d9e 100644 --- a/mozilla/netwerk/build/nsNetModule.cpp +++ b/mozilla/netwerk/build/nsNetModule.cpp @@ -49,13 +49,11 @@ #include "nsLoadGroup.h" #include "nsStreamLoader.h" #include "nsUnicharStreamLoader.h" -#include "nsAsyncStreamListener.h" #include "nsFileStreams.h" #include "nsBufferedStreams.h" #include "nsMIMEInputStream.h" #include "nsSOCKSSocketProvider.h" #include "nsCacheService.h" -#include "nsIOThreadPool.h" #include "nsMimeTypes.h" #include "nsNetStrings.h" @@ -81,7 +79,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsDNSService, Init) NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsProtocolProxyService, Init) #include "nsStreamTransportService.h" -NS_GENERIC_FACTORY_CONSTRUCTOR(nsStreamTransportService) +NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsStreamTransportService, Init) #include "nsSocketTransportService2.h" #undef LOG @@ -621,10 +619,6 @@ static const nsModuleComponentInfo gNetModuleInfo[] = { NS_IOSERVICE_CID, NS_NETUTIL_CONTRACTID, nsIOServiceConstructor }, - { NS_IOTHREADPOOL_CLASSNAME, - NS_IOTHREADPOOL_CID, - NS_IOTHREADPOOL_CONTRACTID, - net_NewIOThreadPool }, { NS_STREAMTRANSPORTSERVICE_CLASSNAME, NS_STREAMTRANSPORTSERVICE_CID, NS_STREAMTRANSPORTSERVICE_CONTRACTID, @@ -689,10 +683,6 @@ static const nsModuleComponentInfo gNetModuleInfo[] = { NS_SIMPLESTREAMLISTENER_CID, NS_SIMPLESTREAMLISTENER_CONTRACTID, nsSimpleStreamListenerConstructor }, - { NS_ASYNCSTREAMLISTENER_CLASSNAME, - NS_ASYNCSTREAMLISTENER_CID, - NS_ASYNCSTREAMLISTENER_CONTRACTID, - nsAsyncStreamListener::Create }, { NS_STREAMLISTENERTEE_CLASSNAME, NS_STREAMLISTENERTEE_CID, NS_STREAMLISTENERTEE_CONTRACTID, diff --git a/mozilla/netwerk/cache/src/nsCacheEntry.cpp b/mozilla/netwerk/cache/src/nsCacheEntry.cpp index 82cf9720316..f1f1cad8fb8 100644 --- a/mozilla/netwerk/cache/src/nsCacheEntry.cpp +++ b/mozilla/netwerk/cache/src/nsCacheEntry.cpp @@ -44,6 +44,8 @@ #include "nsCacheEntryDescriptor.h" #include "nsCacheMetaData.h" #include "nsCacheRequest.h" +#include "nsThreadUtils.h" +#include "nsProxyRelease.h" #include "nsError.h" #include "nsICacheService.h" #include "nsCache.h" @@ -85,11 +87,11 @@ nsCacheEntry::~nsCacheEntry() // proxy release of of memory cache nsISupports objects if (!mData) return; - nsISupports * data = mData; - NS_ADDREF(data); // this reference will be owned by the proxy - mData = nsnull; // release our reference before switching threads + nsISupports *data = nsnull; + mData.swap(data); // this reference will be owned by the proxy + // release our reference before switching threads - nsCacheService::ProxyObjectRelease(data, mThread); + NS_ProxyRelease(mThread, data); } @@ -138,6 +140,13 @@ nsCacheEntry::TouchData() } +void +nsCacheEntry::SetThread() +{ + mThread = do_GetCurrentThread(); +} + + void nsCacheEntry::TouchMetaData() { diff --git a/mozilla/netwerk/cache/src/nsCacheEntry.h b/mozilla/netwerk/cache/src/nsCacheEntry.h index 2b19eb7031e..9f886186053 100644 --- a/mozilla/netwerk/cache/src/nsCacheEntry.h +++ b/mozilla/netwerk/cache/src/nsCacheEntry.h @@ -43,6 +43,7 @@ #include "nsICache.h" #include "nsICacheEntryDescriptor.h" +#include "nsIThread.h" #include "nsCacheMetaData.h" #include "nspr.h" @@ -110,7 +111,7 @@ public: void TouchData(); - void SetThread(PRThread *aThread) { mThread = aThread; } + void SetThread(); /** * Meta data accessors @@ -241,7 +242,7 @@ private: nsCacheDevice * mCacheDevice; // 4 nsCOMPtr mSecurityInfo; // nsCOMPtr mData; // - PRThread * mThread; + nsCOMPtr mThread; nsCacheMetaData mMetaData; // 4 PRCList mRequestQ; // 8 PRCList mDescriptorQ; // 8 diff --git a/mozilla/netwerk/cache/src/nsCacheRequest.h b/mozilla/netwerk/cache/src/nsCacheRequest.h index 7015aa6b588..68d6fc336c4 100644 --- a/mozilla/netwerk/cache/src/nsCacheRequest.h +++ b/mozilla/netwerk/cache/src/nsCacheRequest.h @@ -45,7 +45,6 @@ #include "nsCOMPtr.h" #include "nsICache.h" #include "nsICacheListener.h" -#include "nsIEventQueue.h" #include "nsCacheSession.h" @@ -63,7 +62,6 @@ private: : mKey(key), mInfo(0), mListener(listener), - mThread(nsnull), mLock(nsnull), mCondVar(nsnull) { @@ -189,7 +187,7 @@ private: nsCString * mKey; PRUint32 mInfo; nsCOMPtr mListener; - PRThread * mThread; + nsCOMPtr mThread; PRLock * mLock; PRCondVar * mCondVar; }; diff --git a/mozilla/netwerk/cache/src/nsCacheService.cpp b/mozilla/netwerk/cache/src/nsCacheService.cpp index b0899c1c354..d290d35d6e0 100644 --- a/mozilla/netwerk/cache/src/nsCacheService.cpp +++ b/mozilla/netwerk/cache/src/nsCacheService.cpp @@ -56,7 +56,6 @@ #endif #include "nsAutoLock.h" -#include "nsIEventQueue.h" #include "nsIObserverService.h" #include "nsIPrefService.h" #include "nsIPrefBranch.h" @@ -64,6 +63,7 @@ #include "nsILocalFile.h" #include "nsDirectoryServiceDefs.h" #include "nsAppDirectoryServiceDefs.h" +#include "nsThreadUtils.h" #include "nsVoidArray.h" #include "nsDeleteDir.h" #include // for log() @@ -105,7 +105,7 @@ public: virtual ~nsCacheProfilePrefObserver() {} nsresult Install(); - nsresult Remove(); + void Remove(); nsresult ReadPrefs(nsIPrefBranch* branch); PRBool DiskCacheEnabled(); @@ -189,46 +189,31 @@ nsCacheProfilePrefObserver::Install() } -nsresult +void nsCacheProfilePrefObserver::Remove() { - nsresult rv, rv2 = NS_OK; - // remove Observer Service observers - nsCOMPtr observerService = do_GetService("@mozilla.org/observer-service;1", &rv); - if (NS_FAILED(rv)) return rv; - - rv = observerService->RemoveObserver(this, "profile-before-change"); - if (NS_FAILED(rv)) rv2 = rv; - - rv = observerService->RemoveObserver(this, "profile-after-change"); - if (NS_FAILED(rv)) rv2 = rv; - - rv = observerService->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID); - if (NS_FAILED(rv)) rv2 = rv; - + nsCOMPtr obs = + do_GetService("@mozilla.org/observer-service;1"); + if (obs) { + obs->RemoveObserver(this, "profile-before-change"); + obs->RemoveObserver(this, "profile-after-change"); + obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID); + } // remove Pref Service observers - nsCOMPtr prefInternal = do_GetService(NS_PREFSERVICE_CONTRACTID); + nsCOMPtr prefs = + do_GetService(NS_PREFSERVICE_CONTRACTID); + if (prefs) { + // remove Disk cache pref observers + prefs->RemoveObserver(DISK_CACHE_ENABLE_PREF, this); + prefs->RemoveObserver(DISK_CACHE_CAPACITY_PREF, this); + prefs->RemoveObserver(DISK_CACHE_DIR_PREF, this); - // remove Disk cache pref observers - rv = prefInternal->RemoveObserver(DISK_CACHE_ENABLE_PREF, this); - if (NS_FAILED(rv)) rv2 = rv; - - rv = prefInternal->RemoveObserver(DISK_CACHE_CAPACITY_PREF, this); - if (NS_FAILED(rv)) rv2 = rv; - - rv = prefInternal->RemoveObserver(DISK_CACHE_DIR_PREF, this); - if (NS_FAILED(rv)) rv2 = rv; - - // remove Memory cache pref observers - rv = prefInternal->RemoveObserver(MEMORY_CACHE_ENABLE_PREF, this); - if (NS_FAILED(rv)) rv2 = rv; - - rv = prefInternal->RemoveObserver(MEMORY_CACHE_CAPACITY_PREF, this); - // if (NS_FAILED(rv)) rv2 = rv; - - return NS_SUCCEEDED(rv) ? rv2 : rv; + // remove Memory cache pref observers + prefs->RemoveObserver(MEMORY_CACHE_ENABLE_PREF, this); + prefs->RemoveObserver(MEMORY_CACHE_CAPACITY_PREF, this); + } } @@ -532,13 +517,6 @@ nsCacheService::Init() nsresult rv = mActiveEntries.Init(); if (NS_FAILED(rv)) return rv; - // get references to services we'll be using frequently - mEventQService = do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv); - if (NS_FAILED(rv)) return rv; - - mProxyObjectManager = do_GetService(NS_XPCOMPROXY_CONTRACTID, &rv); - if (NS_FAILED(rv)) return rv; - // create profile/preference observer mObserver = new nsCacheProfilePrefObserver(); if (!mObserver) return NS_ERROR_OUT_OF_MEMORY; @@ -651,9 +629,9 @@ nsCacheService::EvictEntriesForClient(const char * clientID, // notification happens before or after the actual eviction. nsCOMPtr obsProxy; - NS_GetProxyForObject(NS_UI_THREAD_EVENTQ, - NS_GET_IID(nsIObserverService), - obsSvc, PROXY_ASYNC, getter_AddRefs(obsProxy)); + NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD, + NS_GET_IID(nsIObserverService), obsSvc, + NS_PROXY_ASYNC, getter_AddRefs(obsProxy)); if (obsProxy) { obsProxy->NotifyObservers(this, @@ -855,7 +833,7 @@ nsCacheService::CreateRequest(nsCacheSession * session, if (!listener) return NS_OK; // we're sync, we're done. // get the nsIEventQueue for the request's thread - (*request)->mThread = PR_GetCurrentThread(); + (*request)->mThread = do_GetCurrentThread(); return NS_OK; } @@ -871,14 +849,12 @@ nsCacheService::NotifyListener(nsCacheRequest * request, nsCOMPtr listenerProxy; NS_ASSERTION(request->mThread, "no thread set in async request!"); - nsCOMPtr eventQ; - mEventQService->GetThreadEventQueue(request->mThread, - getter_AddRefs(eventQ)); - rv = mProxyObjectManager->GetProxyForObject(eventQ, - NS_GET_IID(nsICacheListener), - request->mListener, - PROXY_ASYNC|PROXY_ALWAYS, - getter_AddRefs(listenerProxy)); + + rv = NS_GetProxyForObject(request->mThread, + NS_GET_IID(nsICacheListener), + request->mListener, + NS_PROXY_ASYNC | NS_PROXY_ALWAYS, + getter_AddRefs(listenerProxy)); if (NS_FAILED(rv)) return rv; return listenerProxy->OnCacheEntryAvailable(descriptor, accessGranted, error); @@ -1178,45 +1154,6 @@ nsCacheService::DoomEntry_Internal(nsCacheEntry * entry) } -static void* PR_CALLBACK -EventHandler(PLEvent *self) -{ - nsISupports * object = (nsISupports *)PL_GetEventOwner(self); - NS_RELEASE(object); - return 0; -} - - -static void PR_CALLBACK -DestroyHandler(PLEvent *self) -{ - delete self; -} - - -void -nsCacheService::ProxyObjectRelease(nsISupports * object, PRThread * thread) -{ - NS_ASSERTION(gService, "nsCacheService not initialized"); - NS_ASSERTION(thread, "no thread"); - // XXX if thread == current thread, we could avoid posting an event, - // XXX by add this object to a queue and release it when the cache service is unlocked. - - nsCOMPtr eventQ; - gService->mEventQService->GetThreadEventQueue(thread, getter_AddRefs(eventQ)); - NS_ASSERTION(eventQ, "no event queue for thread"); - if (!eventQ) return; - - PLEvent * event = new PLEvent; - if (!event) { - NS_WARNING("failed to allocate a PLEvent."); - return; - } - PL_InitEvent(event, object, EventHandler, DestroyHandler); - eventQ->PostEvent(event); -} - - void nsCacheService::OnProfileShutdown(PRBool cleanse) { @@ -1413,7 +1350,7 @@ nsCacheService::ServiceLock() nsresult nsCacheService::SetCacheElement(nsCacheEntry * entry, nsISupports * element) { - entry->SetThread(PR_GetCurrentThread()); + entry->SetThread(); entry->SetData(element); entry->TouchData(); return NS_OK; diff --git a/mozilla/netwerk/cache/src/nsCacheService.h b/mozilla/netwerk/cache/src/nsCacheService.h index 4c7e4e3e6dd..c1eff46f341 100644 --- a/mozilla/netwerk/cache/src/nsCacheService.h +++ b/mozilla/netwerk/cache/src/nsCacheService.h @@ -52,7 +52,6 @@ #include "nspr.h" #include "nsIObserver.h" #include "nsString.h" -#include "nsIEventQueueService.h" #include "nsProxiedService.h" class nsCacheRequest; @@ -131,8 +130,6 @@ public: static nsresult DoomEntry(nsCacheEntry * entry); - static void ProxyObjectRelease(nsISupports * object, PRThread * thread); - static PRBool IsStorageEnabledForPolicy_Locked(nsCacheStoragePolicy policy); /** @@ -212,8 +209,6 @@ private: */ static nsCacheService * gService; // there can be only one... - nsCOMPtr mEventQService; - nsCOMPtr mProxyObjectManager; nsCacheProfilePrefObserver * mObserver; diff --git a/mozilla/netwerk/dns/public/nsIDNSService.idl b/mozilla/netwerk/dns/public/nsIDNSService.idl index 151f6b9a044..d7d5e135c2b 100644 --- a/mozilla/netwerk/dns/public/nsIDNSService.idl +++ b/mozilla/netwerk/dns/public/nsIDNSService.idl @@ -46,7 +46,7 @@ interface nsIDNSListener; /** * nsIDNSService */ -[scriptable, uuid(5c8ec09d-bfbf-4eaf-8a36-0d84b5c8f35b)] +[scriptable, uuid(3ac9e611-e6b6-44b5-b312-c040e65b2929)] interface nsIDNSService : nsISupports { /** @@ -58,19 +58,19 @@ interface nsIDNSService : nsISupports * a bitwise OR of the RESOLVE_ prefixed constants defined below. * @param aListener * the listener to be notified when the result is available. - * @param aListenerEventTarget + * @param aListenerTarget * optional parameter (may be null). if non-null, this parameter - * specifies the nsIEventTarget of the thread on which the listener's - * onLookupComplete should be called. however, if this parameter is - * null, then onLookupComplete will be called on an unspecified - * thread (possibly recursively). + * specifies the nsIEventTarget of the thread on which the + * listener's onLookupComplete should be called. however, if this + * parameter is null, then onLookupComplete will be called on an + * unspecified thread (possibly recursively). * * @return An object that can be used to cancel the host lookup. */ - nsICancelable asyncResolve(in AUTF8String aHostName, - in unsigned long aFlags, - in nsIDNSListener aListener, - in nsIEventTarget aListenerEventTarget); + nsICancelable asyncResolve(in AUTF8String aHostName, + in unsigned long aFlags, + in nsIDNSListener aListener, + in nsIEventTarget aListenerTarget); /** * called to synchronously resolve a hostname. warning this method may diff --git a/mozilla/netwerk/dns/src/nsDNSService2.cpp b/mozilla/netwerk/dns/src/nsDNSService2.cpp index c6aaefcaff1..d11292479aa 100644 --- a/mozilla/netwerk/dns/src/nsDNSService2.cpp +++ b/mozilla/netwerk/dns/src/nsDNSService2.cpp @@ -326,11 +326,13 @@ nsDNSService::Init() return NS_ERROR_OUT_OF_MEMORY; // register as prefs observer - prefs->AddObserver(kPrefDnsCacheEntries, this, PR_FALSE); - prefs->AddObserver(kPrefDnsCacheExpiration, this, PR_FALSE); - prefs->AddObserver(kPrefEnableIDN, this, PR_FALSE); - prefs->AddObserver(kPrefIPv4OnlyDomains, this, PR_FALSE); - prefs->AddObserver(kPrefDisableIPv6, this, PR_FALSE); + if (prefs) { + prefs->AddObserver(kPrefDnsCacheEntries, this, PR_FALSE); + prefs->AddObserver(kPrefDnsCacheExpiration, this, PR_FALSE); + prefs->AddObserver(kPrefEnableIDN, this, PR_FALSE); + prefs->AddObserver(kPrefIPv4OnlyDomains, this, PR_FALSE); + prefs->AddObserver(kPrefDisableIPv6, this, PR_FALSE); + } } // we have to null out mIDN since we might be getting re-initialized @@ -370,11 +372,11 @@ nsDNSService::Shutdown() } NS_IMETHODIMP -nsDNSService::AsyncResolve(const nsACString &hostname, - PRUint32 flags, - nsIDNSListener *listener, - nsIEventTarget *eventTarget, - nsICancelable **result) +nsDNSService::AsyncResolve(const nsACString &hostname, + PRUint32 flags, + nsIDNSListener *listener, + nsIEventTarget *target, + nsICancelable **result) { // grab reference to global host resolver and IDN service. beware // simultaneous shutdown!! @@ -397,13 +399,11 @@ nsDNSService::AsyncResolve(const nsACString &hostname, } nsCOMPtr listenerProxy; - nsCOMPtr eventQ = do_QueryInterface(eventTarget); - // TODO(darin): make XPCOM proxies support any nsIEventTarget impl - if (eventQ) { - rv = NS_GetProxyForObject(eventQ, + if (target) { + rv = NS_GetProxyForObject(target, NS_GET_IID(nsIDNSListener), listener, - PROXY_ASYNC | PROXY_ALWAYS, + NS_PROXY_ASYNC | NS_PROXY_ALWAYS, getter_AddRefs(listenerProxy)); if (NS_FAILED(rv)) return rv; listener = listenerProxy; diff --git a/mozilla/netwerk/protocol/file/src/nsFileChannel.cpp b/mozilla/netwerk/protocol/file/src/nsFileChannel.cpp index f613b1745cf..b82caef39d3 100644 --- a/mozilla/netwerk/protocol/file/src/nsFileChannel.cpp +++ b/mozilla/netwerk/protocol/file/src/nsFileChannel.cpp @@ -40,7 +40,7 @@ #include "nsFileChannel.h" #include "nsBaseContentStream.h" #include "nsDirectoryIndexStream.h" -#include "nsEventQueueUtils.h" +#include "nsThreadUtils.h" #include "nsTransportUtils.h" #include "nsStreamUtils.h" #include "nsURLHelper.h" @@ -54,7 +54,7 @@ //----------------------------------------------------------------------------- -class nsFileCopyEvent : public PLEvent { +class nsFileCopyEvent : public nsRunnable { public: nsFileCopyEvent(nsIOutputStream *dest, nsIInputStream *source, PRInt64 len) : mDest(dest) @@ -62,7 +62,6 @@ public: , mLen(len) , mStatus(NS_OK) , mInterruptStatus(NS_OK) { - PL_InitEvent(this, nsnull, HandleEvent, DestroyEvent); } // Read the current status of the file copy operation. @@ -85,18 +84,12 @@ public: mInterruptStatus = status; } + NS_IMETHOD Run() { + DoCopy(); + return NS_OK; + } + private: - - PR_STATIC_CALLBACK(void *) HandleEvent(PLEvent *ev) { - nsFileCopyEvent *f = NS_STATIC_CAST(nsFileCopyEvent *, ev); - f->DoCopy(); - return nsnull; - } - - PR_STATIC_CALLBACK(void) DestroyEvent(PLEvent *ev) { - // nothing to do - } - nsCOMPtr mCallback; nsCOMPtr mSink; nsCOMPtr mDest; @@ -151,8 +144,10 @@ nsFileCopyEvent::DoCopy() mDest->Close(); // Notify completion - if (mCallback) + if (mCallback) { mCallback->OnOutputStreamReady(nsnull); + mCallback = nsnull; + } } nsresult @@ -173,15 +168,13 @@ nsFileCopyEvent::Dispatch(nsIOutputStreamCallback *callback, if (NS_FAILED(rv)) return rv; - // PostEvent to I/O thread... + // Dispatch ourselves to I/O thread pool... nsCOMPtr pool = - do_GetService(NS_IOTHREADPOOL_CONTRACTID, &rv); + do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; - // We don't have to call PL_DestroyEvent here if PostEvent fails because of - // the way we are allocated. - return pool->PostEvent(this); + return pool->Dispatch(this, NS_DISPATCH_NORMAL); } //----------------------------------------------------------------------------- @@ -201,17 +194,21 @@ public: PRInt64 len, nsITransportEventSink *sink) : nsBaseContentStream(nonBlocking) - , mCopyEvent(dest, source, len) + , mCopyEvent(new nsFileCopyEvent(dest, source, len)) , mSink(sink) { } + PRBool IsInitialized() { + return mCopyEvent != nsnull; + } + NS_IMETHODIMP ReadSegments(nsWriteSegmentFun fun, void *closure, PRUint32 count, PRUint32 *result); NS_IMETHODIMP AsyncWait(nsIInputStreamCallback *callback, PRUint32 flags, PRUint32 count, nsIEventTarget *target); private: - nsFileCopyEvent mCopyEvent; + nsRefPtr mCopyEvent; nsCOMPtr mSink; }; @@ -236,8 +233,8 @@ nsFileUploadContentStream::ReadSegments(nsWriteSegmentFun fun, void *closure, } // Perform copy synchronously, and then close out the stream. - mCopyEvent.DoCopy(); - nsresult status = mCopyEvent.Status(); + mCopyEvent->DoCopy(); + nsresult status = mCopyEvent->Status(); CloseWithStatus(NS_FAILED(status) ? status : NS_BASE_STREAM_CLOSED); return status; } @@ -252,7 +249,7 @@ nsFileUploadContentStream::AsyncWait(nsIInputStreamCallback *callback, return rv; if (IsNonBlocking()) - mCopyEvent.Dispatch(this, mSink, target); + mCopyEvent->Dispatch(this, mSink, target); return NS_OK; } @@ -261,7 +258,7 @@ NS_IMETHODIMP nsFileUploadContentStream::OnOutputStreamReady(nsIAsyncOutputStream *unused) { // This method is being called to indicate that we are done copying. - nsresult status = mCopyEvent.Status(); + nsresult status = mCopyEvent->Status(); CloseWithStatus(NS_FAILED(status) ? status : NS_BASE_STREAM_CLOSED); return NS_OK; @@ -325,10 +322,12 @@ nsFileChannel::OpenContentStream(PRBool async, nsIInputStream **result) if (NS_FAILED(rv)) return rv; - stream = new nsFileUploadContentStream(async, fileStream, mUploadStream, - mUploadLength, this); - if (!stream) + nsFileUploadContentStream *uploadStream = + new nsFileUploadContentStream(async, fileStream, mUploadStream, + mUploadLength, this); + if (!uploadStream || !uploadStream->IsInitialized()) return NS_ERROR_OUT_OF_MEMORY; + stream = uploadStream; SetContentLength64(0); diff --git a/mozilla/netwerk/protocol/ftp/src/nsFTPChannel.cpp b/mozilla/netwerk/protocol/ftp/src/nsFTPChannel.cpp index 470cbc7a6d6..8cf9c27e5e8 100644 --- a/mozilla/netwerk/protocol/ftp/src/nsFTPChannel.cpp +++ b/mozilla/netwerk/protocol/ftp/src/nsFTPChannel.cpp @@ -41,6 +41,7 @@ #include "nsIStreamListener.h" #include "nsIServiceManager.h" +#include "nsThreadUtils.h" #include "nsNetUtil.h" #include "nsMimeTypes.h" #include "nsIProxyObjectManager.h" @@ -175,12 +176,13 @@ nsFtpChannel::GetFTPEventSink(nsCOMPtr &aResult) if (!mFTPEventSink) { nsCOMPtr ftpSink; GetCallback(ftpSink); - if (ftpSink) - NS_GetProxyForObject(NS_CURRENT_EVENTQ, + if (ftpSink) { + NS_GetProxyForObject(NS_PROXY_TO_CURRENT_THREAD, NS_GET_IID(nsIFTPEventSink), ftpSink, - PROXY_ASYNC | PROXY_ALWAYS, + NS_PROXY_ASYNC | NS_PROXY_ALWAYS, getter_AddRefs(mFTPEventSink)); + } } aResult = mFTPEventSink; } diff --git a/mozilla/netwerk/protocol/ftp/src/nsFtpConnectionThread.cpp b/mozilla/netwerk/protocol/ftp/src/nsFtpConnectionThread.cpp index a89d0e865f1..5c20b7206b7 100644 --- a/mozilla/netwerk/protocol/ftp/src/nsFtpConnectionThread.cpp +++ b/mozilla/netwerk/protocol/ftp/src/nsFtpConnectionThread.cpp @@ -56,7 +56,7 @@ #include "nsEscape.h" #include "nsMimeTypes.h" #include "nsNetUtil.h" -#include "nsEventQueueUtils.h" +#include "nsThreadUtils.h" #include "nsStreamUtils.h" #include "nsIURL.h" #include "nsISocketTransport.h" @@ -1445,11 +1445,10 @@ nsFtpState::R_pasv() { LOG(("FTP:(%x) created DT (%s:%x)\n", this, hostStr, port)); // hook ourself up as a proxy for status notifications - nsCOMPtr eventQ; - rv = NS_GetCurrentEventQ(getter_AddRefs(eventQ)); - NS_ENSURE_SUCCESS(rv, FTP_ERROR); + nsCOMPtr thread = do_GetCurrentThread(); + NS_ENSURE_TRUE(thread, FTP_ERROR); - rv = mDataTransport->SetEventSink(this, eventQ); + rv = mDataTransport->SetEventSink(this, thread); NS_ENSURE_SUCCESS(rv, FTP_ERROR); if (mAction == PUT) { @@ -1623,11 +1622,10 @@ nsFtpState::OpenCacheDataStream() getter_AddRefs(transport)); NS_ENSURE_STATE(transport); - nsCOMPtr eventQ; - NS_GetCurrentEventQ(getter_AddRefs(eventQ)); - NS_ENSURE_STATE(eventQ); + nsCOMPtr thread = do_GetCurrentThread(); + NS_ENSURE_STATE(thread); - nsresult rv = transport->SetEventSink(this, eventQ); + nsresult rv = transport->SetEventSink(this, thread); NS_ENSURE_SUCCESS(rv, rv); // Open a non-blocking, buffered input stream... diff --git a/mozilla/netwerk/protocol/ftp/src/nsFtpConnectionThread.h b/mozilla/netwerk/protocol/ftp/src/nsFtpConnectionThread.h index 31c20318b53..b650a3169a3 100644 --- a/mozilla/netwerk/protocol/ftp/src/nsFtpConnectionThread.h +++ b/mozilla/netwerk/protocol/ftp/src/nsFtpConnectionThread.h @@ -61,7 +61,6 @@ #include "nsIOutputStream.h" #include "nsAutoLock.h" #include "nsAutoPtr.h" -#include "nsIEventQueueService.h" #include "nsIPrompt.h" #include "nsIAuthPrompt.h" #include "nsITransport.h" diff --git a/mozilla/netwerk/protocol/ftp/src/nsFtpControlConnection.cpp b/mozilla/netwerk/protocol/ftp/src/nsFtpControlConnection.cpp index cf16e12367c..5fedfaf2f01 100644 --- a/mozilla/netwerk/protocol/ftp/src/nsFtpControlConnection.cpp +++ b/mozilla/netwerk/protocol/ftp/src/nsFtpControlConnection.cpp @@ -44,7 +44,7 @@ #include "nsISocketTransportService.h" #include "nsISocketTransport.h" #include "nsNetUtil.h" -#include "nsEventQueueUtils.h" +#include "nsThreadUtils.h" #include "nsCRT.h" #if defined(PR_LOGGING) @@ -137,10 +137,9 @@ nsFtpControlConnection::Connect(nsIProxyInfo* proxyInfo, // proxy transport events back to current thread if (eventSink) { - nsCOMPtr eventQ; - rv = NS_GetCurrentEventQ(getter_AddRefs(eventQ)); - if (NS_SUCCEEDED(rv)) - mSocket->SetEventSink(eventSink, eventQ); + nsCOMPtr thread = do_GetCurrentThread(); + if (thread) + mSocket->SetEventSink(eventSink, thread); } // open buffered, blocking output stream to socket. so long as commands @@ -177,12 +176,11 @@ nsFtpControlConnection::WaitData(nsFtpControlConnectionListener *listener) NS_ENSURE_STATE(mSocketInput); - nsCOMPtr eventQ; - NS_GetCurrentEventQ(getter_AddRefs(eventQ)); - NS_ENSURE_STATE(eventQ); + nsCOMPtr thread = do_GetCurrentThread(); + NS_ENSURE_STATE(thread); mListener = listener; - return mSocketInput->AsyncWait(this, 0, 0, eventQ); + return mSocketInput->AsyncWait(this, 0, 0, thread); } nsresult diff --git a/mozilla/netwerk/protocol/gopher/src/nsGopherChannel.cpp b/mozilla/netwerk/protocol/gopher/src/nsGopherChannel.cpp index 1e90f11b861..f03dcf5cd16 100644 --- a/mozilla/netwerk/protocol/gopher/src/nsGopherChannel.cpp +++ b/mozilla/netwerk/protocol/gopher/src/nsGopherChannel.cpp @@ -49,7 +49,8 @@ #include "nsIStringBundle.h" #include "nsITXTToHTMLConv.h" #include "nsIPrompt.h" -#include "nsEventQueueUtils.h" +#include "nsServiceManagerUtils.h" +#include "nsThreadUtils.h" #include "nsStreamUtils.h" #include "nsMimeTypes.h" #include "nsNetCID.h" diff --git a/mozilla/netwerk/protocol/http/src/nsHttpChannel.cpp b/mozilla/netwerk/protocol/http/src/nsHttpChannel.cpp index 1d4c41173fe..5d345e9e0c9 100644 --- a/mozilla/netwerk/protocol/http/src/nsHttpChannel.cpp +++ b/mozilla/netwerk/protocol/http/src/nsHttpChannel.cpp @@ -292,48 +292,18 @@ nsHttpChannel::Init(nsIURI *uri, nsresult nsHttpChannel::AsyncCall(nsAsyncCallback funcPtr) { - nsresult rv; - - nsAsyncCallEvent *event = new nsAsyncCallEvent; + nsCOMPtr event = new nsAsyncCallEvent(this, funcPtr); if (!event) return NS_ERROR_OUT_OF_MEMORY; - event->mFuncPtr = funcPtr; - - NS_ADDREF_THIS(); - - PL_InitEvent(event, this, - nsHttpChannel::AsyncCall_EventHandlerFunc, - nsHttpChannel::AsyncCall_EventCleanupFunc); - - rv = mEventQ->PostEvent(event); - if (NS_FAILED(rv)) { - PL_DestroyEvent(event); - NS_RELEASE_THIS(); - } - return rv; + return mThread->Dispatch(event, NS_DISPATCH_NORMAL); } -void *PR_CALLBACK -nsHttpChannel::AsyncCall_EventHandlerFunc(PLEvent *ev) +NS_IMETHODIMP +nsHttpChannel::nsAsyncCallEvent::Run() { - nsHttpChannel *chan = - NS_STATIC_CAST(nsHttpChannel *, PL_GetEventOwner(ev)); - - nsAsyncCallEvent *ace = (nsAsyncCallEvent *) ev; - nsAsyncCallback funcPtr = ace->mFuncPtr; - - if (chan) { - (chan->*funcPtr)(); - NS_RELEASE(chan); - } - return nsnull; -} - -void PR_CALLBACK -nsHttpChannel::AsyncCall_EventCleanupFunc(PLEvent *ev) -{ - delete (nsAsyncCallEvent *) ev; + (mObj->*mFuncPtr)(); + return NS_OK; } nsresult @@ -427,7 +397,7 @@ nsHttpChannel::AsyncAbort(nsresult status) // create a proxy for the listener.. nsCOMPtr observer; - NS_NewRequestObserverProxy(getter_AddRefs(observer), mListener, mEventQ); + NS_NewRequestObserverProxy(getter_AddRefs(observer), mListener, mThread); if (observer) { observer->OnStartRequest(this, mListenerContext); observer->OnStopRequest(this, mListenerContext, mStatus); @@ -642,7 +612,7 @@ nsHttpChannel::SetupTransaction() nsCOMPtr responseStream; rv = mTransaction->Init(mCaps, mConnectionInfo, &mRequestHead, mUploadStream, mUploadStreamHasHeaders, - mEventQ, callbacks, this, + mThread, callbacks, this, getter_AddRefs(responseStream)); if (NS_FAILED(rv)) return rv; @@ -3353,11 +3323,10 @@ nsHttpChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *context) nsresult rv; - // we want to grab a reference to the calling thread's event queue at - // this point. we will proxy all events back to the current thread via - // this event queue. - if (!mEventQ) { - rv = gHttpHandler->GetCurrentEventQ(getter_AddRefs(mEventQ)); + // we want to grab a reference to the calling thread at this point. we + // will proxy all events back to this thread. + if (!mThread) { + rv = NS_GetCurrentThread(getter_AddRefs(mThread)); if (NS_FAILED(rv)) return rv; } @@ -4158,7 +4127,7 @@ nsHttpChannel::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult st mCallbacks = nsnull; mProgressSink = nsnull; - mEventQ = nsnull; + mThread = nsnull; return NS_OK; } diff --git a/mozilla/netwerk/protocol/http/src/nsHttpChannel.h b/mozilla/netwerk/protocol/http/src/nsHttpChannel.h index 4adbe12ba02..2cc38e84c5c 100644 --- a/mozilla/netwerk/protocol/http/src/nsHttpChannel.h +++ b/mozilla/netwerk/protocol/http/src/nsHttpChannel.h @@ -44,14 +44,14 @@ #include "nsHttpTransaction.h" #include "nsHttpRequestHead.h" #include "nsHttpAuthCache.h" +#include "nsHashPropertyBag.h" #include "nsInputStreamPump.h" -#include "nsXPIDLString.h" +#include "nsThreadUtils.h" +#include "nsString.h" #include "nsAutoPtr.h" #include "nsCOMPtr.h" #include "nsInt64.h" -#include "nsHashPropertyBag.h" - #include "nsIHttpChannel.h" #include "nsIHttpChannelInternal.h" #include "nsIHttpHeaderVisitor.h" @@ -143,9 +143,17 @@ private: // // AsyncCall may be used to call a member function asynchronously. // - struct nsAsyncCallEvent : PLEvent + class nsAsyncCallEvent : public nsRunnable { - nsAsyncCallback mFuncPtr; + public: + nsAsyncCallEvent(nsHttpChannel *obj, nsAsyncCallback func) + : mObj(obj), mFuncPtr(func) {} + + NS_IMETHOD Run(); + + private: + nsRefPtr mObj; + nsAsyncCallback mFuncPtr; }; nsresult AsyncCall(nsAsyncCallback funcPtr); @@ -208,9 +216,6 @@ private: void ClearPasswordManagerEntry(const char *scheme, const char *host, PRInt32 port, const char *realm, const PRUnichar *user); nsresult DoAuthRetry(nsAHttpConnection *); - static void *PR_CALLBACK AsyncCall_EventHandlerFunc(PLEvent *); - static void PR_CALLBACK AsyncCall_EventCleanupFunc(PLEvent *); - private: nsCOMPtr mOriginalURI; nsCOMPtr mURI; @@ -220,11 +225,11 @@ private: nsCOMPtr mLoadGroup; nsCOMPtr mOwner; nsCOMPtr mCallbacks; + nsCOMPtr mThread; nsCOMPtr mProgressSink; nsCOMPtr mUploadStream; nsCOMPtr mReferrer; nsCOMPtr mSecurityInfo; - nsCOMPtr mEventQ; nsCOMPtr mProxyRequest; nsHttpRequestHead mRequestHead; diff --git a/mozilla/netwerk/protocol/http/src/nsHttpConnection.cpp b/mozilla/netwerk/protocol/http/src/nsHttpConnection.cpp index dfa3d6c6bef..0d844aa53ed 100644 --- a/mozilla/netwerk/protocol/http/src/nsHttpConnection.cpp +++ b/mozilla/netwerk/protocol/http/src/nsHttpConnection.cpp @@ -51,7 +51,6 @@ #include "nsNetCID.h" #include "nsAutoLock.h" #include "prmem.h" -#include "plevent.h" #ifdef DEBUG // defined by the socket transport service while active diff --git a/mozilla/netwerk/protocol/http/src/nsHttpConnection.h b/mozilla/netwerk/protocol/http/src/nsHttpConnection.h index df0f2e2ed24..98cd848c776 100644 --- a/mozilla/netwerk/protocol/http/src/nsHttpConnection.h +++ b/mozilla/netwerk/protocol/http/src/nsHttpConnection.h @@ -49,7 +49,6 @@ #include "nsIStreamListener.h" #include "nsISocketTransport.h" -#include "nsIEventTarget.h" #include "nsIAsyncInputStream.h" #include "nsIAsyncOutputStream.h" #include "nsIInterfaceRequestor.h" diff --git a/mozilla/netwerk/protocol/http/src/nsHttpConnectionMgr.cpp b/mozilla/netwerk/protocol/http/src/nsHttpConnectionMgr.cpp index b3739ae1339..2dc38483c0c 100644 --- a/mozilla/netwerk/protocol/http/src/nsHttpConnectionMgr.cpp +++ b/mozilla/netwerk/protocol/http/src/nsHttpConnectionMgr.cpp @@ -112,7 +112,7 @@ nsHttpConnectionMgr::Init(PRUint16 maxConns, nsAutoMonitor mon(mMonitor); // do nothing if already initialized - if (mSTEventTarget) + if (mSocketThreadTarget) return NS_OK; // no need to do any special synchronization here since there cannot be @@ -125,7 +125,7 @@ nsHttpConnectionMgr::Init(PRUint16 maxConns, mMaxRequestDelay = maxRequestDelay; mMaxPipelinedRequests = maxPipelinedRequests; - mSTEventTarget = sts; + mSocketThreadTarget = sts; return rv; } @@ -137,7 +137,7 @@ nsHttpConnectionMgr::Shutdown() nsAutoMonitor mon(mMonitor); // do nothing if already shutdown - if (!mSTEventTarget) + if (!mSocketThreadTarget) return NS_OK; nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgShutdown); @@ -145,7 +145,7 @@ nsHttpConnectionMgr::Shutdown() // release our reference to the STS to prevent further events // from being posted. this is how we indicate that we are // shutting down. - mSTEventTarget = 0; + mSocketThreadTarget = 0; if (NS_FAILED(rv)) { NS_WARNING("unable to post SHUTDOWN message\n"); @@ -163,19 +163,16 @@ nsHttpConnectionMgr::PostEvent(nsConnEventHandler handler, PRInt32 iparam, void nsAutoMonitor mon(mMonitor); nsresult rv; - if (!mSTEventTarget) { + if (!mSocketThreadTarget) { NS_WARNING("cannot post event if not initialized"); rv = NS_ERROR_NOT_INITIALIZED; } else { - PLEvent *event = new nsConnEvent(this, handler, iparam, vparam); + nsRefPtr event = new nsConnEvent(this, handler, iparam, vparam); if (!event) rv = NS_ERROR_OUT_OF_MEMORY; - else { - rv = mSTEventTarget->PostEvent(event); - if (NS_FAILED(rv)) - PL_DestroyEvent(event); - } + else + rv = mSocketThreadTarget->Dispatch(event, NS_DISPATCH_NORMAL); } return rv; } @@ -225,10 +222,10 @@ nsHttpConnectionMgr::PruneDeadConnections() } nsresult -nsHttpConnectionMgr::GetSocketThreadEventTarget(nsIEventTarget **target) +nsHttpConnectionMgr::GetSocketThreadTarget(nsIEventTarget **target) { nsAutoMonitor mon(mMonitor); - NS_IF_ADDREF(*target = mSTEventTarget); + NS_IF_ADDREF(*target = mSocketThreadTarget); return NS_OK; } diff --git a/mozilla/netwerk/protocol/http/src/nsHttpConnectionMgr.h b/mozilla/netwerk/protocol/http/src/nsHttpConnectionMgr.h index 50bdd154b1f..922033222e3 100644 --- a/mozilla/netwerk/protocol/http/src/nsHttpConnectionMgr.h +++ b/mozilla/netwerk/protocol/http/src/nsHttpConnectionMgr.h @@ -43,11 +43,11 @@ #include "nsHttpConnection.h" #include "nsHttpTransaction.h" #include "nsVoidArray.h" +#include "nsThreadUtils.h" #include "nsHashtable.h" +#include "nsAutoPtr.h" #include "prmon.h" -#include "nsIEventTarget.h" - class nsHttpPipeline; //----------------------------------------------------------------------------- @@ -115,7 +115,7 @@ public: // called to get a reference to the socket transport service. the socket // transport service is not available when the connection manager is down. - nsresult GetSocketThreadEventTarget(nsIEventTarget **); + nsresult GetSocketThreadTarget(nsIEventTarget **); // called when a connection is done processing a transaction. if the // connection can be reused then it will be added to the idle list, else @@ -187,9 +187,9 @@ private: // NOTE: these members may be accessed from any thread (use mMonitor) //------------------------------------------------------------------------- - PRInt32 mRef; - PRMonitor *mMonitor; - nsCOMPtr mSTEventTarget; // event target for socket thread + PRInt32 mRef; + PRMonitor *mMonitor; + nsCOMPtr mSocketThreadTarget; // connection limits PRUint16 mMaxConns; @@ -222,44 +222,35 @@ private: // nsConnEvent // - // subclass of PLEvent used to marshall events to the socket transport + // subclass of nsRunnable used to marshall events to the socket transport // thread. this class is used to implement PostEvent. // class nsConnEvent; friend class nsConnEvent; - class nsConnEvent : public PLEvent + class nsConnEvent : public nsRunnable { public: nsConnEvent(nsHttpConnectionMgr *mgr, nsConnEventHandler handler, PRInt32 iparam, void *vparam) - : mHandler(handler) + : mMgr(mgr) + , mHandler(handler) , mIParam(iparam) , mVParam(vparam) - { - NS_ADDREF(mgr); - PL_InitEvent(this, mgr, HandleEvent, DestroyEvent); - } + {} - PR_STATIC_CALLBACK(void*) HandleEvent(PLEvent *event) + NS_IMETHOD Run() { - nsHttpConnectionMgr *mgr = (nsHttpConnectionMgr *) event->owner; - nsConnEvent *self = (nsConnEvent *) event; - nsConnEventHandler handler = self->mHandler; - (mgr->*handler)(self->mIParam, self->mVParam); - NS_RELEASE(mgr); - return nsnull; - } - PR_STATIC_CALLBACK(void) DestroyEvent(PLEvent *event) - { - delete (nsConnEvent *) event; + (mMgr->*mHandler)(mIParam, mVParam); + return NS_OK; } private: - nsConnEventHandler mHandler; - PRInt32 mIParam; - void *mVParam; + nsRefPtr mMgr; + nsConnEventHandler mHandler; + PRInt32 mIParam; + void *mVParam; }; nsresult PostEvent(nsConnEventHandler handler, diff --git a/mozilla/netwerk/protocol/http/src/nsHttpHandler.cpp b/mozilla/netwerk/protocol/http/src/nsHttpHandler.cpp index 50a57687232..14fd8236b06 100644 --- a/mozilla/netwerk/protocol/http/src/nsHttpHandler.cpp +++ b/mozilla/netwerk/protocol/http/src/nsHttpHandler.cpp @@ -92,7 +92,6 @@ static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID); static NS_DEFINE_CID(kStreamConverterServiceCID, NS_STREAMCONVERTERSERVICE_CID); static NS_DEFINE_CID(kCookieServiceCID, NS_COOKIESERVICE_CID); static NS_DEFINE_CID(kCacheServiceCID, NS_CACHESERVICE_CID); -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); static NS_DEFINE_CID(kSocketProviderServiceCID, NS_SOCKETPROVIDERSERVICE_CID); #define UA_PREF_PREFIX "general.useragent." @@ -436,17 +435,6 @@ nsHttpHandler::GetCacheSession(nsCacheStoragePolicy storagePolicy, return NS_OK; } -nsresult -nsHttpHandler::GetCurrentEventQ(nsIEventQueue **result) -{ - if (!mEventQueueService) { - nsresult rv; - mEventQueueService = do_GetService(kEventQueueServiceCID, &rv); - if (NS_FAILED(rv)) return rv; - } - return mEventQueueService->ResolveEventQueue(NS_CURRENT_EVENTQ, result); -} - nsresult nsHttpHandler::GetStreamConverterService(nsIStreamConverterService **result) { diff --git a/mozilla/netwerk/protocol/http/src/nsHttpHandler.h b/mozilla/netwerk/protocol/http/src/nsHttpHandler.h index 882a61b874b..1cd8a0117a4 100644 --- a/mozilla/netwerk/protocol/http/src/nsHttpHandler.h +++ b/mozilla/netwerk/protocol/http/src/nsHttpHandler.h @@ -58,7 +58,6 @@ #include "nsIProxyObjectManager.h" #include "nsIStreamConverterService.h" #include "nsICacheSession.h" -#include "nsIEventQueueService.h" #include "nsICookieService.h" #include "nsIIDNService.h" #include "nsITimer.h" @@ -161,16 +160,15 @@ public: return mConnMgr->ProcessPendingQ(cinfo); } - nsresult GetSocketThreadEventTarget(nsIEventTarget **target) + nsresult GetSocketThreadTarget(nsIEventTarget **target) { - return mConnMgr->GetSocketThreadEventTarget(target); + return mConnMgr->GetSocketThreadTarget(target); } // // The HTTP handler caches pointers to specific XPCOM services, and // provides the following helper routines for accessing those services: // - nsresult GetCurrentEventQ(nsIEventQueue **); nsresult GetStreamConverterService(nsIStreamConverterService **); nsresult GetIOService(nsIIOService** service); nsICookieService * GetCookieService(); // not addrefed @@ -221,7 +219,6 @@ private: // cached services nsCOMPtr mIOService; - nsCOMPtr mEventQueueService; nsCOMPtr mStreamConvSvc; nsCOMPtr mObserverService; nsCOMPtr mCookieService; diff --git a/mozilla/netwerk/protocol/http/src/nsHttpTransaction.cpp b/mozilla/netwerk/protocol/http/src/nsHttpTransaction.cpp index 5655e8e7ae7..56eff5b3e34 100644 --- a/mozilla/netwerk/protocol/http/src/nsHttpTransaction.cpp +++ b/mozilla/netwerk/protocol/http/src/nsHttpTransaction.cpp @@ -46,11 +46,11 @@ #include "nsHttpChunkedDecoder.h" #include "nsNetSegmentUtils.h" #include "nsTransportUtils.h" +#include "nsProxyRelease.h" #include "nsIOService.h" #include "nsNetUtil.h" #include "nsAutoLock.h" #include "pratom.h" -#include "plevent.h" #include "nsISeekableStream.h" #include "nsISocketTransport.h" @@ -132,7 +132,6 @@ nsHttpTransaction::nsHttpTransaction() , mRestartCount(0) , mCaps(0) , mClosed(PR_FALSE) - , mDestroying(PR_FALSE) , mConnected(PR_FALSE) , mHaveStatusLine(PR_FALSE) , mHaveAllHeaders(PR_FALSE) @@ -166,7 +165,7 @@ nsHttpTransaction::Init(PRUint8 caps, nsHttpRequestHead *requestHead, nsIInputStream *requestBody, PRBool requestBodyHasHeaders, - nsIEventQueue *queue, + nsIEventTarget *target, nsIInterfaceRequestor *callbacks, nsITransportEventSink *eventsink, nsIAsyncInputStream **responseBody) @@ -177,16 +176,16 @@ nsHttpTransaction::Init(PRUint8 caps, NS_ASSERTION(cinfo, "ouch"); NS_ASSERTION(requestHead, "ouch"); - NS_ASSERTION(queue, "ouch"); + NS_ASSERTION(target, "ouch"); // create transport event sink proxy that coalesces all events rv = net_NewTransportEventSinkProxy(getter_AddRefs(mTransportSink), - eventsink, queue, PR_TRUE); + eventsink, target, PR_TRUE); if (NS_FAILED(rv)) return rv; NS_ADDREF(mConnInfo = cinfo); mCallbacks = callbacks; - mConsumerEventQ = queue; + mConsumerTarget = target; mCaps = caps; if (requestHead->Method() == nsHttp::Head) @@ -394,7 +393,7 @@ nsHttpTransaction::ReadSegments(nsAHttpSegmentReader *reader, do_QueryInterface(mRequestStream); if (asyncIn) { nsCOMPtr target; - gHttpHandler->GetSocketThreadEventTarget(getter_AddRefs(target)); + gHttpHandler->GetSocketThreadTarget(getter_AddRefs(target)); if (target) asyncIn->AsyncWait(this, 0, 0, target); else { @@ -458,7 +457,7 @@ nsHttpTransaction::WriteSegments(nsAHttpSegmentWriter *writer, // occur on socket thread so we stay synchronized. if (rv == NS_BASE_STREAM_WOULD_BLOCK) { nsCOMPtr target; - gHttpHandler->GetSocketThreadEventTarget(getter_AddRefs(target)); + gHttpHandler->GetSocketThreadTarget(getter_AddRefs(target)); if (target) mPipeOut->AsyncWait(this, 0, 0, target); else { @@ -936,54 +935,18 @@ nsHttpTransaction::ProcessData(char *buf, PRUint32 count, PRUint32 *countRead) void nsHttpTransaction::DeleteSelfOnConsumerThread() { - nsCOMPtr eqs; - nsCOMPtr currentEventQ; - LOG(("nsHttpTransaction::DeleteSelfOnConsumerThread [this=%x]\n", this)); - NS_ASSERTION(!mDestroying, "deleting self again"); - mDestroying = PR_TRUE; - - gHttpHandler->GetCurrentEventQ(getter_AddRefs(currentEventQ)); - - if (currentEventQ == mConsumerEventQ) + PRBool val; + if (NS_SUCCEEDED(mConsumerTarget->IsOnCurrentThread(&val)) && val) delete this; else { LOG(("proxying delete to consumer thread...\n")); - - PLEvent *event = new PLEvent; - if (!event) { - NS_WARNING("out of memory"); - // probably better to leak |this| than to delete it on this thread. - return; - } - - PL_InitEvent(event, this, DeleteThis_Handler, DeleteThis_Cleanup); - - nsresult status = mConsumerEventQ->PostEvent(event); - if (NS_FAILED(status)) - NS_ERROR("PostEvent failed"); + NS_ProxyRelease(mConsumerTarget, + NS_STATIC_CAST(nsIInputStreamCallback *, this)); } } -void *PR_CALLBACK -nsHttpTransaction::DeleteThis_Handler(PLEvent *ev) -{ - nsHttpTransaction *trans = - NS_STATIC_CAST(nsHttpTransaction *, PL_GetEventOwner(ev)); - - LOG(("nsHttpTransaction::DeleteThis_EventHandlerFunc [trans=%x]\n", trans)); - - delete trans; - return nsnull; -} - -void PR_CALLBACK -nsHttpTransaction::DeleteThis_Cleanup(PLEvent *ev) -{ - delete ev; -} - //----------------------------------------------------------------------------- // nsHttpTransaction::nsISupports //----------------------------------------------------------------------------- diff --git a/mozilla/netwerk/protocol/http/src/nsHttpTransaction.h b/mozilla/netwerk/protocol/http/src/nsHttpTransaction.h index 7c3289e33ee..02829207fe2 100644 --- a/mozilla/netwerk/protocol/http/src/nsHttpTransaction.h +++ b/mozilla/netwerk/protocol/http/src/nsHttpTransaction.h @@ -52,7 +52,7 @@ #include "nsIInterfaceRequestor.h" #include "nsISocketTransportService.h" #include "nsITransport.h" -#include "nsIEventQueue.h" +#include "nsIEventTarget.h" //----------------------------------------------------------------------------- @@ -92,8 +92,8 @@ public: // the request body (POST or PUT data stream) // @param reqBodyIncludesHeaders // fun stuff to support NPAPI plugins. - // @param eventQ - // the event queue were notifications should be sent. + // @param target + // the dispatch target were notifications should be sent. // @param callbacks // the notification callbacks to be given to PSM. // @param responseBody @@ -106,7 +106,7 @@ public: nsHttpRequestHead *reqHeaders, nsIInputStream *reqBody, PRBool reqBodyIncludesHeaders, - nsIEventQueue *consumerEventQ, + nsIEventTarget *consumerTarget, nsIInterfaceRequestor *callbacks, nsITransportEventSink *eventsink, nsIAsyncInputStream **responseBody); @@ -119,7 +119,7 @@ public: nsISupports *SecurityInfo() { return mSecurityInfo; } nsIInterfaceRequestor *Callbacks() { return mCallbacks; } - nsIEventQueue *ConsumerEventQ() { return mConsumerEventQ; } + nsIEventTarget *ConsumerTarget() { return mConsumerTarget; } nsAHttpConnection *Connection() { return mConnection; } // Called to take ownership of the response headers; the transaction @@ -146,10 +146,10 @@ private: nsresult ProcessData(char *, PRUint32, PRUint32 *); void DeleteSelfOnConsumerThread(); + /*XXX static void *PR_CALLBACK TransportStatus_Handler(PLEvent *); static void PR_CALLBACK TransportStatus_Cleanup(PLEvent *); - static void *PR_CALLBACK DeleteThis_Handler(PLEvent *); - static void PR_CALLBACK DeleteThis_Cleanup(PLEvent *); + */ static NS_METHOD ReadRequestSegment(nsIInputStream *, void *, const char *, PRUint32, PRUint32, PRUint32 *); @@ -159,7 +159,7 @@ private: private: nsCOMPtr mCallbacks; nsCOMPtr mTransportSink; - nsCOMPtr mConsumerEventQ; + nsCOMPtr mConsumerTarget; nsCOMPtr mSecurityInfo; nsCOMPtr mPipeIn; nsCOMPtr mPipeOut; @@ -192,7 +192,6 @@ private: // state flags PRUint32 mClosed : 1; - PRUint32 mDestroying : 1; PRUint32 mConnected : 1; PRUint32 mHaveStatusLine : 1; PRUint32 mHaveAllHeaders : 1; diff --git a/mozilla/netwerk/streamconv/test/TestStreamConv.cpp b/mozilla/netwerk/streamconv/test/TestStreamConv.cpp index ffc27e00c13..e895ebd8adb 100644 --- a/mozilla/netwerk/streamconv/test/TestStreamConv.cpp +++ b/mozilla/netwerk/streamconv/test/TestStreamConv.cpp @@ -45,6 +45,7 @@ #include "nsIStringStream.h" #include "nsCOMPtr.h" #include "nsNetUtil.h" +#include "nsThreadUtils.h" #include "nspr.h" @@ -53,7 +54,6 @@ ///////////////////////////////// // Event pump setup ///////////////////////////////// -#include "nsIEventQueueService.h" #ifdef XP_WIN #include #endif @@ -62,7 +62,6 @@ #endif static int gKeepRunning = 0; -static nsIEventQueue* gEventQ = nsnull; ///////////////////////////////// // Event pump END ///////////////////////////////// @@ -74,7 +73,6 @@ static nsIEventQueue* gEventQ = nsnull; #include "Converters.h" // CID setup -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); static NS_DEFINE_CID(kStreamConverterServiceCID, NS_STREAMCONVERTERSERVICE_CID); //////////////////////////////////////////////////////////////////////// @@ -153,12 +151,7 @@ main(int argc, char* argv[]) if (registrar) registrar->AutoRegister(nsnull); - // Create the Event Queue for this thread... - nsCOMPtr eventQService = - do_GetService(kEventQueueServiceCID, &rv); - if (NS_FAILED(rv)) return rv; - - eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &gEventQ); + nsCOMPtr thread = do_GetCurrentThread(); nsCOMPtr catman = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv); @@ -281,10 +274,9 @@ main(int argc, char* argv[]) // Enter the message pump to allow the URL load to proceed. while ( gKeepRunning ) { - PLEvent *gEvent; - gEventQ->WaitForEvent(&gEvent); - gEventQ->HandleEvent(gEvent); - /* gKeepRunning = PR_FALSE; */ + rv = thread->ProcessNextEvent(); + if (NS_FAILED(rv)) + break; } } // this scopes the nsCOMPtrs // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM diff --git a/mozilla/netwerk/test/PropertiesTest.cpp b/mozilla/netwerk/test/PropertiesTest.cpp index a9958054154..b87e4e0c6f2 100644 --- a/mozilla/netwerk/test/PropertiesTest.cpp +++ b/mozilla/netwerk/test/PropertiesTest.cpp @@ -39,7 +39,6 @@ #include "TestCommon.h" #include "nsXPCOM.h" #include "nsStringAPI.h" -#include "nsIEventQueueService.h" #include "nsIPersistentProperties2.h" #include "nsIServiceManager.h" #include "nsIComponentRegistrar.h" @@ -57,7 +56,6 @@ static NS_DEFINE_CID(kPersistentPropertiesCID, NS_IPERSISTENTPROPERTIES_CID); static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID); -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); /***************************************************************************/ @@ -69,7 +67,6 @@ main(int argc, char* argv[]) nsresult ret; - nsCOMPtr servMan; NS_InitXPCOM2(getter_AddRefs(servMan), nsnull, nsnull); nsCOMPtr registrar = do_QueryInterface(servMan); @@ -81,18 +78,10 @@ main(int argc, char* argv[]) nsCOMPtr service(do_GetService(kIOServiceCID, &ret)); if (NS_FAILED(ret)) return ret; - nsCOMPtr eventQService = - do_GetService(kEventQueueServiceCID, &ret); - if (NS_FAILED(ret)) return ret; - nsIChannel *channel = nsnull; ret = service->NewChannel(NS_LITERAL_CSTRING(TEST_URL), nsnull, nsnull, &channel); if (NS_FAILED(ret)) return ret; - nsIEventQueue *eventQ = nsnull; - ret = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &eventQ); - if (NS_FAILED(ret)) return ret; - ret = channel->Open(&in); if (NS_FAILED(ret)) return ret; diff --git a/mozilla/netwerk/test/TestCallbacks.cpp b/mozilla/netwerk/test/TestCallbacks.cpp index f18141347ac..37cfbf2ebc9 100644 --- a/mozilla/netwerk/test/TestCallbacks.cpp +++ b/mozilla/netwerk/test/TestCallbacks.cpp @@ -43,7 +43,6 @@ #include "nspr.h" #include "nscore.h" #include "nsCOMPtr.h" -#include "nsIEventQueueService.h" #include "nsIIOService.h" #include "nsIServiceManager.h" #include "nsIStreamListener.h" @@ -58,12 +57,10 @@ #include "nsNetUtil.h" #include "nsStringAPI.h" -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID); -static int gKeepRunning = 0; -static nsIEventQueue* gEventQ = nsnull; static PRBool gError = PR_FALSE; +static PRInt32 gKeepRunning = 0; #define NS_IEQUALS_IID \ { 0x11c5c8ee, 0x1dd2, 0x11b2, \ @@ -201,7 +198,8 @@ Consumer::~Consumer() { } fprintf(stderr, "Consumer::~Consumer -> out\n\n"); - gKeepRunning--; + if (--gKeepRunning == 0) + QuitPumpingEvents(); } nsresult @@ -256,14 +254,6 @@ int main(int argc, char *argv[]) { rv = NS_InitXPCOM2(nsnull, nsnull, nsnull); if (NS_FAILED(rv)) return rv; - // Create the Event Queue for this thread... - nsCOMPtr eventQService = - do_GetService(kEventQueueServiceCID, &rv); - if (NS_FAILED(rv)) return rv; - - rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &gEventQ); - if (NS_FAILED(rv)) return rv; - if (cmdLineURL) { rv = StartLoad(argv[1]); } else { @@ -272,11 +262,7 @@ int main(int argc, char *argv[]) { if (NS_FAILED(rv)) return rv; // Enter the message pump to allow the URL load to proceed. - while ( gKeepRunning ) { - PLEvent *gEvent; - gEventQ->WaitForEvent(&gEvent); - gEventQ->HandleEvent(gEvent); - } + PumpEvents(); NS_ShutdownXPCOM(nsnull); if (gError) { diff --git a/mozilla/netwerk/test/TestCommon.h b/mozilla/netwerk/test/TestCommon.h index 711ad8d32a8..3a336736819 100644 --- a/mozilla/netwerk/test/TestCommon.h +++ b/mozilla/netwerk/test/TestCommon.h @@ -37,9 +37,45 @@ #ifndef TestCommon_h__ #define TestCommon_h__ +#include +#include "nsThreadUtils.h" + inline int test_common_init(int *argc, char ***argv) { return 0; } +//----------------------------------------------------------------------------- + +static PRBool gKeepPumpingEvents = PR_FALSE; + +class nsQuitPumpingEvent : public nsIRunnable { +public: + NS_DECL_ISUPPORTS + NS_IMETHOD Run() { + gKeepPumpingEvents = PR_FALSE; + return NS_OK; + } +}; +NS_IMPL_THREADSAFE_ISUPPORTS1(nsQuitPumpingEvent, nsIRunnable) + +static void PumpEvents() +{ + nsCOMPtr thread = do_GetCurrentThread(); + + gKeepPumpingEvents = PR_TRUE; + while (gKeepPumpingEvents) + thread->ProcessNextEvent(); + + NS_ProcessPendingEvents(thread); +} + +static void QuitPumpingEvents() +{ + // Dispatch a task that toggles gKeepPumpingEvents so that we flush all + // of the pending tasks before exiting from PumpEvents. + nsCOMPtr event = new nsQuitPumpingEvent(); + NS_DispatchToMainThread(event); +} + #endif diff --git a/mozilla/netwerk/test/TestDNS.cpp b/mozilla/netwerk/test/TestDNS.cpp index 6f63f3667b9..359007586f9 100644 --- a/mozilla/netwerk/test/TestDNS.cpp +++ b/mozilla/netwerk/test/TestDNS.cpp @@ -93,9 +93,10 @@ NS_IMPL_THREADSAFE_ISUPPORTS1(myDNSListener, nsIDNSListener) static PRBool IsAscii(const char *s) { - while (*s) + for (; *s; ++s) { if (*s & 0x80) return PR_FALSE; + } return PR_TRUE; } diff --git a/mozilla/netwerk/test/TestIOThreads.cpp b/mozilla/netwerk/test/TestIOThreads.cpp index 32fc19c94f1..c60a154d592 100644 --- a/mozilla/netwerk/test/TestIOThreads.cpp +++ b/mozilla/netwerk/test/TestIOThreads.cpp @@ -40,7 +40,7 @@ #include "nsServiceManagerUtils.h" #include "nsIEventTarget.h" #include "nsCOMPtr.h" -#include "plevent.h" +#include "nsNetCID.h" #include "prlog.h" #if defined(PR_LOGGING) @@ -51,33 +51,37 @@ static PRLogModuleInfo *gTestLog = nsnull; #endif #define LOG(args) PR_LOG(gTestLog, PR_LOG_DEBUG, args) -PR_STATIC_CALLBACK(void *) HandleEvent(PLEvent *event) -{ - LOG(("HandleEvent:%d\n", NS_PTR_TO_INT32(event->owner))); - return nsnull; -} +class nsIOEvent : public nsIRunnable { +public: + NS_DECL_ISUPPORTS -PR_STATIC_CALLBACK(void) DestroyEvent(PLEvent *event) -{ - delete event; -} + nsIOEvent(int i) : mIndex(i) {} + + NS_IMETHOD Run() { + LOG(("Run [%d]\n", mIndex)); + return NS_OK; + } + +private: + int mIndex; +}; +NS_IMPL_THREADSAFE_ISUPPORTS1(nsIOEvent, nsIRunnable) static nsresult RunTest() { nsresult rv; - nsCOMPtr target = do_GetService("@mozilla.org/network/io-thread-pool;1", &rv); + nsCOMPtr target = + do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; for (int i=0; i<10; ++i) { - PLEvent *event = new PLEvent(); - PL_InitEvent(event, (void *) i, HandleEvent, DestroyEvent); - LOG(("PostEvent:%d\n", i)); - if (NS_FAILED(target->PostEvent(event))) - PL_DestroyEvent(event); + nsCOMPtr event = new nsIOEvent(i); + LOG(("Dispatch %d\n", i)); + target->Dispatch(event, NS_DISPATCH_NORMAL); } - return rv; + return NS_OK; } int main(int argc, char **argv) diff --git a/mozilla/netwerk/test/TestIncrementalDownload.cpp b/mozilla/netwerk/test/TestIncrementalDownload.cpp index 5bb0bbe1ed5..a5065a06d00 100644 --- a/mozilla/netwerk/test/TestIncrementalDownload.cpp +++ b/mozilla/netwerk/test/TestIncrementalDownload.cpp @@ -37,54 +37,18 @@ * ***** END LICENSE BLOCK ***** */ #include +#include "TestCommon.h" #include "nsNetUtil.h" #include "nsIIncrementalDownload.h" #include "nsIRequestObserver.h" #include "nsIProgressEventSink.h" -#include "nsIEventQueueService.h" -#include "nsIEventQueue.h" +#include "nsThreadUtils.h" #include "nsAutoPtr.h" #include "prprf.h" #include "prenv.h" //----------------------------------------------------------------------------- -static nsresult SetupEventQ() -{ - nsresult rv; - - nsCOMPtr eqs = - do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv); - if (NS_FAILED(rv)) - return rv; - - return eqs->CreateMonitoredThreadEventQueue(); -} - -static nsresult PumpEvents() -{ - nsresult rv; - - nsCOMPtr eqs = - do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv); - if (NS_FAILED(rv)) - return rv; - - nsCOMPtr eq; - rv = eqs->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(eq)); - if (NS_FAILED(rv)) - return rv; - - return eq->EventLoop(); -} - -static void QuitPumpingEvents() -{ - PR_Interrupt(PR_GetCurrentThread()); -} - -//----------------------------------------------------------------------------- - class FetchObserver : public nsIRequestObserver , public nsIProgressEventSink { @@ -160,15 +124,12 @@ DoIncrementalFetch(const char *uriSpec, const char *resultPath, PRInt32 chunkSiz if (NS_FAILED(rv)) return rv; - rv = SetupEventQ(); - if (NS_FAILED(rv)) - return rv; - rv = download->Start(observer, nsnull); if (NS_FAILED(rv)) return rv; - return PumpEvents(); + PumpEvents(); + return NS_OK; } int diff --git a/mozilla/netwerk/test/TestPageLoad.cpp b/mozilla/netwerk/test/TestPageLoad.cpp index 6ef63550386..36d79f4fd56 100644 --- a/mozilla/netwerk/test/TestPageLoad.cpp +++ b/mozilla/netwerk/test/TestPageLoad.cpp @@ -37,7 +37,6 @@ #include "TestCommon.h" #include "nsNetUtil.h" -#include "nsIEventQueueService.h" #include "nsIServiceManager.h" #include "nsIInterfaceRequestor.h" #include "nsIInterfaceRequestorUtils.h" @@ -65,9 +64,6 @@ nsresult auxLoad(char *uriBuf); } \ PR_END_MACRO -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); -static nsIEventQueue* gEventQ = nsnull; -static PRBool gKeepRunning = PR_FALSE; static nsCString globalStream; //static char urlBuf[256]; static nsCOMPtr baseURI; @@ -77,6 +73,8 @@ static nsCOMPtr uriList; static int numStart=0; static int numFound=0; +static PRInt32 gKeepRunning = 0; + //--------writer fun---------------------- @@ -186,7 +184,8 @@ NS_IMETHODIMP MyListener::OnStopRequest(nsIRequest *req, nsISupports *ctxt, nsresult status) { //printf(">>> OnStopRequest status=%x\n", status); - gKeepRunning--; + if (--gKeepRunning == 0) + QuitPumpingEvents(); return NS_OK; } @@ -371,17 +370,6 @@ int main(int argc, char **argv) uriList = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID, &rv); RETURN_IF_FAILED(rv, "do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID)"); - // Create the Event Queue for this thread... - nsCOMPtr eqs = - do_GetService(kEventQueueServiceCID, &rv); - RETURN_IF_FAILED(rv, "do_GetService(EventQueueService)"); - - rv = eqs->CreateMonitoredThreadEventQueue(); - RETURN_IF_FAILED(rv, "CreateMonitoredThreadEventQueue"); - - rv = eqs->GetThreadEventQueue(NS_CURRENT_THREAD, &gEventQ); - RETURN_IF_FAILED(rv, "GetThreadEventQueue"); - printf("Loading necko ... \n"); nsCOMPtr chan; nsCOMPtr listener = new MyListener(); @@ -400,9 +388,7 @@ int main(int argc, char **argv) rv = chan->AsyncOpen(listener, nsnull); RETURN_IF_FAILED(rv, "AsyncOpen"); - while (gKeepRunning) { - gEventQ->ProcessPendingEvents(); - } + PumpEvents(); finish = PR_Now(); PRUint32 totalTime32; diff --git a/mozilla/netwerk/test/TestPerf.cpp b/mozilla/netwerk/test/TestPerf.cpp index 6352c12e60e..4516d920f9b 100644 --- a/mozilla/netwerk/test/TestPerf.cpp +++ b/mozilla/netwerk/test/TestPerf.cpp @@ -2,7 +2,6 @@ #include #include "nsCRT.h" /* should be "plstr.h"? */ #include "nsNetUtil.h" -#include "nsIEventQueueService.h" #include "nsIServiceManager.h" #include "nsIComponentRegistrar.h" #include "nsISupportsArray.h" @@ -53,8 +52,6 @@ load_sync(nsISupportsArray *urls) //----------------------------------------------------------------------------- static int gRequestCount = 0; -static nsIEventQueue *gEventQ = 0; - class MyListener : public nsIStreamListener { @@ -95,18 +92,6 @@ MyListener::OnDataAvailable(nsIRequest *req, nsISupports *ctx, return NS_OK; } -static void *PR_CALLBACK -ShutdownEvent_Handler(PLEvent *ev) -{ - return nsnull; -} - -static void PR_CALLBACK -ShutdownEvent_Cleanup(PLEvent *ev) -{ - delete ev; -} - NS_IMETHODIMP MyListener::OnStopRequest(nsIRequest *req, nsISupports *ctx, nsresult status) { @@ -117,11 +102,7 @@ MyListener::OnStopRequest(nsIRequest *req, nsISupports *ctx, nsresult status) } if (--gRequestCount == 0) { // post shutdown event - PLEvent *ev = new PLEvent; - PL_InitEvent(ev, nsnull, - ShutdownEvent_Handler, - ShutdownEvent_Cleanup); - gEventQ->PostEvent(ev); + QuitPumpingEvents(); } return NS_OK; } @@ -149,29 +130,9 @@ load_async_1(nsISupports *element, void *data) static nsresult load_async(nsISupportsArray *urls) { - nsresult rv; - - // Create the Event Queue for this thread... - nsCOMPtr eqs( - do_GetService("@mozilla.org/event-queue-service;1", &rv) ); - if (NS_FAILED(rv)) return rv; - - rv = eqs->CreateMonitoredThreadEventQueue(); - if (NS_FAILED(rv)) return rv; - - rv = eqs->GetThreadEventQueue(NS_CURRENT_THREAD, &gEventQ); - if (NS_FAILED(rv)) return rv; - urls->EnumerateForwards(load_async_1, nsnull); - while (1) { - PLEvent *ev; - gEventQ->WaitForEvent(&ev); - if (gRequestCount == 0) - break; - gEventQ->HandleEvent(ev); - } - NS_RELEASE(gEventQ); + PumpEvents(); return NS_OK; } diff --git a/mozilla/netwerk/test/TestProtocols.cpp b/mozilla/netwerk/test/TestProtocols.cpp index 946299db5dd..e7160905804 100644 --- a/mozilla/netwerk/test/TestProtocols.cpp +++ b/mozilla/netwerk/test/TestProtocols.cpp @@ -57,7 +57,6 @@ #include "nspr.h" #include "nscore.h" #include "nsCOMPtr.h" -#include "nsIEventQueueService.h" #include "nsIIOService.h" #include "nsIServiceManager.h" #include "nsIStreamListener.h" @@ -97,13 +96,11 @@ static PRLogModuleInfo *gTestLog = nsnull; #endif #define LOG(args) PR_LOG(gTestLog, PR_LOG_DEBUG, args) -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID); //static PRTime gElapsedTime; // enable when we time it... static int gKeepRunning = 0; static PRBool gVerbose = PR_FALSE; -static nsIEventQueue* gEventQ = nsnull; static PRBool gAskUserForInput = PR_FALSE; static PRBool gResume = PR_FALSE; static PRUint64 gStartAt = 0; @@ -504,29 +501,6 @@ InputTestConsumer::OnDataAvailable(nsIRequest *request, return NS_OK; } -PR_STATIC_CALLBACK(void) DecrementDestroyHandler(PLEvent *self) -{ - PR_Free(self); -} - - -PR_STATIC_CALLBACK(void*) DecrementEventHandler(PLEvent *self) -{ - gKeepRunning--; - return nsnull; -} - -void FireDecrement() -{ - PLEvent *event = PR_NEW(PLEvent); - PL_InitEvent(event, - nsnull, - DecrementEventHandler, - DecrementDestroyHandler); - - gEventQ->PostEvent(event); -} - NS_IMETHODIMP InputTestConsumer::OnStopRequest(nsIRequest *request, nsISupports* context, nsresult aStatus) @@ -572,7 +546,8 @@ InputTestConsumer::OnStopRequest(nsIRequest *request, nsISupports* context, LOG(("\nFinished loading: UNKNOWN URL. Status Code: %x\n", aStatus)); } - FireDecrement(); + if (--gKeepRunning == 0) + QuitPumpingEvents(); return NS_OK; } @@ -708,7 +683,7 @@ nsresult StartLoadingURL(const char* aUrlString) info); if (NS_SUCCEEDED(rv)) { - gKeepRunning += 1; + gKeepRunning++; } else { LOG(("ERROR: AsyncOpen failed [rv=%x]\n", rv)); @@ -833,13 +808,6 @@ main(int argc, char* argv[]) if (NS_FAILED(rv)) return rv; { - // Create the Event Queue for this thread... - nsCOMPtr eventQService = - do_GetService(kEventQueueServiceCID, &rv); - if (NS_FAILED(rv)) return rv; - - eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &gEventQ); - int i; LOG(("Trying to load:\n")); for (i=1; iWaitForEvent(&gEvent); - gEventQ->HandleEvent(gEvent); - } + // Enter the message pump to allow the URL load to proceed. + PumpEvents(); } // this scopes the nsCOMPtrs // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM NS_ShutdownXPCOM(nsnull); diff --git a/mozilla/netwerk/test/TestServ.cpp b/mozilla/netwerk/test/TestServ.cpp index 0fbf0084720..dbb4e7a06a0 100644 --- a/mozilla/netwerk/test/TestServ.cpp +++ b/mozilla/netwerk/test/TestServ.cpp @@ -38,8 +38,6 @@ #include "TestCommon.h" #include #include "nsIServiceManager.h" -#include "nsIEventQueueService.h" -#include "nsIEventQueue.h" #include "nsIServerSocket.h" #include "nsISocketTransport.h" #include "nsNetUtil.h" @@ -55,9 +53,6 @@ static PRLogModuleInfo *gTestLog = nsnull; #endif #define LOG(args) PR_LOG(gTestLog, PR_LOG_DEBUG, args) -static PRBool gKeepRunning = PR_TRUE; -static nsIEventQueue* gEventQ = nsnull; - class MySocketListener : public nsIServerSocketListener { public: @@ -117,7 +112,7 @@ NS_IMETHODIMP MySocketListener::OnStopListening(nsIServerSocket *serv, nsresult status) { LOG(("MySocketListener::OnStopListening [serv=%p status=%x]\n", serv, status)); - gKeepRunning = PR_FALSE; + QuitPumpingEvents(); return NS_OK; } @@ -167,13 +162,6 @@ main(int argc, char* argv[]) if (NS_FAILED(rv)) return rv; { - // Create the Event Queue for this thread... - nsCOMPtr eqs = - do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv); - if (NS_FAILED(rv)) return rv; - - eqs->GetThreadEventQueue(NS_CURRENT_THREAD, &gEventQ); - rv = MakeServer(atoi(argv[1])); if (NS_FAILED(rv)) { LOG(("MakeServer failed [rv=%x]\n", rv)); @@ -181,11 +169,7 @@ main(int argc, char* argv[]) } // Enter the message pump to allow the URL load to proceed. - while (gKeepRunning) { - PLEvent *event; - gEventQ->WaitForEvent(&event); - gEventQ->HandleEvent(event); - } + PumpEvents(); } // this scopes the nsCOMPtrs // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM NS_ShutdownXPCOM(nsnull); diff --git a/mozilla/netwerk/test/TestSocketTransport.cpp b/mozilla/netwerk/test/TestSocketTransport.cpp index ffdfac41fa9..562db706b63 100644 --- a/mozilla/netwerk/test/TestSocketTransport.cpp +++ b/mozilla/netwerk/test/TestSocketTransport.cpp @@ -54,8 +54,6 @@ #include "nsIDNSService.h" #include "nsIFileStreams.h" #include "nsIStreamListener.h" -#include "nsIEventQueueService.h" -#include "nsIEventQueue.h" #include "nsILocalFile.h" #include "nsNetUtil.h" #include "nsAutoLock.h" @@ -74,39 +72,6 @@ static PRLogModuleInfo *gTestLog = nsnull; //////////////////////////////////////////////////////////////////////////////// static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID); -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); - -PRBool gDone = PR_FALSE; -nsIEventQueue* gEventQ = nsnull; - -//////////////////////////////////////////////////////////////////////////////// - -static void *PR_CALLBACK -DoneEvent_Handler(PLEvent *ev) -{ - gDone = PR_TRUE; - return nsnull; -} - -static void PR_CALLBACK -DoneEvent_Cleanup(PLEvent *ev) -{ - delete ev; -} - -static void -PostDoneEvent() -{ - LOG(("PostDoneEvent\n")); - - PLEvent *ev = new PLEvent(); - - PL_InitEvent(ev, nsnull, - DoneEvent_Handler, - DoneEvent_Cleanup); - - gEventQ->PostEvent(ev); -} //////////////////////////////////////////////////////////////////////////////// @@ -169,7 +134,7 @@ public: if (NS_FAILED(rv) || (n == 0)) { if (rv != NS_BASE_STREAM_WOULD_BLOCK) { - PostDoneEvent(); + QuitPumpingEvents(); return NS_OK; } } @@ -261,16 +226,8 @@ RunTest(nsISocketTransportService *sts, rv = asyncOut->AsyncWait(handler, 0, 0, nsnull); - if (NS_SUCCEEDED(rv)) { - PLEvent* event; - gDone = PR_FALSE; - while (!gDone) { - rv = gEventQ->WaitForEvent(&event); - if (NS_FAILED(rv)) return rv; - rv = gEventQ->HandleEvent(event); - if (NS_FAILED(rv)) return rv; - } - } + if (NS_SUCCEEDED(rv)) + PumpEvents(); NS_RELEASE(handler); @@ -309,16 +266,6 @@ main(int argc, char* argv[]) do_GetService(NS_DNSSERVICE_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; - nsCOMPtr eventQService = - do_GetService(kEventQueueServiceCID, &rv); - if (NS_FAILED(rv)) return rv; - - rv = eventQService->CreateMonitoredThreadEventQueue(); - if (NS_FAILED(rv)) return rv; - - rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &gEventQ); - if (NS_FAILED(rv)) return rv; - nsCOMPtr sts = do_GetService(kSocketTransportServiceCID, &rv); if (NS_FAILED(rv)) return rv; @@ -387,8 +334,6 @@ main(int argc, char* argv[]) LOG(("calling Shutdown on socket transport service:\n")); sts->Shutdown(); - NS_RELEASE(gEventQ); - // give background threads a chance to finish whatever work they may // be doing. LOG(("waiting 1 second before exiting...\n")); diff --git a/mozilla/netwerk/test/TestStreamChannel.cpp b/mozilla/netwerk/test/TestStreamChannel.cpp index 58a8fb5863a..05f8a4cd734 100644 --- a/mozilla/netwerk/test/TestStreamChannel.cpp +++ b/mozilla/netwerk/test/TestStreamChannel.cpp @@ -51,8 +51,6 @@ #include "nsStringAPI.h" #include "nsIFileStreams.h" #include "nsIStreamListener.h" -#include "nsIEventQueueService.h" -#include "nsIEventQueue.h" #include "nsILocalFile.h" #include "nsNetUtil.h" #include "nsAutoLock.h" @@ -73,39 +71,6 @@ static PRLogModuleInfo *gTestLog = nsnull; //////////////////////////////////////////////////////////////////////////////// static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID); -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); - -PRBool gDone = PR_FALSE; -nsIEventQueue *gEventQ = nsnull; - -//////////////////////////////////////////////////////////////////////////////// - -static void *PR_CALLBACK -DoneEvent_Handler(PLEvent *ev) -{ - gDone = PR_TRUE; - return nsnull; -} - -static void PR_CALLBACK -DoneEvent_Cleanup(PLEvent *ev) -{ - delete ev; -} - -static void -PostDoneEvent() -{ - LOG(("PostDoneEvent\n")); - - PLEvent *ev = new PLEvent(); - - PL_InitEvent(ev, nsnull, - DoneEvent_Handler, - DoneEvent_Cleanup); - - gEventQ->PostEvent(ev); -} //////////////////////////////////////////////////////////////////////////////// @@ -151,7 +116,7 @@ public: NS_IMETHOD OnStopRequest(nsIRequest *req, nsISupports *ctx, nsresult status) { LOG(("MyListener::OnStopRequest [status=%x]\n", status)); - PostDoneEvent(); + QuitPumpingEvents(); return NS_OK; } }; @@ -225,15 +190,7 @@ RunTest(nsIFile *file) rv = chan->AsyncOpen(new MyListener(), nsnull); if (NS_FAILED(rv)) return rv; - gDone = PR_FALSE; - while (!gDone) { - PLEvent *event; - rv = gEventQ->WaitForEvent(&event); - if (NS_FAILED(rv)) return rv; - rv = gEventQ->HandleEvent(event); - if (NS_FAILED(rv)) return rv; - } - + PumpEvents(); return NS_OK; } @@ -264,13 +221,6 @@ main(int argc, char* argv[]) gTestLog = PR_NewLogModule("Test"); #endif - nsCOMPtr eventQService = - do_GetService(kEventQueueServiceCID, &rv); - if (NS_FAILED(rv)) return rv; - - rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &gEventQ); - if (NS_FAILED(rv)) return rv; - nsCOMPtr file; rv = NS_NewNativeLocalFile(nsDependentCString(fileName), PR_FALSE, getter_AddRefs(file)); if (NS_FAILED(rv)) return rv; @@ -278,8 +228,6 @@ main(int argc, char* argv[]) rv = RunTest(file); NS_ASSERTION(NS_SUCCEEDED(rv), "RunTest failed"); - NS_RELEASE(gEventQ); - // give background threads a chance to finish whatever work they may // be doing. PR_Sleep(PR_SecondsToInterval(1)); diff --git a/mozilla/netwerk/test/TestStreamLoader.cpp b/mozilla/netwerk/test/TestStreamLoader.cpp index 5bf2a26b7af..55e56219aa5 100644 --- a/mozilla/netwerk/test/TestStreamLoader.cpp +++ b/mozilla/netwerk/test/TestStreamLoader.cpp @@ -1,7 +1,7 @@ #include #include "TestCommon.h" #include "nsNetUtil.h" -#include "nsEventQueueUtils.h" +#include "nsThreadUtils.h" #include "prlog.h" #if defined(PR_LOGGING) @@ -12,9 +12,6 @@ static PRLogModuleInfo *gTestLog = nsnull; #endif #define LOG(args) PR_LOG(gTestLog, PR_LOG_DEBUG, args) -static PRBool gKeepRunning = PR_TRUE; -static nsIEventQueue* gEventQ = nsnull; - class MyStreamLoaderObserver : public nsIStreamLoaderObserver { public: @@ -37,7 +34,7 @@ MyStreamLoaderObserver::OnStreamComplete(nsIStreamLoader *loader, loader->GetRequest(getter_AddRefs(request)); LOG((" request=%p\n", request.get())); - gKeepRunning = PR_FALSE; + QuitPumpingEvents(); return NS_OK; } @@ -60,11 +57,6 @@ int main(int argc, char **argv) return -1; { - // Create the Event Queue for this thread... - rv = NS_GetMainEventQ(&gEventQ); - if (NS_FAILED(rv)) - return -1; - nsCOMPtr uri; rv = NS_NewURI(getter_AddRefs(uri), nsDependentCString(argv[1])); if (NS_FAILED(rv)) @@ -84,12 +76,7 @@ int main(int argc, char **argv) if (NS_FAILED(rv)) return -1; - // Enter the message pump to allow the URL load to proceed. - while (gKeepRunning) { - PLEvent *e; - gEventQ->WaitForEvent(&e); - gEventQ->HandleEvent(e); - } + PumpEvents(); } // this scopes the nsCOMPtrs // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM NS_ShutdownXPCOM(nsnull); diff --git a/mozilla/netwerk/test/TestStreamPump.cpp b/mozilla/netwerk/test/TestStreamPump.cpp index a32a7283433..4d73376ca26 100644 --- a/mozilla/netwerk/test/TestStreamPump.cpp +++ b/mozilla/netwerk/test/TestStreamPump.cpp @@ -52,8 +52,6 @@ #include "nsStringAPI.h" #include "nsIFileStreams.h" #include "nsIStreamListener.h" -#include "nsIEventQueueService.h" -#include "nsIEventQueue.h" #include "nsILocalFile.h" #include "nsNetUtil.h" #include "nsAutoLock.h" @@ -74,42 +72,6 @@ static PRLogModuleInfo *gTestLog = nsnull; //////////////////////////////////////////////////////////////////////////////// -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); - -PRBool gDone = PR_FALSE; -nsIEventQueue *gEventQ = nsnull; - -//////////////////////////////////////////////////////////////////////////////// - -static void *PR_CALLBACK -DoneEvent_Handler(PLEvent *ev) -{ - gDone = PR_TRUE; - return nsnull; -} - -static void PR_CALLBACK -DoneEvent_Cleanup(PLEvent *ev) -{ - delete ev; -} - -static void -PostDoneEvent() -{ - LOG(("PostDoneEvent\n")); - - PLEvent *ev = new PLEvent(); - - PL_InitEvent(ev, nsnull, - DoneEvent_Handler, - DoneEvent_Cleanup); - - gEventQ->PostEvent(ev); -} - -//////////////////////////////////////////////////////////////////////////////// - class MyListener : public nsIStreamListener { public: @@ -155,7 +117,7 @@ public: NS_IMETHOD OnStopRequest(nsIRequest *req, nsISupports *ctx, nsresult status) { LOG(("MyListener::OnStopRequest [status=%x]\n", status)); - PostDoneEvent(); + QuitPumpingEvents(); return NS_OK; } }; @@ -187,15 +149,7 @@ RunTest(nsIFile *file, PRInt64 offset, PRInt64 length) rv = pump->AsyncRead(new MyListener(), nsnull); if (NS_FAILED(rv)) return rv; - gDone = PR_FALSE; - while (!gDone) { - PLEvent *event; - rv = gEventQ->WaitForEvent(&event); - if (NS_FAILED(rv)) return rv; - rv = gEventQ->HandleEvent(event); - if (NS_FAILED(rv)) return rv; - } - + PumpEvents(); return NS_OK; } @@ -238,13 +192,6 @@ main(int argc, char* argv[]) gTestLog = PR_NewLogModule("Test"); #endif - nsCOMPtr eventQService = - do_GetService(kEventQueueServiceCID, &rv); - if (NS_FAILED(rv)) return rv; - - rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &gEventQ); - if (NS_FAILED(rv)) return rv; - nsCOMPtr file; rv = NS_NewNativeLocalFile(nsDependentCString(fileName), PR_FALSE, getter_AddRefs(file)); if (NS_FAILED(rv)) return rv; @@ -252,8 +199,6 @@ main(int argc, char* argv[]) rv = RunTest(file, offset, length); NS_ASSERTION(NS_SUCCEEDED(rv), "RunTest failed"); - NS_RELEASE(gEventQ); - // give background threads a chance to finish whatever work they may // be doing. PR_Sleep(PR_SecondsToInterval(1)); diff --git a/mozilla/netwerk/test/TestStreamTransport.cpp b/mozilla/netwerk/test/TestStreamTransport.cpp index 57faf86e34c..ad2b9463f89 100644 --- a/mozilla/netwerk/test/TestStreamTransport.cpp +++ b/mozilla/netwerk/test/TestStreamTransport.cpp @@ -51,8 +51,6 @@ #include "nsStringAPI.h" #include "nsIFileStreams.h" #include "nsIStreamListener.h" -#include "nsIEventQueueService.h" -#include "nsIEventQueue.h" #include "nsILocalFile.h" #include "nsNetUtil.h" #include "nsAutoLock.h" @@ -72,39 +70,6 @@ static PRLogModuleInfo *gTestLog = nsnull; //////////////////////////////////////////////////////////////////////////////// static NS_DEFINE_CID(kStreamTransportServiceCID, NS_STREAMTRANSPORTSERVICE_CID); -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); - -PRBool gDone = PR_FALSE; -nsIEventQueue* gEventQ = nsnull; - -//////////////////////////////////////////////////////////////////////////////// - -static void *PR_CALLBACK -DoneEvent_Handler(PLEvent *ev) -{ - gDone = PR_TRUE; - return nsnull; -} - -static void PR_CALLBACK -DoneEvent_Cleanup(PLEvent *ev) -{ - delete ev; -} - -static void -PostDoneEvent() -{ - LOG(("PostDoneEvent\n")); - - PLEvent *ev = new PLEvent(); - - PL_InitEvent(ev, nsnull, - DoneEvent_Handler, - DoneEvent_Cleanup); - - gEventQ->PostEvent(ev); -} //////////////////////////////////////////////////////////////////////////////// @@ -162,7 +127,7 @@ public: mInput = 0; // post done copying event - PostDoneEvent(); + QuitPumpingEvents(); } void Process_Locked() @@ -277,15 +242,7 @@ RunTest(nsIFile *srcFile, nsIFile *destFile) rv = copier->AsyncCopy(srcTransport, destTransport); if (NS_FAILED(rv)) return rv; - PLEvent* event; - - gDone = PR_FALSE; - while (!gDone) { - rv = gEventQ->WaitForEvent(&event); - if (NS_FAILED(rv)) return rv; - rv = gEventQ->HandleEvent(event); - if (NS_FAILED(rv)) return rv; - } + PumpEvents(); NS_RELEASE(copier); return NS_OK; @@ -361,13 +318,6 @@ main(int argc, char* argv[]) gTestLog = PR_NewLogModule("Test"); #endif - nsCOMPtr eventQService = - do_GetService(kEventQueueServiceCID, &rv); - if (NS_FAILED(rv)) return rv; - - rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &gEventQ); - if (NS_FAILED(rv)) return rv; - nsCOMPtr srcFile; rv = NS_NewNativeLocalFile(nsDependentCString(fileName), PR_FALSE, getter_AddRefs(srcFile)); if (NS_FAILED(rv)) return rv; @@ -396,8 +346,6 @@ main(int argc, char* argv[]) rv = RunBlockingTest(srcFile, destFile); NS_ASSERTION(NS_SUCCEEDED(rv), "RunBlockingTest failed"); - NS_RELEASE(gEventQ); - // give background threads a chance to finish whatever work they may // be doing. PR_Sleep(PR_SecondsToInterval(1)); diff --git a/mozilla/netwerk/test/TestUpload.cpp b/mozilla/netwerk/test/TestUpload.cpp index c4f80c85cc5..b2542ce357c 100644 --- a/mozilla/netwerk/test/TestUpload.cpp +++ b/mozilla/netwerk/test/TestUpload.cpp @@ -41,14 +41,12 @@ #endif #include "nsIComponentRegistrar.h" -#include "nsIEventQueueService.h" #include "nsIIOService.h" #include "nsIServiceManager.h" #include "nsNetUtil.h" #include "nsIUploadChannel.h" -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID); #include "prlog.h" @@ -60,9 +58,6 @@ static PRLogModuleInfo *gTestLog = nsnull; #endif #define LOG(args) PR_LOG(gTestLog, PR_LOG_DEBUG, args) -static int gKeepRunning = 1; -static nsIEventQueue* gEventQ = nsnull; - //----------------------------------------------------------------------------- // InputTestConsumer //----------------------------------------------------------------------------- @@ -126,7 +121,7 @@ InputTestConsumer::OnStopRequest(nsIRequest *request, nsISupports* context, nsresult aStatus) { LOG(("InputTestConsumer::OnStopRequest [status=%x]\n", aStatus)); - gKeepRunning = PR_FALSE; + QuitPumpingEvents(); return NS_OK; } @@ -158,13 +153,6 @@ main(int argc, char* argv[]) if (registrar) registrar->AutoRegister(nsnull); - // Create the Event Queue for this thread... - nsCOMPtr eventQService = - do_GetService(kEventQueueServiceCID, &rv); - if (NS_FAILED(rv)) return rv; - - eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &gEventQ); - nsCOMPtr ioService(do_GetService(kIOServiceCID, &rv)); // first thing to do is create ourselves a stream that // is to be uploaded. @@ -200,11 +188,7 @@ main(int argc, char* argv[]) channel->AsyncOpen(listener, nsnull); - while ( gKeepRunning ) { - PLEvent *gEvent; - gEventQ->WaitForEvent(&gEvent); - gEventQ->HandleEvent(gEvent); - } + PumpEvents(); } // this scopes the nsCOMPtrs // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM rv = NS_ShutdownXPCOM(nsnull); diff --git a/mozilla/parser/htmlparser/src/nsParser.cpp b/mozilla/parser/htmlparser/src/nsParser.cpp index e6426b1af50..586e601e7cd 100644 --- a/mozilla/parser/htmlparser/src/nsParser.cpp +++ b/mozilla/parser/htmlparser/src/nsParser.cpp @@ -54,8 +54,6 @@ #include "nsParserCIID.h" #include "nsReadableUtils.h" #include "nsCOMPtr.h" -#include "nsIEventQueue.h" -#include "nsIEventQueueService.h" #include "nsExpatDriver.h" #include "nsIServiceManager.h" #include "nsICategoryManager.h" @@ -78,8 +76,6 @@ static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID); static NS_DEFINE_IID(kIParserIID, NS_IPARSER_IID); -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); - //------------------------------------------------------------------- nsCOMArray *nsParser::sParserDataListeners; @@ -140,30 +136,19 @@ For more details @see bugzilla bug 76722 */ -struct nsParserContinueEvent : public PLEvent +class nsParserContinueEvent : public nsRunnable { +public: + nsRefPtr mParser; + nsParserContinueEvent(nsParser* aParser) - { - NS_ADDREF(aParser); - PL_InitEvent(this, aParser, HandleEvent, DestroyEvent); - } + : mParser(aParser) + {} - ~nsParserContinueEvent() + NS_IMETHOD Run() { - nsParser *parser = (nsParser*) owner; - NS_RELEASE(parser); - } - - PR_STATIC_CALLBACK(void*) HandleEvent(PLEvent* aEvent) - { - nsParser *parser = (nsParser*) aEvent->owner; - parser->HandleParserContinueEvent(); - return nsnull; - } - - PR_STATIC_CALLBACK(void) DestroyEvent(PLEvent* aEvent) - { - delete (nsParserContinueEvent*) aEvent; + mParser->HandleParserContinueEvent(this); + return NS_OK; } }; @@ -263,20 +248,6 @@ nsParser::nsParser() MOZ_TIMER_RESET(mParseTime); MOZ_TIMER_RESET(mDTDTime); MOZ_TIMER_RESET(mTokenizeTime); - - nsresult rv = NS_OK; - if (mEventQueue == nsnull) { - // Cache the event queue of the current UI thread - nsCOMPtr eventService = - do_GetService(kEventQueueServiceCID, &rv); - // XXX This implies that the UI is the current thread. - if (NS_SUCCEEDED(rv) && eventService) { - rv = eventService->GetThreadEventQueue(NS_CURRENT_THREAD, - getter_AddRefs(mEventQueue)); - } - - // NS_ASSERTION(mEventQueue, "event queue is null"); - } } /** @@ -311,10 +282,10 @@ nsParser::~nsParser() mParserContext = pc; } - if (mFlags & NS_PARSER_FLAG_PENDING_CONTINUE_EVENT) { - NS_ASSERTION(mEventQueue != nsnull, "Event queue is null"); - mEventQueue->RevokeEvents(this); - } + // It should not be possible for this flag to be set when we are getting + // destroyed since this flag implies a pending nsParserContinueEvent, which + // has an owning reference to |this|. + NS_ASSERTION(!(mFlags & NS_PARSER_FLAG_PENDING_CONTINUE_EVENT), "bad"); } NS_IMPL_ISUPPORTS3(nsParser, @@ -330,12 +301,14 @@ NS_IMPL_ISUPPORTS3(nsParser, nsresult nsParser::PostContinueEvent() { - if (!(mFlags & NS_PARSER_FLAG_PENDING_CONTINUE_EVENT) && mEventQueue) { - nsParserContinueEvent* ev = new nsParserContinueEvent(this); - NS_ENSURE_TRUE(ev, NS_ERROR_OUT_OF_MEMORY); - if (NS_FAILED(mEventQueue->PostEvent(ev))) { - NS_ERROR("failed to post parser continuation event"); - PL_DestroyEvent(ev); + if (!(mFlags & NS_PARSER_FLAG_PENDING_CONTINUE_EVENT)) { + // If this flag isn't set, then there shouldn't be a live continue event! + NS_ASSERTION(!mContinueEvent, "bad"); + + mContinueEvent = new nsParserContinueEvent(this); + if (NS_FAILED(NS_DispatchToCurrentThread(mContinueEvent))) { + NS_ERROR("failed to dispatch parser continuation event"); + mContinueEvent = nsnull; } else { mFlags |= NS_PARSER_FLAG_PENDING_CONTINUE_EVENT; } @@ -907,12 +880,9 @@ NS_IMETHODIMP nsParser::CancelParsingEvents() { if (mFlags & NS_PARSER_FLAG_PENDING_CONTINUE_EVENT) { - NS_ASSERTION(mEventQueue,"Event queue is null"); - // Revoke all pending continue parsing events - if (mEventQueue != nsnull) { - mEventQueue->RevokeEvents(this); - } - + NS_ASSERTION(mContinueEvent, "mContinueEvent is null"); + // Revoke the pending continue parsing event + mContinueEvent = nsnull; mFlags &= ~NS_PARSER_FLAG_PENDING_CONTINUE_EVENT; } return NS_OK; @@ -1194,8 +1164,14 @@ nsParser::IsComplete() } -void nsParser::HandleParserContinueEvent() { +void nsParser::HandleParserContinueEvent(nsParserContinueEvent *ev) { + // Ignore any revoked continue events... + if (mContinueEvent != ev) + return; + mFlags &= ~NS_PARSER_FLAG_PENDING_CONTINUE_EVENT; + mContinueEvent = nsnull; + ContinueInterruptedParsing(); } diff --git a/mozilla/parser/htmlparser/src/nsParser.h b/mozilla/parser/htmlparser/src/nsParser.h index 10080929332..c13de8e0bd3 100644 --- a/mozilla/parser/htmlparser/src/nsParser.h +++ b/mozilla/parser/htmlparser/src/nsParser.h @@ -83,7 +83,7 @@ #include "nsHTMLTags.h" #include "nsDTDUtils.h" #include "nsTimer.h" -#include "nsIEventQueue.h" +#include "nsThreadUtils.h" #include "nsIContentSink.h" #include "nsIParserFilter.h" #include "nsCOMArray.h" @@ -372,7 +372,7 @@ class nsParser : public nsIParser, * Fired when the continue parse event is triggered. * @update kmcclusk 5/18/98 */ - void HandleParserContinueEvent(void); + void HandleParserContinueEvent(class nsParserContinueEvent *); /** * Called by top-level scanners when data from necko is added to @@ -446,10 +446,10 @@ protected: //********************************************* - nsCOMPtr mEventQueue; CParserContext* mParserContext; nsCOMPtr mObserver; nsCOMPtr mSink; + nsCOMPtr mContinueEvent; nsCOMPtr mParserFilter; nsTokenAllocator mTokenAllocator; diff --git a/mozilla/parser/htmlparser/tests/grabpage/grabpage.cpp b/mozilla/parser/htmlparser/tests/grabpage/grabpage.cpp index 26d9248686f..9338f224618 100644 --- a/mozilla/parser/htmlparser/tests/grabpage/grabpage.cpp +++ b/mozilla/parser/htmlparser/tests/grabpage/grabpage.cpp @@ -39,6 +39,7 @@ #include "nsIURL.h" #include "nsServiceManagerUtils.h" #include "nsComponentManagerUtils.h" +#include "nsThreadUtils.h" #include "nsNetCID.h" #include "nsCOMPtr.h" @@ -47,10 +48,6 @@ #include "nsILocalFile.h" static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID); -#include "nsIEventQueueService.h" -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); -static nsIEventQueue* gEventQ = nsnull; - #include "nsStringAPI.h" #include "nsCRT.h" #include "prprf.h" @@ -220,14 +217,7 @@ nsresult PageGrabber::Grab(const nsCString& aURL) { nsresult rv; - // Create the Event Queue for this thread... // Unix needs this - nsCOMPtr eventQService = - do_GetService(kEventQueueServiceCID, &rv); - if (NS_FAILED(rv)) return rv; - - eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &gEventQ); - nsCOMPtr file = NextFile("html"); if (!file) { return NS_ERROR_OUT_OF_MEMORY; @@ -270,10 +260,11 @@ PageGrabber::Grab(const nsCString& aURL) } // Enter the message pump to allow the URL load to proceed. + nsCOMPtr thread = do_GetCurrentThread(); while ( !copier->IsDone() ) { - PLEvent *gEvent; - gEventQ->WaitForEvent(&gEvent); - gEventQ->HandleEvent(gEvent); + rv = thread->ProcessNextEvent(); + if (NS_FAILED(rv)) + break; } rv = copier->HaveError() ? NS_ERROR_FAILURE : NS_OK; diff --git a/mozilla/rdf/tests/rdfcat/rdfcat.cpp b/mozilla/rdf/tests/rdfcat/rdfcat.cpp index 9368ff8e78f..55b28f09fb1 100644 --- a/mozilla/rdf/tests/rdfcat/rdfcat.cpp +++ b/mozilla/rdf/tests/rdfcat/rdfcat.cpp @@ -53,7 +53,6 @@ #include "nsIComponentManager.h" #include "nsComponentManagerUtils.h" #include "nsServiceManagerUtils.h" -#include "nsIEventQueueService.h" #include "nsIIOService.h" #include "nsIInputStream.h" #include "nsIOutputStream.h" @@ -66,7 +65,7 @@ #include "nsIStreamListener.h" #include "nsIURL.h" #include "nsRDFCID.h" -#include "plevent.h" +#include "nsThreadUtils.h" #include "plstr.h" #include "prio.h" #include "prthread.h" @@ -77,9 +76,6 @@ // rdf static NS_DEFINE_CID(kRDFXMLDataSourceCID, NS_RDFXMLDATASOURCE_CID); -// xpcom -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); - //////////////////////////////////////////////////////////////////////// // Blatantly stolen from netwerk/test/ #define RETURN_IF_FAILED(rv, step) \ @@ -153,15 +149,6 @@ main(int argc, char** argv) NS_InitXPCOM2(nsnull, nsnull, nsnull); - // Get netlib off the floor... - nsCOMPtr theEventQueueService = - do_GetService(kEventQueueServiceCID, &rv); - RETURN_IF_FAILED(rv, "EventQueueService"); - - nsIEventQueue* eq = nsnull; - rv = theEventQueueService->GetThreadEventQueue(NS_CURRENT_THREAD, &eq); - RETURN_IF_FAILED(rv, "GetThreadEventQueue"); - // Create a stream data source and initialize it on argv[1], which // is hopefully a "file:" URL. nsCOMPtr ds = do_CreateInstance(kRDFXMLDataSourceCID, @@ -179,9 +166,12 @@ main(int argc, char** argv) RETURN_IF_FAILED(rv, "datasource refresh"); // Pump events until the load is finished + nsCOMPtr thread = do_GetCurrentThread(); PRBool done = PR_FALSE; while (!done) { - eq->ProcessPendingEvents(); + rv = thread->ProcessNextEvent(); + if (NS_FAILED(rv)) + return rv; remote->GetLoaded(&done); } @@ -197,7 +187,5 @@ main(int argc, char** argv) rv = source->Serialize(out); RETURN_IF_FAILED(rv, "datasoure serialization"); - theEventQueueService->DestroyThreadEventQueue(); - return NS_OK; } diff --git a/mozilla/rdf/tests/rdfpoll/rdfpoll.cpp b/mozilla/rdf/tests/rdfpoll/rdfpoll.cpp index dbd00835eee..2c21d72d7f4 100644 --- a/mozilla/rdf/tests/rdfpoll/rdfpoll.cpp +++ b/mozilla/rdf/tests/rdfpoll/rdfpoll.cpp @@ -51,7 +51,6 @@ #include #include "nsXPCOM.h" #include "nsCOMPtr.h" -#include "nsIEventQueueService.h" #include "nsIInputStream.h" #include "nsIIOService.h" #include "nsIRDFCompositeDataSource.h" @@ -66,8 +65,8 @@ #include "nsRDFCID.h" #include "nsIComponentManager.h" #include "nsComponentManagerUtils.h" +#include "nsThreadUtils.h" #include "prthread.h" -#include "plevent.h" #include "plstr.h" #include "nsEmbedString.h" #include "nsNetCID.h" @@ -78,9 +77,6 @@ // rdf static NS_DEFINE_CID(kRDFXMLDataSourceCID, NS_RDFXMLDATASOURCE_CID); -// xpcom -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); - //////////////////////////////////////////////////////////////////////// // IIDs @@ -260,15 +256,6 @@ main(int argc, char** argv) return 1; } - // Get netlib off the floor... - nsCOMPtr theEventQueueService = - do_GetService(kEventQueueServiceCID, &rv); - if (NS_FAILED(rv)) return rv; - - rv = theEventQueueService->CreateThreadEventQueue(); - NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create thread event queue"); - if (NS_FAILED(rv)) return rv; - // Create a stream data source and initialize it on argv[1], which // is hopefully a "file:" URL. (Actually, we can do _any_ kind of // URL, but only a "file:" URL will be written back to disk.) diff --git a/mozilla/rdf/tests/triplescat/triplescat.cpp b/mozilla/rdf/tests/triplescat/triplescat.cpp index 521c6353b4b..2ee9cf64598 100644 --- a/mozilla/rdf/tests/triplescat/triplescat.cpp +++ b/mozilla/rdf/tests/triplescat/triplescat.cpp @@ -52,7 +52,7 @@ #include "nsIComponentManager.h" #include "nsComponentManagerUtils.h" #include "nsServiceManagerUtils.h" -#include "nsIEventQueueService.h" +#include "nsThreadUtils.h" #include "nsIIOService.h" #include "nsIInputStream.h" #include "nsIOutputStream.h" @@ -65,7 +65,6 @@ #include "nsIStreamListener.h" #include "nsIURL.h" #include "nsRDFCID.h" -#include "plevent.h" #include "plstr.h" #include "prio.h" #include "prthread.h" @@ -148,15 +147,6 @@ main(int argc, char** argv) NS_InitXPCOM2(nsnull, nsnull, nsnull); - // Get netlib off the floor... - nsCOMPtr theEventQueueService = - do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv); - RETURN_IF_FAILED(rv, "EventQueueService"); - - nsIEventQueue* eq = nsnull; - rv = theEventQueueService->GetThreadEventQueue(NS_CURRENT_THREAD, &eq); - RETURN_IF_FAILED(rv, "GetThreadEventQueue"); - // Create a stream data source and initialize it on argv[1], which // is hopefully a "file:" URL. nsCOMPtr ds = @@ -175,9 +165,12 @@ main(int argc, char** argv) RETURN_IF_FAILED(rv, "datasource refresh"); // Pump events until the load is finished + nsCOMPtr thread = do_GetCurrentThread(); PRBool done = PR_FALSE; while (!done) { - eq->ProcessPendingEvents(); + rv = thread->ProcessNextEvent(); + if (NS_FAILED(rv)) + return rv; remote->GetLoaded(&done); } @@ -193,7 +186,5 @@ main(int argc, char** argv) out->Close(); } - theEventQueueService->DestroyThreadEventQueue(); - return NS_OK; } diff --git a/mozilla/security/manager/boot/src/nsSecureBrowserUIImpl.cpp b/mozilla/security/manager/boot/src/nsSecureBrowserUIImpl.cpp index 3320e7efac1..6a4454e40b2 100644 --- a/mozilla/security/manager/boot/src/nsSecureBrowserUIImpl.cpp +++ b/mozilla/security/manager/boot/src/nsSecureBrowserUIImpl.cpp @@ -77,6 +77,7 @@ #include "nsIFormSubmitObserver.h" #include "nsISecurityWarningDialogs.h" #include "nsIProxyObjectManager.h" +#include "nsThreadUtils.h" #include "nsNetUtil.h" #include "nsCRT.h" @@ -1422,9 +1423,9 @@ GetNSSDialogs(nsISecurityWarningDialogs **result) return NS_ERROR_FAILURE; nsCOMPtr proxiedResult; - proxyman->GetProxyForObject(NS_UI_THREAD_EVENTQ, + proxyman->GetProxyForObject(NS_PROXY_TO_MAIN_THREAD, NS_GET_IID(nsISecurityWarningDialogs), - my_result, PROXY_SYNC, + my_result, NS_PROXY_SYNC, getter_AddRefs(proxiedResult)); if (!proxiedResult) { diff --git a/mozilla/security/manager/ssl/src/Makefile.in b/mozilla/security/manager/ssl/src/Makefile.in index e2123e2d8a4..f82978d5fe9 100644 --- a/mozilla/security/manager/ssl/src/Makefile.in +++ b/mozilla/security/manager/ssl/src/Makefile.in @@ -87,7 +87,6 @@ CPPSRCS = \ nsCRLManager.cpp \ nsNSSShutDown.cpp \ nsNTLMAuthModule.cpp \ - nsNSSEvent.cpp \ nsSmartCardMonitor.cpp \ nsSmartCardEvent.cpp \ $(NULL) diff --git a/mozilla/security/manager/ssl/src/nsCrypto.cpp b/mozilla/security/manager/ssl/src/nsCrypto.cpp index 569a75d3458..ecff0212ffc 100644 --- a/mozilla/security/manager/ssl/src/nsCrypto.cpp +++ b/mozilla/security/manager/ssl/src/nsCrypto.cpp @@ -44,6 +44,7 @@ #include "nsNSSCertificateDB.h" #include "nsPKCS12Blob.h" #include "nsPK11TokenDB.h" +#include "nsThreadUtils.h" #include "nsIServiceManager.h" #include "nsIMemory.h" #include "nsCRT.h" @@ -1625,7 +1626,7 @@ nsCrypto::GenerateCRMFRequest(nsIDOMCRMFObject** aReturn) if (!cryptoRunnable) return NS_ERROR_OUT_OF_MEMORY; - nsresult rv = nsNSSEventPostToUIEventQueue(cryptoRunnable); + nsresult rv = NS_DispatchToMainThread(cryptoRunnable); if (NS_FAILED(rv)) delete cryptoRunnable; @@ -2017,7 +2018,7 @@ nsCrypto::ImportUserCertificates(const nsAString& aNickname, // memory on the way out. certArr = nsnull; - rv = nsNSSEventPostToUIEventQueue(p12Runnable); + rv = NS_DispatchToMainThread(p12Runnable); if (NS_FAILED(rv)) goto loser; } @@ -2202,9 +2203,9 @@ nsCrypto::SignText(const nsAString& aStringToSign, const nsAString& aCaOption, } nsCOMPtr proxied_fsd; - nsresult rv = proxyman->GetProxyForObject(NS_UI_THREAD_EVENTQ, + nsresult rv = proxyman->GetProxyForObject(NS_PROXY_TO_MAIN_THREAD, NS_GET_IID(nsIFormSigningDialog), - fsd, PROXY_SYNC, + fsd, NS_PROXY_SYNC, getter_AddRefs(proxied_fsd)); if (NS_FAILED(rv)) { aResult.Append(internalError); diff --git a/mozilla/security/manager/ssl/src/nsCrypto.h b/mozilla/security/manager/ssl/src/nsCrypto.h index 9520ca1061d..23cc4a1e6e7 100644 --- a/mozilla/security/manager/ssl/src/nsCrypto.h +++ b/mozilla/security/manager/ssl/src/nsCrypto.h @@ -44,10 +44,8 @@ #include "nsIDOMPkcs11.h" #include "nsIRunnable.h" #include "nsString.h" -#include "nsNSSEvent.h" #include "jsapi.h" #include "nsIPrincipal.h" -#include "plevent.h" #define NS_CRYPTO_CLASSNAME "Crypto JavaScript Class" #define NS_CRYPTO_CID \ @@ -108,19 +106,4 @@ public: }; -// -// This is the class we'll use to post ui events -// -struct CryptoRunnableEvent : PLEvent { - CryptoRunnableEvent(nsIRunnable* runnable); - ~CryptoRunnableEvent(); - - nsIRunnable* mRunnable; -}; - - #endif //_nsCrypto_h_ - - - - diff --git a/mozilla/security/manager/ssl/src/nsKeygenThread.cpp b/mozilla/security/manager/ssl/src/nsKeygenThread.cpp index cbaa1541780..1e384cc3fd0 100644 --- a/mozilla/security/manager/ssl/src/nsKeygenThread.cpp +++ b/mozilla/security/manager/ssl/src/nsKeygenThread.cpp @@ -39,6 +39,7 @@ #include "pk11func.h" #include "nsCOMPtr.h" #include "nsProxiedService.h" +#include "nsThreadUtils.h" #include "nsKeygenThread.h" #include "nsIObserver.h" #include "nsNSSShutDown.h" @@ -154,10 +155,10 @@ nsresult nsKeygenThread::StartKeyGeneration(nsIObserver* aObserver) return NS_OK; nsCOMPtr obs; - proxyman->GetProxyForObject( NS_UI_THREAD_EVENTQ, + proxyman->GetProxyForObject( NS_PROXY_TO_MAIN_THREAD, NS_GET_IID(nsIObserver), aObserver, - PROXY_SYNC | PROXY_ALWAYS, + NS_PROXY_SYNC | NS_PROXY_ALWAYS, getter_AddRefs(obs)); PR_Lock(mutex); diff --git a/mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp b/mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp index 142363cdeb8..88cf3bb3068 100644 --- a/mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp +++ b/mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp @@ -54,6 +54,7 @@ #include "nsIInterfaceRequestorUtils.h" #include "nsCRT.h" #include "nsNSSShutDown.h" +#include "nsThreadUtils.h" #include "ssl.h" #include "cert.h" @@ -158,10 +159,10 @@ PK11PasswordPrompt(PK11SlotInfo* slot, PRBool retry, void* arg) { if (!proxyman) return nsnull; nsCOMPtr proxiedCallbacks; - proxyman->GetProxyForObject(NS_UI_THREAD_EVENTQ, + proxyman->GetProxyForObject(NS_PROXY_TO_MAIN_THREAD, NS_GET_IID(nsIInterfaceRequestor), ir, - PROXY_SYNC, + NS_PROXY_SYNC, getter_AddRefs(proxiedCallbacks)); // Get the desired interface @@ -172,10 +173,10 @@ PK11PasswordPrompt(PK11SlotInfo* slot, PRBool retry, void* arg) { } // Finally, get a proxy for the nsIPrompt - proxyman->GetProxyForObject(NS_UI_THREAD_EVENTQ, - NS_GET_IID(nsIPrompt), + proxyman->GetProxyForObject(NS_PROXY_TO_MAIN_THREAD, + NS_GET_IID(nsIPrompt), prompt, - PROXY_SYNC, + NS_PROXY_SYNC, getter_AddRefs(proxyPrompt)); diff --git a/mozilla/security/manager/ssl/src/nsNSSCertificate.cpp b/mozilla/security/manager/ssl/src/nsNSSCertificate.cpp index a1362650794..cad844d7f86 100644 --- a/mozilla/security/manager/ssl/src/nsNSSCertificate.cpp +++ b/mozilla/security/manager/ssl/src/nsNSSCertificate.cpp @@ -64,6 +64,7 @@ #include "nsNSSCertHelper.h" #include "nsISupportsPrimitives.h" #include "nsUnicharUtils.h" +#include "nsThreadUtils.h" #include "nspr.h" extern "C" { @@ -218,10 +219,10 @@ nsNSSCertificate::FormatUIStrings(const nsAutoString &nickname, nsAutoString &ni } nsCOMPtr x509Proxy; - proxyman->GetProxyForObject( NS_UI_THREAD_EVENTQ, + proxyman->GetProxyForObject( NS_PROXY_TO_MAIN_THREAD, nsIX509Cert::GetIID(), NS_STATIC_CAST(nsIX509Cert*, this), - PROXY_SYNC | PROXY_ALWAYS, + NS_PROXY_SYNC | NS_PROXY_ALWAYS, getter_AddRefs(x509Proxy)); if (!x509Proxy) { @@ -265,10 +266,10 @@ nsNSSCertificate::FormatUIStrings(const nsAutoString &nickname, nsAutoString &ni nsCOMPtr originalValidity; rv = x509Proxy->GetValidity(getter_AddRefs(originalValidity)); if (NS_SUCCEEDED(rv) && originalValidity) { - proxyman->GetProxyForObject( NS_UI_THREAD_EVENTQ, + proxyman->GetProxyForObject( NS_PROXY_TO_MAIN_THREAD, nsIX509CertValidity::GetIID(), originalValidity, - PROXY_SYNC | PROXY_ALWAYS, + NS_PROXY_SYNC | NS_PROXY_ALWAYS, getter_AddRefs(validity)); } diff --git a/mozilla/security/manager/ssl/src/nsNSSComponent.cpp b/mozilla/security/manager/ssl/src/nsNSSComponent.cpp index a95dbde47a3..88190ab183d 100644 --- a/mozilla/security/manager/ssl/src/nsNSSComponent.cpp +++ b/mozilla/security/manager/ssl/src/nsNSSComponent.cpp @@ -44,7 +44,6 @@ #include "nsNSSComponent.h" #include "nsNSSCallbacks.h" #include "nsNSSIOLayer.h" -#include "nsNSSEvent.h" #include "nsNetUtil.h" #include "nsAppDirectoryServiceDefs.h" @@ -69,7 +68,6 @@ #include "nsIDateTimeFormat.h" #include "nsDateTimeFormatCID.h" #include "nsAutoLock.h" -#include "nsIEventQueue.h" #include "nsIDOMEvent.h" #include "nsIDOMDocument.h" #include "nsIDOMDocumentEvent.h" @@ -78,8 +76,8 @@ #include "nsIDOMWindowInternal.h" #include "nsIDOMSmartCardEvent.h" #include "nsIDOMCrypto.h" -#include "nsIRunnable.h" -#include "plevent.h" +#include "nsThreadUtils.h" +#include "nsAutoPtr.h" #include "nsCRT.h" #include "nsCRLInfo.h" @@ -204,39 +202,34 @@ static PRIntn PR_CALLBACK certHashtable_clearEntry(PLHashEntry *he, PRIntn /*ind return HT_ENUMERATE_NEXT; } -struct CRLDownloadEvent : PLEvent { - nsCAutoString *urlString; - nsIStreamListener *psmDownloader; -}; +class CRLDownloadEvent : public nsRunnable { +public: + CRLDownloadEvent(const nsCSubstring &urlString, nsIStreamListener *listener) + : mURLString(urlString) + , mListener(listener) + {} -// Note that nsNSSComponent is a singleton object across all threads, -// and automatic downloads are always scheduled sequentially - that is, -// once one crl download is complete, the next one is scheduled -static void* PR_CALLBACK HandleCRLImportPLEvent(PLEvent *aEvent) -{ - CRLDownloadEvent *event = NS_STATIC_CAST(CRLDownloadEvent*, aEvent); + // Note that nsNSSComponent is a singleton object across all threads, + // and automatic downloads are always scheduled sequentially - that is, + // once one crl download is complete, the next one is scheduled + NS_IMETHOD Run() + { + if (!mListener || mURLString.IsEmpty()) + return NS_OK; - nsresult rv; - nsIURI *pURL; - - if((event->psmDownloader==nsnull) || (event->urlString==nsnull) ) - return nsnull; + nsCOMPtr uri; + nsresult rv = NS_NewURI(getter_AddRefs(uri), mURLString); + if (NS_SUCCEEDED(rv)){ + NS_OpenURI(mListener, nsnull, uri); + } - rv = NS_NewURI(&pURL, event->urlString->get()); - if(NS_SUCCEEDED(rv)){ - NS_OpenURI(event->psmDownloader, nsnull, pURL); + return NS_OK; } - return nsnull; -} - -static void PR_CALLBACK DestroyCRLImportPLEvent(PLEvent* aEvent) -{ - CRLDownloadEvent *event = NS_STATIC_CAST(CRLDownloadEvent*, aEvent); - - delete event->urlString; - delete event; -} +private: + nsCString mURLString; + nsCOMPtr mListener; +}; //This class is used to run the callback code //passed to the event handlers for smart card notification @@ -335,18 +328,13 @@ NS_IMETHODIMP nsNSSComponent::PostEvent(const nsAString &eventType, const nsAString &tokenName) { - nsresult rv; - nsTokenEventRunnable *runnable = + nsCOMPtr runnable = new nsTokenEventRunnable(eventType, tokenName); if (!runnable) { return NS_ERROR_OUT_OF_MEMORY; } - rv = nsNSSEventPostToUIEventQueue(runnable); - if (NS_FAILED(rv)) - delete runnable; - - return rv; + return NS_DispatchToMainThread(runnable); } @@ -901,24 +889,16 @@ static void setOCSPOptions(nsIPrefBranch * pref) } nsresult -nsNSSComponent::PostCRLImportEvent(nsCAutoString *urlString, PSMContentDownloader *psmDownloader) +nsNSSComponent::PostCRLImportEvent(const nsCSubstring &urlString, + nsIStreamListener *listener) { //Create the event - CRLDownloadEvent *event = new CRLDownloadEvent; - PL_InitEvent(event, this, HandleCRLImportPLEvent, DestroyCRLImportPLEvent); - event->urlString = urlString; - event->psmDownloader = (nsIStreamListener *)psmDownloader; - - //Get a handle to the ui event queue - - nsCOMPtruiQueue = nsNSSEventGetUIEventQueue(); + nsCOMPtr event = new CRLDownloadEvent(urlString, listener); + if (!event) + return NS_ERROR_OUT_OF_MEMORY; - if (!uiQueue) { - return NS_ERROR_FAILURE; - } - - //Post the event - return uiQueue->PostEvent(event); + //Get a handle to the ui thread + return NS_DispatchToMainThread(event); } nsresult @@ -926,12 +906,11 @@ nsNSSComponent::DownloadCRLDirectly(nsAutoString url, nsAutoString key) { //This api is meant to support direct interactive update of crl from the crl manager //or other such ui. - PSMContentDownloader *psmDownloader = new PSMContentDownloader(PSMContentDownloader::PKCS7_CRL); + nsCOMPtr listener = + new PSMContentDownloader(PSMContentDownloader::PKCS7_CRL); - nsCAutoString *urlString = new nsCAutoString(); - urlString->AssignWithConversion(url.get()); - - return PostCRLImportEvent(urlString, psmDownloader); + NS_ConvertUTF16toUTF8 url8(url); + return PostCRLImportEvent(url8, listener); } nsresult nsNSSComponent::DownloadCrlSilently() @@ -941,15 +920,14 @@ nsresult nsNSSComponent::DownloadCrlSilently() crlsScheduledForDownload->Put(&hashKey,(void *)nsnull); //Set up the download handler - PSMContentDownloader *psmDownloader = new PSMContentDownloader(PSMContentDownloader::PKCS7_CRL); + nsRefPtr psmDownloader = + new PSMContentDownloader(PSMContentDownloader::PKCS7_CRL); psmDownloader->setSilentDownload(PR_TRUE); psmDownloader->setCrlAutodownloadKey(mCrlUpdateKey); //Now get the url string - nsCAutoString *urlString = new nsCAutoString(); - urlString->AssignWithConversion(mDownloadURL); - - return PostCRLImportEvent(urlString, psmDownloader); + NS_ConvertUTF16toUTF8 url8(mDownloadURL); + return PostCRLImportEvent(url8, psmDownloader); } nsresult nsNSSComponent::getParamsForNextCrlToDownload(nsAutoString *url, PRTime *time, nsAutoString *key) @@ -1973,8 +1951,10 @@ void nsNSSComponent::ShowAlert(AlertIdentifier ai) } else { nsCOMPtr proxyPrompt; - proxyman->GetProxyForObject(NS_UI_THREAD_EVENTQ, NS_GET_IID(nsIPrompt), - prompter, PROXY_SYNC, getter_AddRefs(proxyPrompt)); + proxyman->GetProxyForObject(NS_PROXY_TO_MAIN_THREAD, + NS_GET_IID(nsIPrompt), + prompter, NS_PROXY_SYNC, + getter_AddRefs(proxyPrompt)); if (!proxyPrompt) { PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("can't get proxy for nsIPrompt\n")); } @@ -2224,8 +2204,10 @@ NS_IMETHODIMP PipUIContext::GetInterface(const nsIID & uuid, void * *result) wwatch->GetNewPrompter(0, getter_AddRefs(prompter)); if (prompter) { nsCOMPtr proxyPrompt; - proxyman->GetProxyForObject(NS_UI_THREAD_EVENTQ, NS_GET_IID(nsIPrompt), - prompter, PROXY_SYNC, getter_AddRefs(proxyPrompt)); + proxyman->GetProxyForObject(NS_PROXY_TO_MAIN_THREAD, + NS_GET_IID(nsIPrompt), + prompter, NS_PROXY_SYNC, + getter_AddRefs(proxyPrompt)); if (!proxyPrompt) return NS_ERROR_FAILURE; *result = proxyPrompt; NS_ADDREF((nsIPrompt*)*result); @@ -2252,8 +2234,8 @@ getNSSDialogs(void **_result, REFNSIID aIID, const char *contract) if (NS_FAILED(rv)) return rv; - rv = proxyman->GetProxyForObject(NS_UI_THREAD_EVENTQ, - aIID, svc, PROXY_SYNC, + rv = proxyman->GetProxyForObject(NS_PROXY_TO_MAIN_THREAD, + aIID, svc, NS_PROXY_SYNC, _result); return rv; } @@ -2309,8 +2291,7 @@ PSMContentDownloader::~PSMContentDownloader() nsMemory::Free(mByteData); } -/*NS_IMPL_ISUPPORTS1(CertDownloader, nsIStreamListener)*/ -NS_IMPL_ISUPPORTS1(PSMContentDownloader,nsIStreamListener) +NS_IMPL_ISUPPORTS2(PSMContentDownloader, nsIStreamListener, nsIRequestObserver) const PRInt32 kDefaultCertAllocLength = 2048; diff --git a/mozilla/security/manager/ssl/src/nsNSSComponent.h b/mozilla/security/manager/ssl/src/nsNSSComponent.h index caaeb644b3b..b9e98c95d4f 100644 --- a/mozilla/security/manager/ssl/src/nsNSSComponent.h +++ b/mozilla/security/manager/ssl/src/nsNSSComponent.h @@ -247,7 +247,7 @@ private: nsresult RegisterPSMContentListener(); nsresult RegisterObservers(); nsresult DownloadCrlSilently(); - nsresult PostCRLImportEvent(nsCAutoString *urlString, PSMContentDownloader *psmDownloader); + nsresult PostCRLImportEvent(const nsCSubstring &urlString, nsIStreamListener *psmDownloader); nsresult getParamsForNextCrlToDownload(nsAutoString *url, PRTime *time, nsAutoString *key); nsresult DispatchEventToWindow(nsIDOMWindow *domWin, const nsAString &eventType, const nsAString &token); PRLock *mutex; diff --git a/mozilla/security/manager/ssl/src/nsNSSEvent.cpp b/mozilla/security/manager/ssl/src/nsNSSEvent.cpp index 1f63c6c6d14..b5696533540 100644 --- a/mozilla/security/manager/ssl/src/nsNSSEvent.cpp +++ b/mozilla/security/manager/ssl/src/nsNSSEvent.cpp @@ -36,77 +36,14 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ + #include "nsCOMPtr.h" -#include "nsIServiceManager.h" #include "nsNSSEvent.h" -#include "plevent.h" -#include "nsIRunnable.h" -#include "nsIEventQueueService.h" -#include "nsIEventQueue.h" - -// -// This is the class we'll use to post ui events -// -struct nsNSSEventRunnable : PLEvent { - nsNSSEventRunnable(nsIRunnable* runnable); - ~nsNSSEventRunnable(); - - nsCOMPtr mRunnable; -}; - -//Grab the UI event queue so that we can post some events to it. -already_AddRefed -nsNSSEventGetUIEventQueue() -{ - nsresult rv; - nsCOMPtr service = - do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv); - if (NS_FAILED(rv)) - return nsnull; - - nsIEventQueue* result = nsnull; - rv = service->GetThreadEventQueue(NS_UI_THREAD, &result); - if (NS_FAILED(rv)) - return nsnull; - - return result; -} +#include "nsThreadUtils.h" // post something to it nsresult -nsNSSEventPostToUIEventQueue(nsIRunnable *event) +nsNSSEventPostToUIThread(nsIRunnable *event) { - nsNSSEventRunnable *runnable = new nsNSSEventRunnable(event); - if (!runnable) { - return NS_ERROR_OUT_OF_MEMORY; - } - nsCOMPtruiQueue = nsNSSEventGetUIEventQueue(); - uiQueue->PostEvent(runnable); - return NS_OK; + return NS_DispatchToMainThread(event); } - -//A wrapper for PLEvent that we can use to post -//our nsIRunnable Events. -static void PR_CALLBACK -handleNSSEventRunnable(nsNSSEventRunnable* aEvent) -{ - aEvent->mRunnable->Run(); -} - -static void PR_CALLBACK -destroyNSSEventRunnable(nsNSSEventRunnable* aEvent) -{ - delete aEvent; -} - -nsNSSEventRunnable::nsNSSEventRunnable(nsIRunnable* runnable) - : mRunnable(runnable) -{ - PL_InitEvent(this, nsnull, PLHandleEventProc(handleNSSEventRunnable), - PLDestroyEventProc(&destroyNSSEventRunnable)); -} - -nsNSSEventRunnable::~nsNSSEventRunnable() -{ -} - diff --git a/mozilla/security/manager/ssl/src/nsNSSEvent.h b/mozilla/security/manager/ssl/src/nsNSSEvent.h index 68780eb6633..a5b037acd48 100644 --- a/mozilla/security/manager/ssl/src/nsNSSEvent.h +++ b/mozilla/security/manager/ssl/src/nsNSSEvent.h @@ -40,15 +40,9 @@ #define NSS_EVENT_ #include "nsIRunnable.h" -#include "nsIEventQueueService.h" -#include "nsIEventQueue.h" - - -//Grab the UI event queue so that we can post some events to it. -already_AddRefed nsNSSEventGetUIEventQueue(); // post something to it -nsresult nsNSSEventPostToUIEventQueue(nsIRunnable *event); +nsresult nsNSSEventPostToUIThread(nsIRunnable *event); #endif diff --git a/mozilla/security/manager/ssl/src/nsNSSIOLayer.cpp b/mozilla/security/manager/ssl/src/nsNSSIOLayer.cpp index 1b62b2a5810..a7b9e950ce4 100644 --- a/mozilla/security/manager/ssl/src/nsNSSIOLayer.cpp +++ b/mozilla/security/manager/ssl/src/nsNSSIOLayer.cpp @@ -62,9 +62,11 @@ #include "nsReadableUtils.h" #include "nsHashSets.h" #include "nsCRT.h" +#include "nsAutoPtr.h" #include "nsPrintfCString.h" #include "nsNSSShutDown.h" #include "nsNSSCertHelper.h" +#include "nsThreadUtils.h" #include "ssl.h" #include "secerr.h" @@ -263,10 +265,10 @@ nsNSSSocketInfo::SetNotificationCallbacks(nsIInterfaceRequestor* aCallbacks) return NS_ERROR_FAILURE; nsCOMPtr proxiedCallbacks; - proxyman->GetProxyForObject(NS_UI_THREAD_EVENTQ, + proxyman->GetProxyForObject(NS_PROXY_TO_MAIN_THREAD, NS_GET_IID(nsIInterfaceRequestor), NS_STATIC_CAST(nsIInterfaceRequestor*,aCallbacks), - PROXY_SYNC, + NS_PROXY_SYNC, getter_AddRefs(proxiedCallbacks)); mCallbacks = proxiedCallbacks; @@ -442,12 +444,12 @@ displayAlert(nsAFlatString &formattedString, nsNSSSocketInfo *infoObject) nsCOMPtr proxyman(do_GetService(NS_XPCOMPROXY_CONTRACTID)); if (!proxyman) return NS_ERROR_FAILURE; - + nsCOMPtr proxiedCallbacks; - proxyman->GetProxyForObject(NS_UI_THREAD_EVENTQ, + proxyman->GetProxyForObject(NS_PROXY_TO_MAIN_THREAD, NS_GET_IID(nsIInterfaceRequestor), NS_STATIC_CAST(nsIInterfaceRequestor*,infoObject), - PROXY_SYNC, + NS_PROXY_SYNC, getter_AddRefs(proxiedCallbacks)); nsCOMPtr prompt (do_GetInterface(proxiedCallbacks)); @@ -457,10 +459,10 @@ displayAlert(nsAFlatString &formattedString, nsNSSSocketInfo *infoObject) nsCOMPtr proxyPrompt; // Finally, get a proxy for the nsIPrompt - proxyman->GetProxyForObject(NS_UI_THREAD_EVENTQ, + proxyman->GetProxyForObject(NS_PROXY_TO_MAIN_THREAD, NS_GET_IID(nsIPrompt), prompt, - PROXY_SYNC, + NS_PROXY_SYNC, getter_AddRefs(proxyPrompt)); proxyPrompt->Alert(nsnull, formattedString.get()); return NS_OK; @@ -1267,12 +1269,13 @@ nsContinueDespiteCertError(nsNSSSocketInfo *infoObject, infoObject->GetNotificationCallbacks(getter_AddRefs(callbacks)); if (callbacks) { nsCOMPtr handler = do_GetInterface(callbacks); - if (handler) - NS_GetProxyForObject(NS_UI_THREAD_EVENTQ, + if (handler) { + NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD, NS_GET_IID(nsIBadCertListener), handler, - PROXY_SYNC, + NS_PROXY_SYNC, (void**)&badCertHandler); + } } if (!badCertHandler) { rv = getNSSDialogs((void**)&badCertHandler, diff --git a/mozilla/security/manager/ssl/src/nsPKCS12Blob.cpp b/mozilla/security/manager/ssl/src/nsPKCS12Blob.cpp index 504dcd23e14..4b265eda2a3 100644 --- a/mozilla/security/manager/ssl/src/nsPKCS12Blob.cpp +++ b/mozilla/security/manager/ssl/src/nsPKCS12Blob.cpp @@ -34,7 +34,7 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -/* $Id: nsPKCS12Blob.cpp,v 1.46 2006-02-03 14:18:28 cbiesinger%web.de Exp $ */ +/* $Id: nsPKCS12Blob.cpp,v 1.46.6.1 2006-03-09 16:01:49 darin%meer.net Exp $ */ #include "prmem.h" #include "prprf.h" @@ -47,6 +47,7 @@ #include "nsIWindowWatcher.h" #include "nsIPrompt.h" #include "nsProxiedService.h" +#include "nsThreadUtils.h" #include "nsNSSComponent.h" #include "nsNSSHelper.h" @@ -852,9 +853,9 @@ nsPKCS12Blob::handleError(int myerr) wwatch->GetNewPrompter(0, getter_AddRefs(errPrompt)); if (errPrompt) { nsCOMPtr proxyPrompt; - proxyman->GetProxyForObject(NS_UI_THREAD_EVENTQ, NS_GET_IID(nsIPrompt), - errPrompt, PROXY_SYNC, - getter_AddRefs(proxyPrompt)); + proxyman->GetProxyForObject(NS_PROXY_TO_MAIN_THREAD, + NS_GET_IID(nsIPrompt), errPrompt, + NS_PROXY_SYNC, getter_AddRefs(proxyPrompt)); if (!proxyPrompt) return PR_FALSE; } else { return PR_FALSE; diff --git a/mozilla/security/manager/ssl/src/nsSDR.cpp b/mozilla/security/manager/ssl/src/nsSDR.cpp index 1b96c5e4d63..4c62cee6908 100644 --- a/mozilla/security/manager/ssl/src/nsSDR.cpp +++ b/mozilla/security/manager/ssl/src/nsSDR.cpp @@ -44,7 +44,7 @@ #include "nsMemory.h" #include "nsString.h" #include "nsCOMPtr.h" -#include "nsISupports.h" +#include "nsThreadUtils.h" #include "nsIInterfaceRequestor.h" #include "nsIInterfaceRequestorUtils.h" #include "nsIServiceManager.h" @@ -104,8 +104,10 @@ NS_IMETHODIMP nsSDRContext::GetInterface(const nsIID & uuid, void * *result) wwatch->GetNewPrompter(0, getter_AddRefs(prompter)); if (prompter) { nsCOMPtr proxyPrompt; - proxyman->GetProxyForObject(NS_UI_THREAD_EVENTQ, NS_GET_IID(nsIPrompt), - prompter, PROXY_SYNC, getter_AddRefs(proxyPrompt)); + proxyman->GetProxyForObject(NS_PROXY_TO_MAIN_THREAD, + NS_GET_IID(nsIPrompt), + prompter, NS_PROXY_SYNC, + getter_AddRefs(proxyPrompt)); if (!proxyPrompt) return NS_ERROR_FAILURE; *result = proxyPrompt; NS_ADDREF((nsIPrompt*)*result); diff --git a/mozilla/storage/src/mozStorageAsyncIO.cpp b/mozilla/storage/src/mozStorageAsyncIO.cpp index 96f593f4ec4..dd93d0e4925 100644 --- a/mozilla/storage/src/mozStorageAsyncIO.cpp +++ b/mozilla/storage/src/mozStorageAsyncIO.cpp @@ -231,7 +231,7 @@ #include "mozStorageService.h" #include "nsAutoLock.h" -#include "nsEventQueueUtils.h" +#include "nsThreadUtils.h" #include "nsIRunnable.h" #include "nsIThread.h" #include "nsMemory.h" @@ -447,12 +447,12 @@ public: // this will delay processing the release of the storage service until we // get to the main thread. - nsCOMPtr eventQueue; - nsresult rv = NS_GetMainEventQ(getter_AddRefs(eventQueue)); + nsCOMPtr mainThread; + nsresult rv = NS_GetMainThread(getter_AddRefs(mainThread)); if (NS_SUCCEEDED(rv)) { mozIStorageService* service = nsnull; mStorageService.swap(service); - NS_ProxyRelease(eventQueue, service); + NS_ProxyRelease(mainThread, service); } else { NS_NOTREACHED("No event queue"); } diff --git a/mozilla/toolkit/components/startup/src/nsAppStartup.cpp b/mozilla/toolkit/components/startup/src/nsAppStartup.cpp index 7f8cff46470..935808859da 100644 --- a/mozilla/toolkit/components/startup/src/nsAppStartup.cpp +++ b/mozilla/toolkit/components/startup/src/nsAppStartup.cpp @@ -44,8 +44,6 @@ #include "nsIAppShellService.h" #include "nsICloseAllWindows.h" #include "nsIDOMWindowInternal.h" -#include "nsIEventQueue.h" -#include "nsIEventQueueService.h" #include "nsIInterfaceRequestor.h" #include "nsILocalFile.h" #include "nsIObserverService.h" @@ -61,16 +59,35 @@ #include "nsIWindowWatcher.h" #include "nsIXULWindow.h" #include "nsNativeCharsetUtils.h" +#include "nsThreadUtils.h" +#include "nsAutoPtr.h" #include "prprf.h" #include "nsCRT.h" -#include "nsEventQueueUtils.h" #include "nsIInterfaceRequestorUtils.h" #include "nsWidgetsCID.h" #include "nsAppShellCID.h" #include "nsXPFEComponentsCID.h" -NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID); +static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID); + +class nsAppExitEvent : public nsRunnable { +private: + nsRefPtr mService; + +public: + nsAppExitEvent(nsAppStartup *service) : mService(service) {} + + NS_IMETHOD Run() { + // Tell the appshell to exit + mService->mAppShell->Exit(); + + // We're done "shutting down". + mService->mShuttingDown = PR_FALSE; + mService->mRunning = PR_FALSE; + return NS_OK; + } +}; // // nsAppStartup @@ -91,10 +108,10 @@ nsAppStartup::Init() nsresult rv; // Create widget application shell - mAppShell = do_CreateInstance(kAppShellCID, &rv); + mAppShell = do_GetService(kAppShellCID, &rv); NS_ENSURE_SUCCESS(rv, rv); - rv = mAppShell->Create(nsnull, nsnull); + rv = mAppShell->Init(nsnull, nsnull); NS_ENSURE_SUCCESS(rv, rv); // listen to EventQueues' comings and goings. do this after the appshell @@ -104,8 +121,6 @@ nsAppStartup::Init() (do_GetService("@mozilla.org/observer-service;1", &rv)); NS_ENSURE_SUCCESS(rv, rv); - os->AddObserver(this, "nsIEventQueueActivated", PR_TRUE); - os->AddObserver(this, "nsIEventQueueDestroyed", PR_TRUE); os->AddObserver(this, "profile-change-teardown", PR_TRUE); os->AddObserver(this, "xul-window-registered", PR_TRUE); os->AddObserver(this, "xul-window-destroyed", PR_TRUE); @@ -173,7 +188,7 @@ nsAppStartup::Quit(PRUint32 aMode) PRUint32 ferocity = (aMode & 0xF); // Quit the application. We will asynchronously call the appshell's - // Exit() method via HandleExitEvent() to allow one last pass + // Exit() method via nsAppExitEvent to allow one last pass // through any events in the queue. This guarantees a tidy cleanup. nsresult rv = NS_OK; PRBool postedExitEvent = PR_FALSE; @@ -296,28 +311,13 @@ nsAppStartup::Quit(PRUint32 aMode) // no matter what, make sure we send the exit event. If // worst comes to worst, we'll do a leaky shutdown but we WILL // shut down. Well, assuming that all *this* stuff works ;-). - nsCOMPtr queue; - rv = NS_GetMainEventQ(getter_AddRefs(queue)); + nsCOMPtr event = new nsAppExitEvent(this); + rv = NS_DispatchToCurrentThread(event); if (NS_SUCCEEDED(rv)) { - PLEvent* event = new PLEvent; - if (event) { - NS_ADDREF_THIS(); - PL_InitEvent(event, - this, - HandleExitEvent, - DestroyExitEvent); - - rv = queue->PostEvent(event); - if (NS_SUCCEEDED(rv)) { - postedExitEvent = PR_TRUE; - } - else { - PL_DestroyEvent(event); - } - } - else { - rv = NS_ERROR_OUT_OF_MEMORY; - } + postedExitEvent = PR_TRUE; + } + else { + NS_WARNING("failed to dispatch nsAppExitEvent"); } } } @@ -371,33 +371,6 @@ nsAppStartup::ExitLastWindowClosingSurvivalArea(void) return NS_OK; } - -void* PR_CALLBACK -nsAppStartup::HandleExitEvent(PLEvent* aEvent) -{ - nsAppStartup *service = - NS_REINTERPRET_CAST(nsAppStartup*, aEvent->owner); - - // Tell the appshell to exit - service->mAppShell->Exit(); - - // We're done "shutting down". - service->mShuttingDown = PR_FALSE; - service->mRunning = PR_FALSE; - - return nsnull; -} - -void PR_CALLBACK -nsAppStartup::DestroyExitEvent(PLEvent* aEvent) -{ - nsAppStartup *service = - NS_REINTERPRET_CAST(nsAppStartup*, aEvent->owner); - NS_RELEASE(service); - delete aEvent; -} - - // // nsAppStartup->nsIWindowCreator // @@ -477,25 +450,7 @@ nsAppStartup::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData) { NS_ASSERTION(mAppShell, "appshell service notified before appshell built"); - if (!strcmp(aTopic, "nsIEventQueueActivated")) { - nsCOMPtr eq(do_QueryInterface(aSubject)); - if (eq) { - PRBool isNative = PR_TRUE; - // we only add native event queues to the appshell - eq->IsQueueNative(&isNative); - if (isNative) - mAppShell->ListenToEventQueue(eq, PR_TRUE); - } - } else if (!strcmp(aTopic, "nsIEventQueueDestroyed")) { - nsCOMPtr eq(do_QueryInterface(aSubject)); - if (eq) { - PRBool isNative = PR_TRUE; - // we only remove native event queues from the appshell - eq->IsQueueNative(&isNative); - if (isNative) - mAppShell->ListenToEventQueue(eq, PR_FALSE); - } - } else if (!strcmp(aTopic, "profile-change-teardown")) { + if (!strcmp(aTopic, "profile-change-teardown")) { nsresult rv; EnterLastWindowClosingSurvivalArea(); // NOTE: No early error exits because we need to execute the diff --git a/mozilla/toolkit/components/startup/src/nsAppStartup.h b/mozilla/toolkit/components/startup/src/nsAppStartup.h index e6c4bd86908..53a1c852351 100644 --- a/mozilla/toolkit/components/startup/src/nsAppStartup.h +++ b/mozilla/toolkit/components/startup/src/nsAppStartup.h @@ -75,9 +75,7 @@ private: void AttemptingQuit(PRBool aAttempt); - // A "last event" that is used to flush the appshell's event queue. - PR_STATIC_CALLBACK(void*) HandleExitEvent(PLEvent* aEvent); - PR_STATIC_CALLBACK(void) DestroyExitEvent(PLEvent* aEvent); + friend class nsAppExitEvent; nsCOMPtr mAppShell; diff --git a/mozilla/toolkit/xre/nsAppRunner.cpp b/mozilla/toolkit/xre/nsAppRunner.cpp index 6951468ea93..c5f048dc22e 100644 --- a/mozilla/toolkit/xre/nsAppRunner.cpp +++ b/mozilla/toolkit/xre/nsAppRunner.cpp @@ -54,7 +54,6 @@ #ifdef XP_OS2 #include "private/pprthred.h" #endif -#include "plevent.h" #include "prmem.h" #include "prnetdb.h" #include "prprf.h" @@ -73,7 +72,6 @@ #include "nsIContentHandler.h" #include "nsIDialogParamBlock.h" #include "nsIDOMWindow.h" -#include "nsIEventQueueService.h" #include "nsIExtensionManager.h" #include "nsIFastLoadService.h" // for PLATFORM_FASL_SUFFIX #include "nsIGenericFactory.h" @@ -539,7 +537,6 @@ public: nsresult Initialize(); nsresult DoAutoreg(); nsresult RegisterProfileService(nsIToolkitProfileService* aProfileService); - nsresult InitEventQueue(); nsresult SetWindowCreator(nsINativeAppSupport* native); private: @@ -634,21 +631,6 @@ ScopedXPCOMStartup::RegisterProfileService(nsIToolkitProfileService* aProfileSer factory); } -nsresult -ScopedXPCOMStartup::InitEventQueue() -{ - NS_TIMELINE_ENTER("init event service"); - nsresult rv; - - nsCOMPtr eventQService(do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv)); - NS_ENSURE_SUCCESS(rv, rv); - - rv = eventQService->CreateThreadEventQueue(); - NS_TIMELINE_LEAVE("init event service"); - - return rv; -} - nsresult ScopedXPCOMStartup::DoAutoreg() { @@ -1251,7 +1233,6 @@ ProfileLockedDialog(nsILocalFile* aProfileDir, nsILocalFile* aProfileLocalDir, NS_ENSURE_SUCCESS(rv, rv); rv = xpcom.DoAutoreg(); - rv |= xpcom.InitEventQueue(); rv |= xpcom.SetWindowCreator(aNative); NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); @@ -1328,7 +1309,6 @@ ShowProfileManager(nsIToolkitProfileService* aProfileSvc, rv = xpcom.RegisterProfileService(aProfileSvc); rv |= xpcom.DoAutoreg(); - rv |= xpcom.InitEventQueue(); rv |= xpcom.SetWindowCreator(aNative); NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); @@ -2203,7 +2183,6 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData) rv = xpcom.Initialize(); NS_ENSURE_SUCCESS(rv, 1); rv = xpcom.DoAutoreg(); - rv |= xpcom.InitEventQueue(); rv |= xpcom.SetWindowCreator(nativeApp); NS_ENSURE_SUCCESS(rv, 1); diff --git a/mozilla/toolkit/xre/nsEmbedFunctions.cpp b/mozilla/toolkit/xre/nsEmbedFunctions.cpp index 4725d8815e6..2cd9f4f60bf 100644 --- a/mozilla/toolkit/xre/nsEmbedFunctions.cpp +++ b/mozilla/toolkit/xre/nsEmbedFunctions.cpp @@ -41,7 +41,6 @@ #include "nsIAppStartupNotifier.h" #include "nsIDirectoryService.h" -#include "nsIEventQueueService.h" #include "nsILocalFile.h" #include "nsIToolkitChromeRegistry.h" @@ -131,15 +130,6 @@ XRE_InitEmbedding(nsILocalFile *aLibXULDirectory, // to autoregister every time (for instance, if it's debug), it can do // so after we return from this function. - nsCOMPtr eventQService - (do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv)); - if (NS_FAILED(rv)) - return rv; - - rv = eventQService->CreateThreadEventQueue(); - if (NS_FAILED(rv)) - return rv; - nsCOMPtr startupNotifier (do_CreateInstance(NS_APPSTARTUPNOTIFIER_CONTRACTID)); if (!startupNotifier) diff --git a/mozilla/tools/test-harness/xpcshell-simple/head.js b/mozilla/tools/test-harness/xpcshell-simple/head.js index 6342570a945..a34938b1c4f 100644 --- a/mozilla/tools/test-harness/xpcshell-simple/head.js +++ b/mozilla/tools/test-harness/xpcshell-simple/head.js @@ -39,13 +39,8 @@ // This file contains common code that is loaded with each test file. -const nsIEventQueueService = Components.interfaces.nsIEventQueueService; -const nsIEventQueue = Components.interfaces.nsIEventQueue; - -var _eqs; var _quit = false; var _fail = false; -var _running_event_loop = false; var _tests_pending = 0; function _TimerCallback(expr) { @@ -75,29 +70,20 @@ function do_main() { return; dump("*** running event loop\n"); - var eq = _eqs.getSpecialEventQueue(_eqs.CURRENT_THREAD_EVENT_QUEUE); + var thr = Components.classes["@mozilla.org/thread-manager;1"] + .getService().currentThread; - _running_event_loop = true; - eq.eventLoop(); // unblocked via interrupt from do_quit() - _running_event_loop = false; + while (!_quit) + thr.processNextEvent(); - // process any remaining events before exiting - eq.processPendingEvents(); - eq.stopAcceptingEvents(); - eq.processPendingEvents(); + while (thr.hasPendingEvents()) + thr.processNextEvent(); } function do_quit() { dump("*** exiting\n"); _quit = true; - - if (_running_event_loop) { - // interrupt the current thread to make eventLoop return. - var thr = Components.classes["@mozilla.org/thread;1"] - .createInstance(Components.interfaces.nsIThread); - thr.currentThread.interrupt(); - } } function do_throw(text) { @@ -132,8 +118,3 @@ function do_test_finished() { if (--_tests_pending == 0) do_quit(); } - -// setup the main thread event queue -_eqs = Components.classes["@mozilla.org/event-queue-service;1"] - .getService(nsIEventQueueService); -_eqs.createMonitoredThreadEventQueue(); diff --git a/mozilla/uriloader/exthandler/nsExternalHelperAppService.cpp b/mozilla/uriloader/exthandler/nsExternalHelperAppService.cpp index 475c4f65ebd..9a9b20dcc48 100644 --- a/mozilla/uriloader/exthandler/nsExternalHelperAppService.cpp +++ b/mozilla/uriloader/exthandler/nsExternalHelperAppService.cpp @@ -61,6 +61,7 @@ #include "nsIRequest.h" #include "nsDirectoryServiceDefs.h" #include "nsIInterfaceRequestor.h" +#include "nsThreadUtils.h" #include "nsAutoPtr.h" // used to manage our in memory data source of helper applications @@ -1075,47 +1076,26 @@ NS_IMETHODIMP nsExternalHelperAppService::LoadUrl(nsIURI * aURL) // that existing callers aren't expecting. We must do it on an event // callback to make sure we don't hang someone up. -struct extLoadRequest : PLEvent { - nsCOMPtr uri; - nsCOMPtr prompt; +class nsExternalLoadRequest : public nsRunnable { + public: + nsExternalLoadRequest(nsIURI *uri, nsIPrompt *prompt) + : mURI(uri), mPrompt(prompt) {} + + NS_IMETHOD Run() { + if (sSrv && sSrv->isExternalLoadOK(mURI, mPrompt)) + sSrv->LoadUriInternal(mURI); + return NS_OK; + } + + private: + nsCOMPtr mURI; + nsCOMPtr mPrompt; }; -void *PR_CALLBACK -nsExternalHelperAppService::handleExternalLoadEvent(PLEvent *event) -{ - extLoadRequest* req = NS_STATIC_CAST(extLoadRequest*, event); - if (req && sSrv && sSrv->isExternalLoadOK(req->uri, req->prompt)) - sSrv->LoadUriInternal(req->uri); - - return nsnull; -} - -static void PR_CALLBACK destroyExternalLoadEvent(PLEvent *event) -{ - delete NS_STATIC_CAST(extLoadRequest*, event); -} - NS_IMETHODIMP nsExternalHelperAppService::LoadURI(nsIURI * aURL, nsIPrompt * aPrompt) { - // post external load event - nsCOMPtr eventQ; - nsresult rv = NS_GetCurrentEventQ(getter_AddRefs(eventQ)); - if (NS_FAILED(rv)) - return rv; - - extLoadRequest *event = new extLoadRequest; - if (!event) - return NS_ERROR_OUT_OF_MEMORY; - - event->uri = aURL; - event->prompt = aPrompt; - PL_InitEvent(event, nsnull, handleExternalLoadEvent, destroyExternalLoadEvent); - - rv = eventQ->PostEvent(event); - if (NS_FAILED(rv)) - PL_DestroyEvent(event); - - return rv; + nsCOMPtr event = new nsExternalLoadRequest(aURL, aPrompt); + return NS_DispatchToCurrentThread(event); } // helper routines used by LoadURI to check whether we're allowed diff --git a/mozilla/uriloader/exthandler/nsExternalHelperAppService.h b/mozilla/uriloader/exthandler/nsExternalHelperAppService.h index bbf2fbdfa70..803fecb1db1 100644 --- a/mozilla/uriloader/exthandler/nsExternalHelperAppService.h +++ b/mozilla/uriloader/exthandler/nsExternalHelperAppService.h @@ -73,7 +73,6 @@ #include "nsCOMArray.h" #include "nsWeakReference.h" #include "nsIPrompt.h" -#include "nsEventQueueUtils.h" class nsExternalAppHandler; class nsIMIMEInfo; @@ -283,6 +282,7 @@ protected: #endif // friend, so that it can access the nspr log module and FixFilePermissions friend class nsExternalAppHandler; + friend class nsExternalLoadRequest; /** * Functions related to the tempory file cleanup service provided by @@ -300,9 +300,6 @@ protected: virtual NS_HIDDEN_(nsresult) LoadUriInternal(nsIURI * aURL) = 0; NS_HIDDEN_(PRBool) isExternalLoadOK(nsIURI* aURI, nsIPrompt* aPrompt); NS_HIDDEN_(PRBool) promptForScheme(nsIURI* aURI, nsIPrompt* aPrompt, PRBool *aRemember); - - // friend event handler that accesses the external loading functions - static void *PR_CALLBACK handleExternalLoadEvent(PLEvent *event); }; /** diff --git a/mozilla/uriloader/exthandler/nsExternalProtocolHandler.cpp b/mozilla/uriloader/exthandler/nsExternalProtocolHandler.cpp index 573a39ff26b..cc185b41450 100644 --- a/mozilla/uriloader/exthandler/nsExternalProtocolHandler.cpp +++ b/mozilla/uriloader/exthandler/nsExternalProtocolHandler.cpp @@ -51,7 +51,6 @@ #include "nsIStringBundle.h" #include "nsIPrefService.h" #include "nsIPrompt.h" -#include "nsEventQueueUtils.h" #include "nsNetUtil.h" // used to dispatch urls to default protocol handlers diff --git a/mozilla/view/src/nsViewManager.cpp b/mozilla/view/src/nsViewManager.cpp index d0fcff0f67d..a9e8be7bcd8 100644 --- a/mozilla/view/src/nsViewManager.cpp +++ b/mozilla/view/src/nsViewManager.cpp @@ -53,8 +53,6 @@ #include "nsISupportsArray.h" #include "nsICompositeListener.h" #include "nsCOMPtr.h" -#include "nsIEventQueue.h" -#include "nsIEventQueueService.h" #include "nsIServiceManager.h" #include "nsGUIEvent.h" #include "nsIPrefBranch.h" @@ -64,6 +62,7 @@ #include "nsScrollPortView.h" #include "nsHashtable.h" #include "nsCOMArray.h" +#include "nsThreadUtils.h" #ifdef MOZ_CAIRO_GFX #include "gfxContext.h" @@ -72,7 +71,6 @@ static NS_DEFINE_IID(kBlenderCID, NS_BLENDER_CID); static NS_DEFINE_IID(kRegionCID, NS_REGION_CID); static NS_DEFINE_IID(kRenderingContextCID, NS_RENDERING_CONTEXT_CID); -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); #define ARENA_ALLOCATE(var, pool, type) \ {void *_tmp_; PL_ARENA_ALLOCATE(_tmp_, pool, sizeof(type)); \ @@ -103,46 +101,28 @@ static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); //-------------- Begin Invalidate Event Definition ------------------------ -struct nsViewManagerEvent : public PLEvent { - nsViewManagerEvent(nsViewManager* aViewManager); - - virtual void HandleEvent() = 0; - - nsViewManager* ViewManager() { - // |owner| is a weak pointer, but the view manager will destroy any - // pending invalidate events in it's destructor. - return NS_STATIC_CAST(nsViewManager*, owner); +class nsViewManagerEvent : public nsRunnable { +public: + nsViewManagerEvent(const nsViewManagerWeakRef &aViewManager) + : mViewManager(aViewManager) { + // mViewManager is a weak reference that the view manager will break in + // it's destructor. + NS_ASSERTION(aViewManager, "null parameter"); } + +protected: + nsViewManagerWeakRef mViewManager; }; -static void* PR_CALLBACK HandlePLEvent(PLEvent* aEvent) -{ - NS_ASSERTION(nsnull != aEvent,"Event is null"); - nsViewManagerEvent *event = NS_STATIC_CAST(nsViewManagerEvent*, aEvent); - - event->HandleEvent(); - return nsnull; -} - -static void PR_CALLBACK DestroyPLEvent(PLEvent* aEvent) -{ - NS_ASSERTION(nsnull != aEvent,"Event is null"); - nsViewManagerEvent *event = NS_STATIC_CAST(nsViewManagerEvent*, aEvent); - delete event; -} - -nsViewManagerEvent::nsViewManagerEvent(nsViewManager* aViewManager) -{ - NS_ASSERTION(aViewManager, "null parameter"); - PL_InitEvent(this, aViewManager, ::HandlePLEvent, ::DestroyPLEvent); -} - -struct nsInvalidateEvent : public nsViewManagerEvent { - nsInvalidateEvent(nsViewManager* aViewManager) +class nsInvalidateEvent : public nsViewManagerEvent { +public: + nsInvalidateEvent(const nsViewManagerWeakRef &aViewManager) : nsViewManagerEvent(aViewManager) { } - virtual void HandleEvent() { - ViewManager()->ProcessInvalidateEvent(); + NS_IMETHOD Run() { + if (mViewManager) + mViewManager->ProcessInvalidateEvent(); + return NS_OK; } }; @@ -169,16 +149,17 @@ void nsViewManager::PostInvalidateEvent() { NS_ASSERTION(IsRootVM(), "Caller screwed up"); - - nsCOMPtr eventQueue; - mEventQueueService->GetSpecialEventQueue( - nsIEventQueueService::UI_THREAD_EVENT_QUEUE, getter_AddRefs(eventQueue)); - NS_ASSERTION(nsnull != eventQueue, "Event queue is null"); - if (eventQueue != mInvalidateEventQueue) { - nsInvalidateEvent* ev = new nsInvalidateEvent(this); - eventQueue->PostEvent(ev); - mInvalidateEventQueue = eventQueue; + if (!EnsureWeakRef()) + return; // out of memory + + if (!mInvalidateEventPending) { + nsCOMPtr ev = new nsInvalidateEvent(mWeakRef); + if (NS_FAILED(NS_DispatchToCurrentThread(ev))) { + NS_WARNING("failed to dispatch nsSynthMouseMoveEvent"); + } else { + mInvalidateEventPending = PR_TRUE; + } } } @@ -195,6 +176,8 @@ nsViewManager::nsViewManager() : mMouseLocation(NSCOORD_NONE, NSCOORD_NONE) , mDelayedResize(NSCOORD_NONE, NSCOORD_NONE) , mRootViewManager(this) + , mSynthMouseMoveEventPending(PR_FALSE) + , mInvalidateEventPending(PR_FALSE) { if (gViewManagers == nsnull) { NS_ASSERTION(mVMCount == 0, "View Manager count is incorrect"); @@ -229,22 +212,18 @@ nsViewManager::~nsViewManager() mRootView = nsnull; } - // Make sure to RevokeEvents for all viewmanagers, since some events + // Make sure to revoke pending events for all viewmanagers, since some events // are posted by a non-root viewmanager. - if (mInvalidateEventQueue) { - mInvalidateEventQueue->RevokeEvents(this); - mInvalidateEventQueue = nsnull; - } - if (mSynthMouseMoveEventQueue) { - mSynthMouseMoveEventQueue->RevokeEvents(this); - mSynthMouseMoveEventQueue = nsnull; - } + mWeakRef.forget(); if (!IsRootVM()) { // We have a strong ref to mRootViewManager NS_RELEASE(mRootViewManager); } + mInvalidateEventPending = PR_FALSE; + mSynthMouseMoveEventPending = PR_FALSE; + mRootScrollable = nsnull; NS_ASSERTION((mVMCount > 0), "underflow of viewmanagers"); @@ -335,11 +314,6 @@ NS_IMETHODIMP nsViewManager::Init(nsIDeviceContext* aContext) mMouseGrabber = nsnull; mKeyGrabber = nsnull; - if (nsnull == mEventQueueService) { - mEventQueueService = do_GetService(kEventQueueServiceCID); - NS_ASSERTION(mEventQueueService, "couldn't get event queue service"); - } - return NS_OK; } @@ -2855,7 +2829,7 @@ nsViewManager::ProcessInvalidateEvent() if (processEvent) { FlushPendingInvalidates(); } - mInvalidateEventQueue = nsnull; + mInvalidateEventPending = PR_FALSE; if (!processEvent) { // We didn't actually process this event... post a new one PostInvalidateEvent(); @@ -2884,17 +2858,21 @@ nsViewManager::GetLastUserEventTime(PRUint32& aTime) return NS_OK; } -struct nsSynthMouseMoveEvent : public nsViewManagerEvent { - nsSynthMouseMoveEvent(nsViewManager *aViewManager, PRBool aFromScroll) +class nsSynthMouseMoveEvent : public nsViewManagerEvent { +public: + nsSynthMouseMoveEvent(const nsViewManagerWeakRef &aViewManager, + PRBool aFromScroll) : nsViewManagerEvent(aViewManager), mFromScroll(aFromScroll) - { - } - - virtual void HandleEvent() { - ViewManager()->ProcessSynthMouseMoveEvent(mFromScroll); + { } + + NS_IMETHOD Run() { + if (mViewManager) + mViewManager->ProcessSynthMouseMoveEvent(mFromScroll); + return NS_OK; } +private: PRBool mFromScroll; }; @@ -2904,15 +2882,19 @@ nsViewManager::SynthesizeMouseMove(PRBool aFromScroll) if (mMouseLocation == nsPoint(NSCOORD_NONE, NSCOORD_NONE)) return NS_OK; - nsCOMPtr eventQueue; - mEventQueueService->GetSpecialEventQueue( - nsIEventQueueService::UI_THREAD_EVENT_QUEUE, getter_AddRefs(eventQueue)); - NS_ASSERTION(nsnull != eventQueue, "Event queue is null"); + if (!EnsureWeakRef()) + return NS_ERROR_OUT_OF_MEMORY; - if (eventQueue != mSynthMouseMoveEventQueue) { - nsSynthMouseMoveEvent *ev = new nsSynthMouseMoveEvent(this, aFromScroll); - eventQueue->PostEvent(ev); - mSynthMouseMoveEventQueue = eventQueue; + if (!mSynthMouseMoveEventPending) { + nsCOMPtr ev = + new nsSynthMouseMoveEvent(mWeakRef, aFromScroll); + + if (NS_FAILED(NS_DispatchToCurrentThread(ev))) { + NS_WARNING("failed to dispatch nsSynthMouseMoveEvent"); + return NS_ERROR_UNEXPECTED; + } + + mSynthMouseMoveEventPending = PR_TRUE; } return NS_OK; @@ -2951,10 +2933,10 @@ nsViewManager::ProcessSynthMouseMoveEvent(PRBool aFromScroll) // allow new event to be posted while handling this one only if the // source of the event is a scroll (to prevent infinite reflow loops) if (aFromScroll) - mSynthMouseMoveEventQueue = nsnull; + mSynthMouseMoveEventPending = PR_FALSE; if (mMouseLocation == nsPoint(NSCOORD_NONE, NSCOORD_NONE) || !mRootView) { - mSynthMouseMoveEventQueue = nsnull; + mSynthMouseMoveEventPending = PR_FALSE; return; } @@ -2991,7 +2973,7 @@ nsViewManager::ProcessSynthMouseMoveEvent(PRBool aFromScroll) view->GetViewManager()->DispatchEvent(&event, &status); if (!aFromScroll) - mSynthMouseMoveEventQueue = nsnull; + mSynthMouseMoveEventPending = PR_FALSE; } void diff --git a/mozilla/view/src/nsViewManager.h b/mozilla/view/src/nsViewManager.h index 6491876bcf3..a99bd182606 100644 --- a/mozilla/view/src/nsViewManager.h +++ b/mozilla/view/src/nsViewManager.h @@ -45,11 +45,10 @@ #include "prtime.h" #include "prinrval.h" #include "nsVoidArray.h" +#include "nsTWeakRef.h" #include "nsIScrollableView.h" #include "nsIRegion.h" #include "nsIBlender.h" -#include "nsIEventQueueService.h" -#include "nsIEventQueue.h" #include "nsView.h" class nsIRegion; @@ -61,6 +60,8 @@ class BlendingBuffers; struct PLArenaPool; class nsHashtable; +typedef nsTWeakRef nsViewManagerWeakRef; + //Uncomment the following line to enable generation of viewmanager performance data. #ifdef MOZ_PERF_METRICS //#define NS_VM_PERF_METRICS 1 @@ -452,6 +453,13 @@ private: RootViewManager()->mPainting = aPainting; } + PRBool EnsureWeakRef() { + if (mWeakRef.get()) + return PR_TRUE; + mWeakRef = this; + return mWeakRef.get() != nsnull; + } + public: // NOT in nsIViewManager, so private to the view module nsView* GetRootView() const { return mRootView; } nsView* GetMouseEventGrabber() const { @@ -541,8 +549,8 @@ private: // mRootViewManager is a strong ref unless it equals |this|. It's // never null (if we have no ancestors, it will be |this|). nsViewManager *mRootViewManager; - nsCOMPtr mEventQueueService; - nsCOMPtr mSynthMouseMoveEventQueue; + nsViewManagerWeakRef mWeakRef; // weak ref to self (used by event dispatch) + PRPackedBool mSynthMouseMoveEventPending; PRPackedBool mAllowDoubleBuffering; // The following members should not be accessed directly except by @@ -557,7 +565,7 @@ private: PRInt32 mUpdateBatchCnt; PRUint32 mUpdateBatchFlags; PRInt32 mScrollCnt; - nsCOMPtr mInvalidateEventQueue; + PRPackedBool mInvalidateEventPending; // Use IsRefreshEnabled() to check the value of mRefreshEnabled. PRPackedBool mRefreshEnabled; // Use IsPainting() and SetPainting() to access mPainting. diff --git a/mozilla/widget/public/nsIAppShell.idl b/mozilla/widget/public/nsIAppShell.idl index b6a2c10b3f4..694e743ccec 100644 --- a/mozilla/widget/public/nsIAppShell.idl +++ b/mozilla/widget/public/nsIAppShell.idl @@ -40,77 +40,40 @@ #include "nsISupports.idl" native int(int); -[ptr] native nsIEventQueue(nsIEventQueue); -[ptr] native UndefinednsIWidget(nsIWidget); -[ref] native PRBoolRef(PRBool); -[ref] native voidPtrRef(void *); -%{ C++ -class nsIEventQueue; - -/** - * Flags for the getNativeData function. - * See GetNativeData() - */ -#define NS_NATIVE_SHELL 0 - -class nsIWidget; -%} - - -[uuid(a0757c31-eeac-11d1-9ec1-00aa002fb821)] +[uuid(3785230a-da91-4eaa-8a25-56acc7ff35d0)] interface nsIAppShell : nsISupports { - /** - * Creates an application shell - */ + /** + * Initializes the application shell. + */ + void init(inout int argc, inout string argv); - void Create(inout int argc, inout string argv); + /** + * Enter an event loop. Don't leave until exit() is called. + */ + void run(); - /** - * Enter an event loop. - * Don't leave until application exits. - */ - - void Run(); - - /** - * Prepare to process events. - */ - - void Spinup(); - - /** - * Prepare to stop processing events. - */ - - void Spindown(); - - /** - * An event queue has been created or destroyed. Hook or unhook it from - * your system, as necessary. - * @param aQueue the queue in question - * @param aListen PR_TRUE for a new queue wanting hooking up. PR_FALSE - * for a queue wanting to be unhooked. - */ - void ListenToEventQueue(in nsIEventQueue aQueue, in PRBool aListen); - - /** - * After event dispatch execute app specific code - */ - - void GetNativeEvent(in PRBoolRef aRealEvent, in voidPtrRef aEvent); - - /** - * After event dispatch execute app specific code - */ - - void DispatchNativeEvent(in PRBool aRealEvent, in voidPtr aEvent); - - /** - * Exit the handle event loop - */ - - void Exit(); + /** + * Exit the handle event loop + */ + void exit(); + /** + * Give hint to native event queue notification mechanism. If the native + * platform needs to tradeoff performance vs. native event starvation this + * hint tells the native dispatch code which to favor. The default is to + * prevent event starvation. + * + * Calls to this function may be nested. When the number of calls that pass + * PR_TRUE is subtracted from the number of calls that pass PR_FALSE is + * greater than 0, performance is given precedence over preventing event + * starvation. + * + * The starvationDelay arg is only used when favorPerfOverStarvation is + * PR_FALSE. It is the amount of time in milliseconds to wait before the + * PR_FALSE actually takes effect. + */ + void favorPerformanceHint(in boolean favorPerfOverStarvation, + in unsigned long starvationDelay); }; diff --git a/mozilla/widget/src/gtk2/nsAppShell.cpp b/mozilla/widget/src/gtk2/nsAppShell.cpp index e0b05eba345..3259d1c047f 100644 --- a/mozilla/widget/src/gtk2/nsAppShell.cpp +++ b/mozilla/widget/src/gtk2/nsAppShell.cpp @@ -36,21 +36,13 @@ * * ***** END LICENSE BLOCK ***** */ +#include +#include +#include #include "nsAppShell.h" -#include "nsIEventQueueService.h" -#include "nsServiceManagerUtils.h" -#include "plhash.h" +#include "prlog.h" #include "prenv.h" -// to get the logging stuff -#include "nsCommonWidget.h" - -#include - -static PRBool sInitialized = PR_FALSE; -static PLHashTable *sQueueHashTable = nsnull; -static PLHashTable *sCountHashTable = nsnull; - #ifdef PR_LOGGING PRLogModuleInfo *gWidgetLog = nsnull; PRLogModuleInfo *gWidgetFocusLog = nsnull; @@ -58,27 +50,8 @@ PRLogModuleInfo *gWidgetIMLog = nsnull; PRLogModuleInfo *gWidgetDrawLog = nsnull; #endif -static gboolean event_processor_callback (GIOChannel *source, - GIOCondition condition, - gpointer data) -{ - nsIEventQueue *eventQueue = (nsIEventQueue *)data; - if (eventQueue) - eventQueue->ProcessPendingEvents(); - - // always remove the source event - return TRUE; -} - -#define NUMBER_HASH_KEY(_num) ((PLHashNumber) _num) - -static PLHashNumber -IntHashKey(PRInt32 key) -{ - return NUMBER_HASH_KEY(key); -} - -nsAppShell::nsAppShell(void) +NS_IMETHODIMP +nsAppShell::Init(int *argc, char **argv) { #ifdef PR_LOGGING if (!gWidgetLog) @@ -90,195 +63,26 @@ nsAppShell::nsAppShell(void) if (!gWidgetDrawLog) gWidgetDrawLog = PR_NewLogModule("WidgetDraw"); #endif -} -nsAppShell::~nsAppShell(void) -{ -} + nsresult rv = nsBaseAppShell::Init(argc, argv); + if (NS_FAILED(rv)) + return rv; -/* static */ void -nsAppShell::ReleaseGlobals() -{ - if (sQueueHashTable) { - PL_HashTableDestroy(sQueueHashTable); - sQueueHashTable = nsnull; - } - if (sCountHashTable) { - PL_HashTableDestroy(sCountHashTable); - sCountHashTable = nsnull; - } -} - -NS_IMPL_ISUPPORTS1(nsAppShell, nsIAppShell) - -NS_IMETHODIMP -nsAppShell::Create(int *argc, char **argv) -{ - if (sInitialized) - return NS_OK; - - sInitialized = PR_TRUE; - - if (PR_GetEnv("MOZ_DEBUG_PAINTS")) { + if (PR_GetEnv("MOZ_DEBUG_PAINTS")) gdk_window_set_debug_updates(TRUE); - } return NS_OK; } NS_IMETHODIMP -nsAppShell::Run(void) +nsAppShell::OnDispatchedEvent(nsIThreadInternal *thread) { - if (!mEventQueue) - Spinup(); - - if (!mEventQueue) - return NS_ERROR_NOT_INITIALIZED; - - // go go gadget gtk2! - gtk_main(); - - Spindown(); - + g_main_context_wakeup(NULL); return NS_OK; } -NS_IMETHODIMP -nsAppShell::Spinup(void) +PRBool +nsAppShell::ProcessNextNativeEvent(PRBool mayWait) { - nsresult rv = NS_OK; - - // get the event queue service - nsCOMPtr eventQService = - do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv); - - if (NS_FAILED(rv)) { - NS_WARNING("Failed to get event queue service"); - return rv; - } - - // get the event queue for this thread - rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, - getter_AddRefs(mEventQueue)); - - // if we got an event queue, just use it - if (mEventQueue) - goto done; - - // otherwise creaet a new event queue for the thread - rv = eventQService->CreateThreadEventQueue(); - if (NS_FAILED(rv)) { - NS_WARNING("Could not create the thread event queue"); - return rv; - } - - // ask again for the event queue now that we have create one. - rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, - getter_AddRefs(mEventQueue)); - - done: - ListenToEventQueue(mEventQueue, PR_TRUE); - - return rv; -} - -NS_IMETHODIMP -nsAppShell::Spindown(void) -{ - // stop listening to the event queue - if (mEventQueue) { - ListenToEventQueue(mEventQueue, PR_FALSE); - mEventQueue->ProcessPendingEvents(); - mEventQueue = nsnull; - } - return NS_OK; -} - -NS_IMETHODIMP -nsAppShell::ListenToEventQueue(nsIEventQueue *aQueue, PRBool aListen) -{ - LOG(("ListenToEventQueue %p %d\n", (void *)aQueue, aListen)); - // initialize our hash tables if we have to - if (!sQueueHashTable) - sQueueHashTable = PL_NewHashTable(3, (PLHashFunction)IntHashKey, - PL_CompareValues, - PL_CompareValues, 0, 0); - if (!sCountHashTable) - sCountHashTable = PL_NewHashTable(3, (PLHashFunction)IntHashKey, - PL_CompareValues, - PL_CompareValues, 0, 0); - - PRInt32 key = aQueue->GetEventQueueSelectFD(); - - /* add a listener */ - if (aListen) { - /* only add if we arn't already in the table */ - if (!PL_HashTableLookup(sQueueHashTable, GINT_TO_POINTER(key))) { - GIOChannel *ioc; - guint tag; - ioc = g_io_channel_unix_new(key); - tag = g_io_add_watch_full (ioc, G_PRIORITY_DEFAULT_IDLE, - G_IO_IN, - event_processor_callback, aQueue, NULL); - // it's owned by the mainloop now - g_io_channel_unref(ioc); - PL_HashTableAdd(sQueueHashTable, GINT_TO_POINTER(key), - GUINT_TO_POINTER(tag)); - LOG(("created tag %d from key %d\n", tag, key)); - } - /* bump up the count */ - gint count = GPOINTER_TO_INT(PL_HashTableLookup(sCountHashTable, - GINT_TO_POINTER(key))); - PL_HashTableAdd(sCountHashTable, GINT_TO_POINTER(key), - GINT_TO_POINTER(count+1)); - LOG(("key %d now has count %d\n", key, count+1)); - } else { - /* remove listener */ - gint count = GPOINTER_TO_INT(PL_HashTableLookup(sCountHashTable, - GINT_TO_POINTER(key))); - LOG(("key %d will have count %d\n", key, count-1)); - if (count - 1 == 0) { - guint tag; - tag = GPOINTER_TO_UINT(PL_HashTableLookup(sQueueHashTable, - GINT_TO_POINTER(key))); - LOG(("shutting down tag %d\n", tag)); - g_source_remove(tag); - PL_HashTableRemove(sQueueHashTable, GINT_TO_POINTER(key)); - PL_HashTableRemove(sCountHashTable, GINT_TO_POINTER(key)); - } - else { - // update the count for this key - PL_HashTableAdd(sCountHashTable, GINT_TO_POINTER(key), - GINT_TO_POINTER(count-1)); - } - } - - return NS_OK; -} - -NS_IMETHODIMP -nsAppShell::GetNativeEvent(PRBool &aRealEvent, void * &aEvent) -{ - aRealEvent = PR_FALSE; - aEvent = 0; - - return NS_OK; -} - -NS_IMETHODIMP -nsAppShell::DispatchNativeEvent(PRBool aRealEvent, void *aEvent) -{ - if (!mEventQueue) - return NS_ERROR_NOT_INITIALIZED; - - g_main_context_iteration(NULL, TRUE); - - return NS_OK; -} - -NS_IMETHODIMP -nsAppShell::Exit(void) -{ - gtk_main_quit(); - return NS_OK; + return g_main_context_iteration(NULL, mayWait); } diff --git a/mozilla/widget/src/gtk2/nsAppShell.h b/mozilla/widget/src/gtk2/nsAppShell.h index ab46e8b15cf..6aa80bbd98d 100644 --- a/mozilla/widget/src/gtk2/nsAppShell.h +++ b/mozilla/widget/src/gtk2/nsAppShell.h @@ -39,23 +39,27 @@ #ifndef nsAppShell_h__ #define nsAppShell_h__ -#include "nsIAppShell.h" -#include "nsIEventQueue.h" +#include "nsBaseAppShell.h" #include "nsCOMPtr.h" -class nsAppShell : public nsIAppShell { +class nsAppShell : public nsBaseAppShell { public: + nsAppShell() : mInitialized(PR_FALSE) {} - nsAppShell(); - virtual ~nsAppShell(); + // nsIAppShell overrides: + NS_IMETHOD Init(int *argc, char **argv); - static void ReleaseGlobals(); + // nsIThreadObserver overrides: + NS_IMETHOD OnDispatchedEvent(nsIThreadInternal *thread); - NS_DECL_ISUPPORTS - NS_DECL_NSIAPPSHELL + // nsBaseAppShell overrides: + PRBool ProcessNextNativeEvent(PRBool mayWait); private: - nsCOMPtr mEventQueue; + virtual ~nsAppShell() {} + + int mPipeFDs[2]; + PRBool mInitialized; }; #endif /* nsAppShell_h__ */ diff --git a/mozilla/widget/src/gtk2/nsWidgetFactory.cpp b/mozilla/widget/src/gtk2/nsWidgetFactory.cpp index 275c7b06fbf..e4f2c2bc938 100644 --- a/mozilla/widget/src/gtk2/nsWidgetFactory.cpp +++ b/mozilla/widget/src/gtk2/nsWidgetFactory.cpp @@ -263,7 +263,6 @@ nsWidgetGtk2ModuleDtor(nsIModule *aSelf) { nsFilePicker::Shutdown(); nsWindow::ReleaseGlobals(); - nsAppShell::ReleaseGlobals(); } NS_IMPL_NSGETMODULE_WITH_DTOR(nsWidgetGtk2Module, diff --git a/mozilla/widget/src/mac/nsAppShell.cpp b/mozilla/widget/src/mac/nsAppShell.cpp index 8b83208e2f0..c7df6cecf57 100644 --- a/mozilla/widget/src/mac/nsAppShell.cpp +++ b/mozilla/widget/src/mac/nsAppShell.cpp @@ -1,4 +1,5 @@ /* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */ +/* vim:set ts=2 sw=2 sts=2 ci et: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -47,7 +48,7 @@ #include "nsAppShell.h" #include "nsIAppShell.h" -#include "nsIEventQueueService.h" +#include "nsThreadUtils.h" #include "nsIServiceManager.h" #include "nsIWidget.h" #include "nsMacMessagePump.h" @@ -64,20 +65,13 @@ PRBool nsAppShell::mInitializedToolbox = PR_FALSE; -//------------------------------------------------------------------------- -// -// nsISupports implementation macro -// -//------------------------------------------------------------------------- -NS_IMPL_THREADSAFE_ISUPPORTS1(nsAppShell, nsIAppShell) - //------------------------------------------------------------------------- // // Create the application shell // //------------------------------------------------------------------------- -NS_IMETHODIMP nsAppShell::Create(int* argc, char ** argv) +NS_IMETHODIMP nsAppShell::Init(int* argc, char ** argv) { nsresult rv = NS_GetCurrentToolkit(getter_AddRefs(mToolkit)); if (NS_FAILED(rv)) @@ -89,9 +83,10 @@ NS_IMETHODIMP nsAppShell::Create(int* argc, char ** argv) if (!mMacPump.get() || ! nsMacMemoryCushion::EnsureMemoryCushion()) return NS_ERROR_OUT_OF_MEMORY; - return NS_OK; + return nsBaseAppShell::Init(argc, argv);; } +#if 0 //------------------------------------------------------------------------- // // Enter a message handler loop @@ -99,6 +94,21 @@ NS_IMETHODIMP nsAppShell::Create(int* argc, char ** argv) //------------------------------------------------------------------------- NS_IMETHODIMP nsAppShell::Run(void) { + nsCOMPtr thread = do_GetCurrentThread(); + NS_ENSURE_STATE(thread); + + nsToolkit::AppInForeground(); + + mExitCalled = PR_FALSE; + while (!mExitCalled) + thread->RunNextTask(nsIThread::RUN_NORMAL); + + NS_RunPendingTasks(thread); + + NS_RELEASE_THIS(); // hack: see below + return NS_OK; + +#if 0 if (!mMacPump.get()) return NS_ERROR_NOT_INITIALIZED; @@ -113,6 +123,7 @@ NS_IMETHODIMP nsAppShell::Run(void) } return NS_OK; +#endif } //------------------------------------------------------------------------- @@ -122,18 +133,21 @@ NS_IMETHODIMP nsAppShell::Run(void) //------------------------------------------------------------------------- NS_IMETHODIMP nsAppShell::Exit(void) { - if (mMacPump.get()) - { - Spindown(); - mExitCalled = PR_TRUE; - ++mRefCnt; // hack: since the applications are likely to delete us - // after calling this method (see nsViewerApp::Exit()), - // we temporarily bump the refCnt to let the message pump - // exit properly. The object will delete itself afterwards. - } + if (!mMacPump.get()) + return NS_OK; + + Spindown(); + mExitCalled = PR_TRUE; + + NS_ADDREF_THIS(); // hack: since the applications are likely to delete us + // after calling this method (see nsViewerApp::Exit()), + // we temporarily bump the refCnt to let the message pump + // exit properly. The object will delete itself afterwards. return NS_OK; } +#endif +#if 0 //------------------------------------------------------------------------- // // respond to notifications that an event queue has come or gone @@ -143,7 +157,9 @@ NS_IMETHODIMP nsAppShell::ListenToEventQueue(nsIEventQueue * aQueue, PRBool aLis { // unnecessary; handled elsewhere return NS_OK; } +#endif +#if 0 //------------------------------------------------------------------------- // // Prepare to process events @@ -151,12 +167,10 @@ NS_IMETHODIMP nsAppShell::ListenToEventQueue(nsIEventQueue * aQueue, PRBool aLis //------------------------------------------------------------------------- NS_IMETHODIMP nsAppShell::Spinup(void) { - if (mMacPump.get()) - { - mMacPump->StartRunning(); - return NS_OK; - } - return NS_ERROR_NOT_INITIALIZED; + NS_ENSURE_TRUE(mMacPump.get(), NS_ERROR_NOT_INITIALIZED); + + mMacPump->StartRunning(); + return NS_OK; } //------------------------------------------------------------------------- @@ -170,6 +184,7 @@ NS_IMETHODIMP nsAppShell::Spindown(void) mMacPump->StopRunning(); return NS_OK; } +#endif //------------------------------------------------------------------------- // @@ -184,15 +199,7 @@ nsAppShell::nsAppShell() mExitCalled = PR_FALSE; } -//------------------------------------------------------------------------- -// -// nsAppShell destructor -// -//------------------------------------------------------------------------- -nsAppShell::~nsAppShell() -{ -} - +#if 0 NS_METHOD nsAppShell::GetNativeEvent(PRBool &aRealEvent, void *&aEvent) { @@ -215,3 +222,119 @@ nsAppShell::DispatchNativeEvent(PRBool aRealEvent, void *aEvent) mMacPump->DispatchEvent(aRealEvent, (EventRecord *) aEvent); return NS_OK; } +#endif + +//------------------------------------------------------------------------- +// +// Thread observer methods +// +//------------------------------------------------------------------------- + +#if 0 +#if defined(XP_MACOSX) +#if defined(MOZ_WIDGET_COCOA) +#include +#define MAC_USE_CFRUNLOOPSOURCE +#elif defined(TARGET_CARBON) +/* #include */ +/* #define MAC_USE_CARBON_EVENT */ +#include +#define MAC_USE_CFRUNLOOPSOURCE +#endif +#endif + +#if defined(MAC_USE_CFRUNLOOPSOURCE) + CFRunLoopSourceRef mRunLoopSource; + CFRunLoopRef mMainRunLoop; +#elif defined(MAC_USE_CARBON_EVENT) + EventHandlerUPP eventHandlerUPP; + EventHandlerRef eventHandlerRef; +#endif + +static void _md_CreateEventQueue( PLEventQueue *eventQueue ) +{ +#if defined(MAC_USE_CFRUNLOOPSOURCE) + CFRunLoopSourceContext sourceContext = { 0 }; + sourceContext.version = 0; + sourceContext.info = (void*)eventQueue; + sourceContext.perform = _md_EventReceiverProc; + + /* make a run loop source */ + eventQueue->mRunLoopSource = CFRunLoopSourceCreate(kCFAllocatorDefault, 0 /* order */, &sourceContext); + PR_ASSERT(eventQueue->mRunLoopSource); + + eventQueue->mMainRunLoop = CFRunLoopGetCurrent(); + CFRetain(eventQueue->mMainRunLoop); + + /* and add it to the run loop */ + CFRunLoopAddSource(eventQueue->mMainRunLoop, eventQueue->mRunLoopSource, kCFRunLoopCommonModes); + +#elif defined(MAC_USE_CARBON_EVENT) + eventQueue->eventHandlerUPP = NewEventHandlerUPP(_md_EventReceiverProc); + PR_ASSERT(eventQueue->eventHandlerUPP); + if (eventQueue->eventHandlerUPP) + { + EventTypeSpec eventType; + + eventType.eventClass = kEventClassPL; + eventType.eventKind = kEventProcessPLEvents; + + InstallApplicationEventHandler(eventQueue->eventHandlerUPP, 1, &eventType, + eventQueue, &eventQueue->eventHandlerRef); + PR_ASSERT(eventQueue->eventHandlerRef); + } +#endif +} /* end _md_CreateEventQueue() */ + +static PRStatus +_pl_NativeNotify(PLEventQueue* self) +{ +#if defined(MAC_USE_CFRUNLOOPSOURCE) + CFRunLoopSourceSignal(self->mRunLoopSource); + CFRunLoopWakeUp(self->mMainRunLoop); +#elif defined(MAC_USE_CARBON_EVENT) + OSErr err; + EventRef newEvent; + if (CreateEvent(NULL, kEventClassPL, kEventProcessPLEvents, + 0, kEventAttributeNone, &newEvent) != noErr) + return PR_FAILURE; + err = SetEventParameter(newEvent, kEventParamPLEventQueue, + typeUInt32, sizeof(PREventQueue*), &self); + if (err == noErr) { + err = PostEventToQueue(GetMainEventQueue(), newEvent, kEventPriorityLow); + ReleaseEvent(newEvent); + } + if (err != noErr) + return PR_FAILURE; +#endif + return PR_SUCCESS; +} +#endif + +NS_IMETHODIMP nsAppShell::OnNewTask(nsIThreadInternal *thr, PRUint32 flags) +{ + // post a message to the native event queue... + return NS_OK; +} + +NS_IMETHODIMP nsAppShell::OnBeforeRunNextTask(nsIThreadInternal *thr, + PRUint32 flags) +{ + return NS_OK; +} + +NS_IMETHODIMP nsAppShell::OnAfterRunNextTask(nsIThreadInternal *thr, + PRUint32 flags, + nsresult status) +{ + // process any pending native events... + return NS_OK; +} + +NS_IMETHODIMP nsAppShell::OnWaitNextTask(nsIThreadInternal *thr, + PRUint32 flags) +{ + // while (!thr->HasPendingTask()) + // wait for and process native events + return NS_OK; +} diff --git a/mozilla/widget/src/mac/nsAppShell.h b/mozilla/widget/src/mac/nsAppShell.h index 886dedede73..a402caf85c0 100644 --- a/mozilla/widget/src/mac/nsAppShell.h +++ b/mozilla/widget/src/mac/nsAppShell.h @@ -47,7 +47,7 @@ #ifndef nsAppShell_h__ #define nsAppShell_h__ -#include "nsIAppShell.h" +#include "nsBaseAppShell.h" #include "nsCOMPtr.h" #include "nsIToolkit.h" @@ -57,16 +57,24 @@ using std::auto_ptr; class nsMacMessagePump; -class nsAppShell : public nsIAppShell +class nsAppShell : public nsBaseAppShell { public: nsAppShell(); - virtual ~nsAppShell(); - NS_DECL_ISUPPORTS - NS_DECL_NSIAPPSHELL + // nsIAppShell overrides: + NS_IMETHOD Init(int *argc, char **argv); + + // nsIThreadObserver overrides: + NS_IMETHOD OnNewTask(nsIThreadInternal *thread, PRUint32 flags); + NS_IMETHOD OnBeforeRunNextTask(nsIThreadInternal *thread, PRUint32 flags); + NS_IMETHOD OnAfterRunNextTask(nsIThreadInternal *thread, PRUint32 flags, + nsresult status); + NS_IMETHOD OnWaitNextTask(nsIThreadInternal *thread, PRUint32 flags); private: + ~nsAppShell() {} + nsCOMPtr mToolkit; auto_ptr mMacPump; PRBool mExitCalled; diff --git a/mozilla/widget/src/mac/nsMacMessagePump.cpp b/mozilla/widget/src/mac/nsMacMessagePump.cpp index 64508270dca..4741058b34d 100644 --- a/mozilla/widget/src/mac/nsMacMessagePump.cpp +++ b/mozilla/widget/src/mac/nsMacMessagePump.cpp @@ -57,7 +57,6 @@ #include "nsRepeater.h" -#include "nsIEventQueueService.h" #include "nsIServiceManager.h" #include "prthread.h" diff --git a/mozilla/widget/src/mac/nsMacMessagePump.h b/mozilla/widget/src/mac/nsMacMessagePump.h index b9ef49150f5..2dd53c81a97 100644 --- a/mozilla/widget/src/mac/nsMacMessagePump.h +++ b/mozilla/widget/src/mac/nsMacMessagePump.h @@ -56,7 +56,6 @@ #include #include "prtypes.h" -#include "nsIEventQueueService.h" class nsToolkit; class nsMacTSMMessagePump; diff --git a/mozilla/widget/src/mac/nsToolkit.cpp b/mozilla/widget/src/mac/nsToolkit.cpp index a26827e95ed..c43f75599f4 100644 --- a/mozilla/widget/src/mac/nsToolkit.cpp +++ b/mozilla/widget/src/mac/nsToolkit.cpp @@ -46,16 +46,12 @@ #include "nsIEventSink.h" -#include "nsIEventQueue.h" -#include "nsIEventQueueService.h" #include "nsIServiceManager.h" +#include "nsThreadUtils.h" #include "nsGfxCIID.h" #include "nsIPref.h" -// Class IDs... -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); - static nsMacNSPREventQueueHandler* gEventQueueHandler = nsnull; //------------------------------------------------------------------------- @@ -64,7 +60,6 @@ static nsMacNSPREventQueueHandler* gEventQueueHandler = nsnull; nsMacNSPREventQueueHandler::nsMacNSPREventQueueHandler(): Repeater() { mRefCnt = 0; - mEventQueueService = do_GetService(kEventQueueServiceCID); } //------------------------------------------------------------------------- @@ -115,15 +110,10 @@ void nsMacNSPREventQueueHandler::RepeatAction(const EventRecord& inMacEvent) PRBool nsMacNSPREventQueueHandler::EventsArePending() { PRBool pendingEvents = PR_FALSE; - - if (mEventQueueService) - { - nsCOMPtr queue; - mEventQueueService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(queue)); - if (queue) - queue->PendingEvents(&pendingEvents); - } + nsCOMPtr thread = do_GetCurrentThread(); + if (thread) + thread->HasPendingEvents(&pendingEvents); return pendingEvents; } @@ -134,15 +124,9 @@ PRBool nsMacNSPREventQueueHandler::EventsArePending() //------------------------------------------------------------------------- void nsMacNSPREventQueueHandler::ProcessPLEventQueue() { - NS_ASSERTION(mEventQueueService, "Need event queue service here"); - - nsCOMPtr queue; - mEventQueueService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(queue)); - if (queue) - { - nsresult rv = queue->ProcessPendingEvents(); - NS_ASSERTION(NS_SUCCEEDED(rv), "Error processing PLEvents"); - } + nsCOMPtr thread = do_GetCurrentThread(); + if (thread) + NS_ProcessPendingEvents(thread); } diff --git a/mozilla/widget/src/mac/nsToolkit.h b/mozilla/widget/src/mac/nsToolkit.h index b6239eef754..65907606513 100644 --- a/mozilla/widget/src/mac/nsToolkit.h +++ b/mozilla/widget/src/mac/nsToolkit.h @@ -44,7 +44,6 @@ #include "nsRepeater.h" #include "nsCOMPtr.h" -#include "nsIEventQueueService.h" /** * The toolkit abstraction is necessary because the message pump must @@ -138,8 +137,6 @@ protected: protected: nsrefcnt mRefCnt; - - nsCOMPtr mEventQueueService; }; diff --git a/mozilla/widget/src/mac/nsToolkitBase.cpp b/mozilla/widget/src/mac/nsToolkitBase.cpp index 0975ecf6267..96e019723c2 100644 --- a/mozilla/widget/src/mac/nsToolkitBase.cpp +++ b/mozilla/widget/src/mac/nsToolkitBase.cpp @@ -53,8 +53,6 @@ #include "nsToolkitBase.h" #include "nsWidgetAtoms.h" -#include "nsIEventQueue.h" -#include "nsIEventQueueService.h" #include "nsIObserverService.h" #include "nsIServiceManager.h" #include "nsIPrefBranch2.h" diff --git a/mozilla/widget/src/mac/nsToolkitBase.h b/mozilla/widget/src/mac/nsToolkitBase.h index 555ee999d51..82d8e7b8437 100644 --- a/mozilla/widget/src/mac/nsToolkitBase.h +++ b/mozilla/widget/src/mac/nsToolkitBase.h @@ -43,7 +43,6 @@ #include "nsIToolkit.h" #include "nsCOMPtr.h" -#include "nsIEventQueueService.h" #include "nsIObserver.h" class nsToolkitBase : public nsIToolkit, public nsIObserver diff --git a/mozilla/widget/src/windows/nsAppShell.cpp b/mozilla/widget/src/windows/nsAppShell.cpp index b3805bed10b..4f289bac2a5 100644 --- a/mozilla/widget/src/windows/nsAppShell.cpp +++ b/mozilla/widget/src/windows/nsAppShell.cpp @@ -21,6 +21,7 @@ * * Contributor(s): * Michael Lowe + * Darin Fisher * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -39,7 +40,7 @@ #include "nsAppShell.h" #include "nsToolkit.h" #include "nsIWidget.h" -#include "nsIEventQueueService.h" +#include "nsThreadUtils.h" #include "nsIServiceManager.h" #include @@ -49,20 +50,376 @@ #include "nsWidgetsCID.h" #include "aimm.h" +#if 0 +UINT _pr_PostEventMsgId; +static char *_pr_eventWindowClass = "XPCOM:EventWindow"; -NS_IMPL_ISUPPORTS1(nsAppShell, nsIAppShell) +static LPCTSTR _md_GetEventQueuePropName() { + static ATOM atom = 0; + if (!atom) { + atom = GlobalAddAtom("XPCOM_EventQueue"); + } + return MAKEINTATOM(atom); +} -static int gKeepGoing = 1; -//------------------------------------------------------------------------- -// -// nsAppShell constructor -// -//------------------------------------------------------------------------- -nsAppShell::nsAppShell() -{ +static PRBool _md_WasInputPending = PR_FALSE; +static PRUint32 _md_InputTime = 0; +static PRBool _md_WasPaintPending = PR_FALSE; +static PRUint32 _md_PaintTime = 0; +/* last mouse location */ +static POINT _md_LastMousePos; + +LRESULT CALLBACK +_md_EventReceiverProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (_pr_PostEventMsgId == uMsg ) + { + PREventQueue *queue = (PREventQueue *)lParam; + queue->removeMsg = PR_FALSE; + PL_ProcessPendingEvents(queue); + queue->removeMsg = PR_TRUE; + return TRUE; + } + return DefWindowProc(hwnd, uMsg, wParam, lParam); +} + +/* +** _md_CreateEventQueue() -- ModelDependent initializer +*/ +static void _md_CreateEventQueue( PLEventQueue *eventQueue ) +{ + WNDCLASS wc; + HANDLE h = GetModuleHandle(NULL); + + /* + ** If this is the first call to PL_InitializeEventsLib(), + ** make the call to InitWinEventLib() to create the initLock. + ** + ** Then lock the initializer lock to insure that + ** we have exclusive control over the initialization sequence. + ** + */ + + + /* Register the windows message for XPCOM Event notification */ + _pr_PostEventMsgId = RegisterWindowMessage("XPCOM_PostEvent"); + + /* Register the class for the event receiver window */ + if (!GetClassInfo(h, _pr_eventWindowClass, &wc)) { + wc.style = 0; + wc.lpfnWndProc = _md_EventReceiverProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = h; + wc.hIcon = NULL; + wc.hCursor = NULL; + wc.hbrBackground = (HBRUSH) NULL; + wc.lpszMenuName = (LPCSTR) NULL; + wc.lpszClassName = _pr_eventWindowClass; + RegisterClass(&wc); + } + + /* Create the event receiver window */ + eventQueue->eventReceiverWindow = CreateWindow(_pr_eventWindowClass, + "XPCOM:EventReceiver", + 0, 0, 0, 10, 10, + NULL, NULL, h, + NULL); + PR_ASSERT(eventQueue->eventReceiverWindow); + /* Set a property which can be used to retrieve the event queue + * within the _md_TimerProc callback + */ + SetProp(eventQueue->eventReceiverWindow, + _md_GetEventQueuePropName(), (HANDLE)eventQueue); + + return; +} /* end _md_CreateEventQueue() */ + +static void +_pl_CleanupNativeNotifier(PLEventQueue* self) +{ + if (self->timerSet) { + KillTimer(self->eventReceiverWindow, TIMER_ID); + self->timerSet = PR_FALSE; + } + RemoveProp(self->eventReceiverWindow, _md_GetEventQueuePropName()); + + /* DestroyWindow doesn't do anything when called from a non ui thread. Since + * self->eventReceiverWindow was created on the ui thread, it must be destroyed + * on the ui thread. + */ + SendMessage(self->eventReceiverWindow, WM_CLOSE, 0, 0); +} + +/******************************************************************************* + * Timer callback function. Timers are used on WIN32 instead of APP events + * when there are pending UI events because APP events can cause the GUI to lockup + * because posted messages are processed before other messages. + ******************************************************************************/ + +static void CALLBACK _md_TimerProc( HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime ) +{ + PREventQueue* queue = (PREventQueue *) GetProp(hwnd, _md_GetEventQueuePropName()); + PR_ASSERT(queue != NULL); + + KillTimer(hwnd, TIMER_ID); + queue->timerSet = PR_FALSE; + queue->removeMsg = PR_FALSE; + PL_ProcessPendingEvents( queue ); + queue->removeMsg = PR_TRUE; +} + +static PRBool _md_IsWIN9X = PR_FALSE; +static PRBool _md_IsOSSet = PR_FALSE; + +static void _md_DetermineOSType() +{ + OSVERSIONINFO os; + os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&os); + if (VER_PLATFORM_WIN32_WINDOWS == os.dwPlatformId) { + _md_IsWIN9X = PR_TRUE; + } +} + +static PRUint32 _md_GetPaintStarvationLimit() +{ + if (! _md_IsOSSet) { + _md_DetermineOSType(); + _md_IsOSSet = PR_TRUE; + } + + if (_md_IsWIN9X) { + return WIN9X_PAINT_STARVATION_LIMIT; + } + + return PAINT_STARVATION_LIMIT; } +/* + * Determine if an event is being starved (i.e the starvation limit has + * been exceeded. + * Note: this function uses the current setting and updates the contents + * of the wasPending and lastTime arguments + * + * ispending: PR_TRUE if the event is currently pending + * starvationLimit: Threshold defined in milliseconds for determining when + * the event has been held in the queue too long + * wasPending: PR_TRUE if the last time _md_EventIsStarved was called + * the event was pending. This value is updated within + * this function. + * lastTime: Holds the last time the event was in the queue. + * This value is updated within this function + * returns: PR_TRUE if the event is starved, PR_FALSE otherwise + */ + +static PRBool _md_EventIsStarved(PRBool isPending, PRUint32 starvationLimit, + PRBool *wasPending, PRUint32 *lastTime, + PRUint32 currentTime) +{ + if (*wasPending && isPending) { + /* + * It was pending previously and the event is still + * pending so check to see if the elapsed time is + * over the limit which indicates the event was starved + */ + if ((currentTime - *lastTime) > starvationLimit) { + return PR_TRUE; /* pending and over the limit */ + } + + return PR_FALSE; /* pending but within the limit */ + } + + if (isPending) { + /* + * was_pending must be false so record the current time + * so the elapsed time can be computed the next time this + * function is called + */ + *lastTime = currentTime; + *wasPending = PR_TRUE; + return PR_FALSE; + } + + /* Event is no longer pending */ + *wasPending = PR_FALSE; + return PR_FALSE; +} + +/* Determines if the there is a pending Mouse or input event */ + +static PRBool _md_IsInputPending(WORD qstatus) +{ + /* Return immediately there aren't any pending input or paints. */ + if (qstatus == 0) { + return PR_FALSE; + } + + /* Is there anything other than a QS_MOUSEMOVE pending? */ + if ((qstatus & QS_MOUSEBUTTON) || + (qstatus & QS_KEY) +#ifndef WINCE + || (qstatus & QS_HOTKEY) +#endif + ) { + return PR_TRUE; + } + + /* + * Mouse moves need extra processing to determine if the mouse + * pointer actually changed location because Windows automatically + * generates WM_MOVEMOVE events when a new window is created which + * we need to filter out. + */ + if (qstatus & QS_MOUSEMOVE) { + POINT cursorPos; + GetCursorPos(&cursorPos); + if ((_md_LastMousePos.x == cursorPos.x) && + (_md_LastMousePos.y == cursorPos.y)) { + return PR_FALSE; /* This is a fake mouse move */ + } + + /* Real mouse move */ + _md_LastMousePos.x = cursorPos.x; + _md_LastMousePos.y = cursorPos.y; + return PR_TRUE; + } + + return PR_FALSE; +} + +static PRStatus +_pl_NativeNotify(PLEventQueue* self) +{ +#ifdef USE_TIMER + WORD qstatus; + + PRUint32 now = PR_IntervalToMilliseconds(PR_IntervalNow()); + + /* Since calls to set the _md_PerformanceSetting can be nested + * only performance setting values <= 0 will potentially trigger + * the use of a timer. + */ + if ((_md_PerformanceSetting <= 0) && + ((now - _md_SwitchTime) > _md_StarvationDelay)) { + SetTimer(self->eventReceiverWindow, TIMER_ID, 0 ,_md_TimerProc); + self->timerSet = PR_TRUE; + _md_WasInputPending = PR_FALSE; + _md_WasPaintPending = PR_FALSE; + return PR_SUCCESS; + } + + qstatus = HIWORD(GetQueueStatus(QS_INPUT | QS_PAINT)); + + /* Check for starved input */ + if (_md_EventIsStarved( _md_IsInputPending(qstatus), + INPUT_STARVATION_LIMIT, + &_md_WasInputPending, + &_md_InputTime, + now )) { + /* + * Use a timer for notification. Timers have the lowest priority. + * They are not processed until all other events have been processed. + * This allows any starved paints and input to be processed. + */ + SetTimer(self->eventReceiverWindow, TIMER_ID, 0 ,_md_TimerProc); + self->timerSet = PR_TRUE; + + /* + * Clear any pending paint. _md_WasInputPending was cleared in + * _md_EventIsStarved. + */ + _md_WasPaintPending = PR_FALSE; + return PR_SUCCESS; + } + + if (_md_EventIsStarved( (qstatus & QS_PAINT), + _md_GetPaintStarvationLimit(), + &_md_WasPaintPending, + &_md_PaintTime, + now) ) { + /* + * Use a timer for notification. Timers have the lowest priority. + * They are not processed until all other events have been processed. + * This allows any starved paints and input to be processed + */ + SetTimer(self->eventReceiverWindow, TIMER_ID, 0 ,_md_TimerProc); + self->timerSet = PR_TRUE; + + /* + * Clear any pending input. _md_WasPaintPending was cleared in + * _md_EventIsStarved. + */ + _md_WasInputPending = PR_FALSE; + return PR_SUCCESS; + } + + /* + * Nothing is being starved so post a message instead of using a timer. + * Posted messages are processed before other messages so they have the + * highest priority. + */ +#endif + PostMessage( self->eventReceiverWindow, _pr_PostEventMsgId, + (WPARAM)0, (LPARAM)self ); + + return PR_SUCCESS; +}/* --- end _pl_NativeNotify() --- */ + +static PRStatus +_pl_AcknowledgeNativeNotify(PLEventQueue* self) +{ + MSG aMsg; + /* + * only remove msg when we've been called directly by + * PL_ProcessPendingEvents, not when we've been called by + * the window proc because the window proc will remove the + * msg for us. + */ + if (self->removeMsg) { + PR_LOG(event_lm, PR_LOG_DEBUG, + ("_pl_AcknowledgeNativeNotify: self=%p", self)); + PeekMessage(&aMsg, self->eventReceiverWindow, + _pr_PostEventMsgId, _pr_PostEventMsgId, PM_REMOVE); + if (self->timerSet) { + KillTimer(self->eventReceiverWindow, TIMER_ID); + self->timerSet = PR_FALSE; + } + } + return PR_SUCCESS; +} + +void +PL_FavorPerformanceHint(PRBool favorPerformanceOverEventStarvation, + PRUint32 starvationDelay) +{ + _md_StarvationDelay = starvationDelay; + + if (favorPerformanceOverEventStarvation) { + _md_PerformanceSetting++; + return; + } + + _md_PerformanceSetting--; + + if (_md_PerformanceSetting == 0) { + /* Switched from allowing event starvation to no event starvation so grab + the current time to determine when to actually switch to using timers + instead of posted WM_APP messages. */ + _md_SwitchTime = PR_IntervalToMilliseconds(PR_IntervalNow()); + } +} +#endif + +NS_IMETHODIMP +nsAppShell::Init(int *argc, char **argv) +{ + mMainThreadId = GetCurrentThreadId(); + mMsgId = RegisterWindowMessage("nsAppShell_Dispatch"); + + return nsBaseAppShell::Init(argc, argv); +} //------------------------------------------------------------------------- // @@ -70,11 +427,6 @@ nsAppShell::nsAppShell() // //------------------------------------------------------------------------- -NS_METHOD nsAppShell::Create(int* argc, char ** argv) -{ - return NS_OK; -} - //------------------------------------------------------------------------- // // Enter a message handler loop @@ -83,7 +435,7 @@ NS_METHOD nsAppShell::Create(int* argc, char ** argv) #include "nsITimerManager.h" -BOOL PeekKeyAndIMEMessage(LPMSG msg, HWND hwnd) +static BOOL PeekKeyAndIMEMessage(LPMSG msg, HWND hwnd) { MSG msg1, msg2, *lpMsg; BOOL b1, b2; @@ -105,16 +457,16 @@ BOOL PeekKeyAndIMEMessage(LPMSG msg, HWND hwnd) return false; } - -NS_METHOD nsAppShell::Run(void) -{ +#if 0 NS_ADDREF_THIS(); MSG msg; int keepGoing = 1; nsresult rv; - nsCOMPtr timerManager(do_GetService("@mozilla.org/timer/manager;1", &rv)); - if (NS_FAILED(rv)) return rv; + nsCOMPtr timerManager = + do_GetService("@mozilla.org/timer/manager;1", &rv); + if (NS_FAILED(rv)) + return rv; timerManager->SetUseIdleTimers(PR_TRUE); @@ -160,15 +512,13 @@ NS_METHOD nsAppShell::Run(void) Release(); return msg.wParam; } +#endif -inline NS_METHOD nsAppShell::Spinup(void) -{ return NS_OK; } - -inline NS_METHOD nsAppShell::Spindown(void) -{ return NS_OK; } - -inline NS_METHOD nsAppShell::ListenToEventQueue(nsIEventQueue * aQueue, PRBool aListen) -{ return NS_OK; } +#if 0 +NS_IMETHODIMP nsAppShell::ListenToEventQueue(nsIEventQueue * aQueue, PRBool aListen) +{ + return NS_OK; +} NS_METHOD nsAppShell::GetNativeEvent(PRBool &aRealEvent, void *&aEvent) @@ -220,30 +570,41 @@ nsresult nsAppShell::DispatchNativeEvent(PRBool aRealEvent, void *aEvent) nsToolkit::mDispatchMessage((MSG *)aEvent); return NS_OK; } +#endif //------------------------------------------------------------------------- -// -// Exit a message handler loop -// -//------------------------------------------------------------------------- +// nsIThreadObserver methods: -NS_METHOD nsAppShell::Exit(void) +NS_IMETHODIMP +nsAppShell::OnDispatchEvent(nsIThreadInternal *thr, PRUint32 flags) { - PostQuitMessage(0); - // - // Also, set a global flag, just in case someone eats the WM_QUIT message. - // see bug #54725. - // - gKeepGoing = 0; + // post a message to the native event queue... + PostThreadMessage(mMainThreadId, mMsgId, 0, 0); return NS_OK; } -//------------------------------------------------------------------------- -// -// nsAppShell destructor -// -//------------------------------------------------------------------------- -nsAppShell::~nsAppShell() +PRBool +nsAppShell::ProcessNextNativeEvent(PRBool mayWait) { -} + // XXX process idle timers + PRBool gotMessage = PR_FALSE; + + do { + MSG msg; + // Give priority to system messages (in particular keyboard, mouse, timer, + // and paint messages). + if (PeekKeyAndIMEMessage(&msg, NULL) || + nsToolkit::mPeekMessage(&msg, NULL, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE) || + nsToolkit::mPeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + gotMessage = PR_TRUE; + TranslateMessage(&msg); + nsToolkit::mDispatchMessage(&msg); + } else if (mayWait) { + // Block and wait for any posted application message + ::WaitMessage(); + } + } while (!gotMessage && mayWait); + + return gotMessage; +} diff --git a/mozilla/widget/src/windows/nsAppShell.h b/mozilla/widget/src/windows/nsAppShell.h index 6a301859788..9f28c58b38f 100644 --- a/mozilla/widget/src/windows/nsAppShell.h +++ b/mozilla/widget/src/windows/nsAppShell.h @@ -38,21 +38,33 @@ #ifndef nsAppShell_h__ #define nsAppShell_h__ -#include "nsIAppShell.h" +#include "nsBaseAppShell.h" +#include "nsITimerManager.h" +#include "nsCOMPtr.h" /** * Native Win32 Application shell wrapper */ - -class nsAppShell : public nsIAppShell +class nsAppShell : public nsBaseAppShell { - public: - nsAppShell(); - virtual ~nsAppShell(); +public: + nsAppShell() : mMainThreadId(0), mMsgId(0) {} - NS_DECL_ISUPPORTS - NS_DECL_NSIAPPSHELL + // nsIAppShell overrides: + NS_IMETHOD Init(int *argc, char **argv); + + // nsIThreadObserver overrides: + NS_IMETHOD OnDispatchEvent(nsIThreadInternal *thread, PRUint32 flags); + + // nsBaseAppShell overrides: + PRBool ProcessNextNativeEvent(PRBool mayWait); + +private: + virtual ~nsAppShell() {} + + nsCOMPtr mTimerManager; + PRUint32 mMainThreadId; + PRUint32 mMsgId; }; #endif // nsAppShell_h__ - diff --git a/mozilla/widget/src/windows/nsToolkit.cpp b/mozilla/widget/src/windows/nsToolkit.cpp index dda718129a0..c053fb1a138 100644 --- a/mozilla/widget/src/windows/nsToolkit.cpp +++ b/mozilla/widget/src/windows/nsToolkit.cpp @@ -37,14 +37,13 @@ * ***** END LICENSE BLOCK ***** */ #include "nsToolkit.h" +#include "nsAppShell.h" #include "nsWindow.h" +#include "nsWidgetsCID.h" #include "prmon.h" #include "prtime.h" #include "nsGUIEvent.h" -#include "plevent.h" #include "nsIServiceManager.h" -#include "nsIEventQueueService.h" -#include "nsIEventQueue.h" #include "nsComponentManagerUtils.h" #include #include @@ -52,11 +51,6 @@ // unknwn.h is needed to build with WIN32_LEAN_AND_MEAN #include -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); - -// Cached reference to event queue service -static nsCOMPtr gEventQueueService; - NS_IMPL_ISUPPORTS1(nsToolkit, nsIToolkit) // If PR_TRUE the user is currently moving a top level window. @@ -344,24 +338,28 @@ struct ThreadInitInfo { #ifndef WINCE LRESULT CALLBACK DetectWindowMove(int code, WPARAM wParam, LPARAM lParam) { + static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID); + /* This msg filter is required to determine when the user has * clicked in the window title bar and is moving the window. */ CWPSTRUCT* sysMsg = (CWPSTRUCT*)lParam; if (sysMsg) { + nsCOMPtr appShell = do_GetService(kAppShellCID); + NS_ASSERTION(appShell, "no appshell"); if (sysMsg->message == WM_ENTERSIZEMOVE) { gIsMovingWindow = PR_TRUE; - // Notify xpcom that it should favor interactivity + // Notify appshell that it should favor interactivity // over performance because the user is moving a // window - PL_FavorPerformanceHint(PR_FALSE, 0); + appShell->FavorPerformanceHint(PR_FALSE, 0); } else if (sysMsg->message == WM_EXITSIZEMOVE) { gIsMovingWindow = PR_FALSE; - // Notify xpcom that it should go back to its + // Notify appshell that it should go back to its // previous performance setting which may favor // performance over interactivity - PL_FavorPerformanceHint(PR_TRUE, 0); + appShell->FavorPerformanceHint(PR_TRUE, 0); } } return CallNextHookEx(nsMsgFilterHook, code, wParam, lParam); @@ -787,9 +785,6 @@ nsToolkit::~nsToolkit() // Remove the TLS reference to the toolkit... PR_SetThreadPrivate(gToolkitTLSIndex, nsnull); - // Remove reference to cached event queue - gEventQueueService = nsnull; - if (gMouseTrailer) { gMouseTrailer->DestroyTimer(); delete gMouseTrailer; @@ -878,23 +873,6 @@ nsToolkit::Shutdown() nsToolkit::mUnregisterClass(L"nsToolkitClass", nsToolkit::mDllInstance); } -nsIEventQueue* -nsToolkit::GetEventQueue() -{ - if (! gEventQueueService) { - gEventQueueService = do_GetService(kEventQueueServiceCID); - } - - if (gEventQueueService) { - nsCOMPtr eventQueue; - gEventQueueService->GetSpecialEventQueue( - nsIEventQueueService::UI_THREAD_EVENT_QUEUE, - getter_AddRefs(eventQueue)); - return eventQueue; - } - - return nsnull; -} //------------------------------------------------------------------------- // diff --git a/mozilla/widget/src/windows/nsToolkit.h b/mozilla/widget/src/windows/nsToolkit.h index 9ad47a8af3f..a83543ac1ad 100644 --- a/mozilla/widget/src/windows/nsToolkit.h +++ b/mozilla/widget/src/windows/nsToolkit.h @@ -84,7 +84,6 @@ class nsToolkit : public nsIToolkit void CreateInternalWindow(PRThread *aThread); // Return whether the user is currently moving any application window PRBool UserIsMovingWindow(void); - nsIEventQueue* GetEventQueue(void); private: ~nsToolkit(); diff --git a/mozilla/widget/src/windows/nsWindow.cpp b/mozilla/widget/src/windows/nsWindow.cpp index d4ae7512fa9..35a40e18aac 100644 --- a/mozilla/widget/src/windows/nsWindow.cpp +++ b/mozilla/widget/src/windows/nsWindow.cpp @@ -56,7 +56,6 @@ #endif #include "nsWindow.h" -#include "plevent.h" #include "nsIAppShell.h" #include "nsIFontMetrics.h" #include "nsIFontEnumerator.h" @@ -70,7 +69,7 @@ #include "nsIScreenManager.h" #include "nsRect.h" #include "nsTransform2D.h" -#include "nsIEventQueue.h" +#include "nsThreadUtils.h" #include "nsIObserverService.h" #include "imgIContainer.h" #include "gfxIImageFrame.h" @@ -3970,9 +3969,9 @@ BOOL CALLBACK nsWindow::DispatchStarvedPaints(HWND aWnd, LPARAM aMsg) // Check for pending paints and dispatch any pending paint // messages for any nsIWidget which is a descendant of the // top-level window that *this* window is embedded within. -// Also dispatch pending PL_Events to avoid PL_EventQueue starvation. -// Note: We do not dispatch pending paint messages for non -// nsIWidget managed windows. +// Also dispatch pending tasks to avoid starvation (see +// nsAppShell.cpp). Note: We do not dispatch pending paint +// messages for non nsIWidget managed windows. void nsWindow::DispatchPendingEvents() { @@ -3984,12 +3983,8 @@ void nsWindow::DispatchPendingEvents() // dispatching the native WM_TIMER event that is used for PL_Event // notification because the timer message will not appear in the // native msg queue until 10ms after the event is posted. Which is too late. - nsCOMPtr eventQueue; - nsToolkit *toolkit = NS_STATIC_CAST(nsToolkit *, mToolkit); - eventQueue = toolkit->GetEventQueue(); - if (eventQueue) { - eventQueue->ProcessPendingEvents(); - } + nsCOMPtr thread = do_GetCurrentThread(); + NS_ProcessPendingEvents(thread); // Quickly check to see if there are any // paint events pending. diff --git a/mozilla/widget/src/xpwidgets/Makefile.in b/mozilla/widget/src/xpwidgets/Makefile.in index 3b7e412334f..8b5672d95c6 100644 --- a/mozilla/widget/src/xpwidgets/Makefile.in +++ b/mozilla/widget/src/xpwidgets/Makefile.in @@ -69,6 +69,7 @@ endif DEFINES += -D_IMPL_NS_WIDGET -DUSE_TLS_FOR_TOOLKIT CPPSRCS = \ + nsBaseAppShell.cpp \ nsBaseWidget.cpp \ nsTransferable.cpp \ nsHTMLFormatConverter.cpp \ diff --git a/mozilla/widget/src/xpwidgets/nsBaseAppShell.cpp b/mozilla/widget/src/xpwidgets/nsBaseAppShell.cpp new file mode 100644 index 00000000000..b942c4fd20b --- /dev/null +++ b/mozilla/widget/src/xpwidgets/nsBaseAppShell.cpp @@ -0,0 +1,137 @@ +/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Michael Lowe + * Darin Fisher + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsBaseAppShell.h" +#include "nsThreadUtils.h" + +// When processing the next thread event, the appshell may process native +// events (if not in performance mode), which can result in suppressing the +// next thread event for at most this many ticks: +#define THREAD_EVENT_STARVATION_LIMIT PR_MillisecondsToInterval(20) + +// Must be threadsafe since nsIThreadObserver::OnNewTask may be called from +// any background thread. +NS_IMPL_THREADSAFE_ISUPPORTS2(nsBaseAppShell, nsIAppShell, nsIThreadObserver) + +//------------------------------------------------------------------------- +// nsIAppShell methods: + +NS_IMETHODIMP +nsBaseAppShell::Init(int *argc, char **argv) +{ + // Configure ourselves as an observer for the current thread: + + nsCOMPtr thread = do_GetCurrentThread(); + NS_ENSURE_STATE(thread); + + nsCOMPtr threadInt = do_QueryInterface(thread); + NS_ENSURE_STATE(threadInt); + threadInt->SetObserver(this); + return NS_OK; +} + +NS_IMETHODIMP +nsBaseAppShell::Run(void) +{ + nsCOMPtr thread = do_GetCurrentThread(); + NS_ENSURE_STATE(thread); + + ++mKeepGoing; + while (mKeepGoing) + thread->ProcessNextEvent(); + + NS_ProcessPendingEvents(thread); + return NS_OK; +} + +NS_IMETHODIMP +nsBaseAppShell::Exit(void) +{ + // Allow more calls to Exit than Run. + if (--mKeepGoing < 0) + mKeepGoing = 0; + return NS_OK; +} + +NS_IMETHODIMP +nsBaseAppShell::FavorPerformanceHint(PRBool favorPerfOverStarvation, + PRUint32 starvationDelay) +{ + mStarvationDelay = PR_MillisecondsToInterval(starvationDelay); + if (favorPerfOverStarvation) { + ++mFavorPerf; + } else { + --mFavorPerf; + mSwitchTime = PR_IntervalNow(); + } + return NS_OK; +} + +//------------------------------------------------------------------------- +// nsIThreadObserver methods: + +NS_IMETHODIMP +nsBaseAppShell::OnDispatchedEvent(nsIThreadInternal *thr) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsBaseAppShell::OnProcessNextEvent(nsIThreadInternal *thr, + PRBool mayWait) +{ + if (mFavorPerf <= 0) { + PRIntervalTime start = PR_IntervalNow(); + if (start > mSwitchTime + mStarvationDelay) { + // Favor pending native events + PRIntervalTime limit = THREAD_EVENT_STARVATION_LIMIT; + PRBool keepGoing; + do { + keepGoing = ProcessNextNativeEvent(PR_FALSE); + } while (keepGoing && (PR_IntervalNow() - start) < limit); + } + } + + PRBool val; + while (NS_SUCCEEDED(thr->HasPendingEvents(&val)) && !val) { + if (!ProcessNextNativeEvent(mayWait) && !mayWait) + break; + } + return NS_OK; +} diff --git a/mozilla/widget/src/xpwidgets/nsBaseAppShell.h b/mozilla/widget/src/xpwidgets/nsBaseAppShell.h new file mode 100644 index 00000000000..1fcbed66573 --- /dev/null +++ b/mozilla/widget/src/xpwidgets/nsBaseAppShell.h @@ -0,0 +1,80 @@ +/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsBaseAppShell_h__ +#define nsBaseAppShell_h__ + +#include "nsIAppShell.h" +#include "nsIThreadInternal.h" +#include "prinrval.h" + +/** + * A singleton that manages the UI thread's event queue. Subclass this class + * to enable platform-specific event queue support. + */ +class nsBaseAppShell : public nsIAppShell, public nsIThreadObserver +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIAPPSHELL + NS_DECL_NSITHREADOBSERVER + + nsBaseAppShell() + : mKeepGoing(0) + , mFavorPerf(0) + , mStarvationDelay(0) + , mSwitchTime(0) + {} + +protected: + virtual ~nsBaseAppShell() {} + + /** + * Implemented by subclasses. Process the next native event. Only wait for + * the next native event if mayWait is true. Return true if a native event + * was processed. + */ + virtual PRBool ProcessNextNativeEvent(PRBool mayWait) = 0; + +protected: + PRInt32 mKeepGoing; + PRInt32 mFavorPerf; + PRIntervalTime mStarvationDelay; + PRIntervalTime mSwitchTime; +}; + +#endif // nsBaseAppShell_h__ diff --git a/mozilla/xpcom/base/nsConsoleService.cpp b/mozilla/xpcom/base/nsConsoleService.cpp index 0f4c1eba0a4..d849dda887a 100644 --- a/mozilla/xpcom/base/nsConsoleService.cpp +++ b/mozilla/xpcom/base/nsConsoleService.cpp @@ -46,6 +46,7 @@ #include "nsIServiceManager.h" #include "nsIProxyObjectManager.h" #include "nsSupportsArray.h" +#include "nsThreadUtils.h" #include "nsConsoleService.h" #include "nsConsoleMessage.h" @@ -308,24 +309,14 @@ nsresult nsConsoleService::GetProxyForListener(nsIConsoleListener* aListener, nsIConsoleListener** aProxy) { - nsresult rv; - *aProxy = nsnull; - - nsCOMPtr proxyManager = - (do_GetService(NS_XPCOMPROXY_CONTRACTID)); - - if (proxyManager == nsnull) - return NS_ERROR_NOT_AVAILABLE; - /* * NOTE this will fail if the calling thread doesn't have an eventQ. * * Would it be better to catch that case and leave the listener unproxied? */ - rv = proxyManager->GetProxyForObject(NS_CURRENT_EVENTQ, - NS_GET_IID(nsIConsoleListener), - aListener, - PROXY_ASYNC | PROXY_ALWAYS, - (void**) aProxy); - return rv; + return NS_GetProxyForObject(NS_PROXY_TO_CURRENT_THREAD, + NS_GET_IID(nsIConsoleListener), + aListener, + NS_PROXY_ASYNC | NS_PROXY_ALWAYS, + (void**) aProxy); } diff --git a/mozilla/xpcom/base/nsMemoryImpl.cpp b/mozilla/xpcom/base/nsMemoryImpl.cpp index 36c2ad191a2..5b565b997c7 100644 --- a/mozilla/xpcom/base/nsMemoryImpl.cpp +++ b/mozilla/xpcom/base/nsMemoryImpl.cpp @@ -37,16 +37,15 @@ #include "nsXPCOM.h" #include "nsMemoryImpl.h" +#include "nsThreadUtils.h" -#include "nsIEventQueueService.h" #include "nsIObserverService.h" -#include "nsIRunnable.h" #include "nsIServiceManager.h" #include "nsISupportsArray.h" -#include "nsIThread.h" #include "prmem.h" -#include "plevent.h" +#include "prcvar.h" +#include "pratom.h" #include "nsAlgorithm.h" #include "nsAutoLock.h" @@ -55,10 +54,14 @@ #if defined(XP_WIN) #include -#define NS_MEMORY_FLUSHER_THREAD +#define NS_MEMORY_FLUSHER #else // Need to implement the nsIMemory::IsLowMemory() predicate -#undef NS_MEMORY_FLUSHER_THREAD +#undef NS_MEMORY_FLUSHER +#endif + +#ifdef NS_MEMORY_FLUSHER +#include "nsITimer.h" #endif //////////////////////////////////////////////////////////////////////////////// @@ -115,14 +118,14 @@ reallocator(void* ptr, PRSize size, PRUint32& counter, PRUint32 max) #define NS_TEST_MEMORY_FLUSHER #endif -#ifdef NS_MEMORY_FLUSHER_THREAD +#ifdef NS_MEMORY_FLUSHER /** * A runnable that is used to periodically check the status * of the system, determine if too much memory is in use, * and if so, trigger a "memory flush". */ -class MemoryFlusher : public nsIRunnable +class MemoryFlusher : public nsITimerCallback { public: // We don't use the generic macros because we are a special static object @@ -130,26 +133,24 @@ public: NS_IMETHOD_(nsrefcnt) AddRef(void) { return 1; } NS_IMETHOD_(nsrefcnt) Release(void) { return 1; } - NS_DECL_NSIRUNNABLE + NS_DECL_NSITIMERCALLBACK nsresult Init(); void StopAndJoin(); private: - static PRBool sRunning; static PRIntervalTime sTimeout; static PRLock* sLock; static PRCondVar* sCVar; - static nsIThread* sThread; enum { - kInitialTimeout = 60 /*seconds*/ + kTimeout = 60000 // milliseconds }; }; static MemoryFlusher sGlobalMemoryFlusher; -#endif // NS_MEMORY_FLUSHER_THREAD +#endif // NS_MEMORY_FLUSHER static nsMemoryImpl sGlobalMemory; @@ -197,30 +198,14 @@ nsMemoryImpl::IsLowMemory(PRBool *result) } -nsresult -nsMemoryImpl::Startup() +void +nsMemoryImpl::InitFlusher() { - sFlushLock = PR_NewLock(); - if (!sFlushLock) return NS_ERROR_FAILURE; - -#ifdef NS_MEMORY_FLUSHER_THREAD - return sGlobalMemoryFlusher.Init(); -#else - return NS_OK; +#ifdef NS_MEMORY_FLUSHER + sGlobalMemoryFlusher.Init(); #endif } -void -nsMemoryImpl::Shutdown() -{ -#ifdef NS_MEMORY_FLUSHER_THREAD - sGlobalMemoryFlusher.StopAndJoin(); -#endif - - if (sFlushLock) PR_DestroyLock(sFlushLock); - sFlushLock = nsnull; -} - nsresult nsMemoryImpl::Create(nsISupports* outer, const nsIID& aIID, void **aResult) { @@ -237,34 +222,15 @@ nsMemoryImpl::FlushMemory(const PRUnichar* aReason, PRBool aImmediate) // They've asked us to run the flusher *immediately*. We've // got to be on the UI main thread for us to be able to do // that...are we? - PRBool isOnUIThread = PR_FALSE; - - nsCOMPtr main; - rv = nsIThread::GetMainThread(getter_AddRefs(main)); - if (NS_SUCCEEDED(rv)) { - nsCOMPtr current; - rv = nsIThread::GetCurrent(getter_AddRefs(current)); - if (NS_SUCCEEDED(rv)) { - if (current == main) - isOnUIThread = PR_TRUE; - } - } - - if (! isOnUIThread) { + if (!NS_IsMainThread()) { NS_ERROR("can't synchronously flush memory: not on UI thread"); return NS_ERROR_FAILURE; } } - { - // Are we already flushing? - nsAutoLock l(sFlushLock); - if (sIsFlushing) - return NS_OK; - - // Well, we are now! - sIsFlushing = PR_TRUE; - } + PRInt32 lastVal = PR_AtomicSet(&sIsFlushing, 1); + if (lastVal) + return NS_OK; // Run the flushers immediately if we can; otherwise, proxy to the // UI thread an run 'em asynchronously. @@ -272,17 +238,8 @@ nsMemoryImpl::FlushMemory(const PRUnichar* aReason, PRBool aImmediate) rv = RunFlushers(aReason); } else { - nsCOMPtr eqs = do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv); - if (eqs) { - nsCOMPtr eq; - rv = eqs->GetThreadEventQueue(NS_UI_THREAD, getter_AddRefs(eq)); - if (NS_SUCCEEDED(rv)) { - PL_InitEvent(&sFlushEvent.mEvent, this, HandleFlushEvent, DestroyFlushEvent); - sFlushEvent.mReason = aReason; - - rv = eq->PostEvent(NS_REINTERPRET_CAST(PLEvent*, &sFlushEvent)); - } - } + sFlushEvent.mReason = aReason; + rv = NS_DispatchToMainThread(&sFlushEvent, NS_DISPATCH_NORMAL); } return rv; @@ -296,33 +253,22 @@ nsMemoryImpl::RunFlushers(const PRUnichar* aReason) os->NotifyObservers(this, "memory-pressure", aReason); } - { - // Done flushing - nsAutoLock l(sFlushLock); - sIsFlushing = PR_FALSE; - } - + sIsFlushing = 0; return NS_OK; } -void* -nsMemoryImpl::HandleFlushEvent(PLEvent* aEvent) +// XXX need NS_IMPL_STATIC_ADDREF/RELEASE +NS_IMETHODIMP_(nsrefcnt) nsMemoryImpl::FlushEvent::AddRef() { return 2; } +NS_IMETHODIMP_(nsrefcnt) nsMemoryImpl::FlushEvent::Release() { return 1; } +NS_IMPL_QUERY_INTERFACE1(nsMemoryImpl::FlushEvent, nsIRunnable) + +NS_IMETHODIMP +nsMemoryImpl::FlushEvent::Run() { - FlushEvent* event = NS_REINTERPRET_CAST(FlushEvent*, aEvent); - - sGlobalMemory.RunFlushers(event->mReason); - return 0; + sGlobalMemory.RunFlushers(mReason); + return NS_OK; } -void -nsMemoryImpl::DestroyFlushEvent(PLEvent* aEvent) -{ - // no-op, since mEvent is a member of nsMemoryImpl -} - -PRLock* -nsMemoryImpl::sFlushLock; - PRBool nsMemoryImpl::sIsFlushing = PR_FALSE; @@ -357,116 +303,40 @@ NS_Free(void* ptr) PR_Free(ptr); } -#ifdef NS_MEMORY_FLUSHER_THREAD +#ifdef NS_MEMORY_FLUSHER -NS_IMPL_QUERY_INTERFACE1(MemoryFlusher, nsIRunnable) +NS_IMPL_QUERY_INTERFACE1(MemoryFlusher, nsITimerCallback) NS_IMETHODIMP -MemoryFlusher::Run() +MemoryFlusher::Notify(nsITimer *timer) { - nsresult rv; - - sRunning = PR_TRUE; - - while (1) { - PRStatus status; - - { - nsAutoLock l(sLock); - if (! sRunning) { - rv = NS_OK; - break; - } - - status = PR_WaitCondVar(sCVar, sTimeout); - } - - if (status != PR_SUCCESS) { - rv = NS_ERROR_FAILURE; - break; - } - - if (! sRunning) { - rv = NS_OK; - break; - } - - PRBool isLowMemory; - rv = sGlobalMemory.IsLowMemory(&isLowMemory); - if (NS_FAILED(rv)) - break; + PRBool isLowMemory; + sGlobalMemory.IsLowMemory(&isLowMemory); #ifdef NS_TEST_MEMORY_FLUSHER - // Fire the flusher *every* time - isLowMemory = PR_TRUE; + // Fire the flusher *every* time + isLowMemory = PR_TRUE; #endif - if (isLowMemory) { - sGlobalMemory.FlushMemory(NS_LITERAL_STRING("low-memory").get(), PR_FALSE); - } - } - - sRunning = PR_FALSE; - - return rv; + if (isLowMemory) + sGlobalMemory.FlushMemory(NS_LITERAL_STRING("low-memory").get(), + PR_FALSE); + return NS_OK; } nsresult MemoryFlusher::Init() { - sTimeout = PR_SecondsToInterval(kInitialTimeout); - sLock = PR_NewLock(); - if (!sLock) return NS_ERROR_FAILURE; + nsCOMPtr timer = do_CreateInstance(NS_TIMER_CONTRACTID); + NS_ENSURE_STATE(timer); - sCVar = PR_NewCondVar(sLock); - if (!sCVar) return NS_ERROR_FAILURE; + // There's no need to keep a reference to the timer object... - return NS_NewThread(&sThread, - this, - 0, /* XXX use default stack size? */ - PR_JOINABLE_THREAD); + return timer->InitWithCallback(this, kTimeout, + nsITimer::TYPE_REPEATING_SLACK); } -void -MemoryFlusher::StopAndJoin() -{ - if (sRunning) { - { - nsAutoLock l(sLock); - sRunning = PR_FALSE; - PR_NotifyCondVar(sCVar); - } - - if (sThread) - sThread->Join(); - } - - NS_IF_RELEASE(sThread); - - if (sLock) - PR_DestroyLock(sLock); - - if (sCVar) - PR_DestroyCondVar(sCVar); -} - - -PRBool -MemoryFlusher::sRunning; - -PRIntervalTime -MemoryFlusher::sTimeout; - -PRLock* -MemoryFlusher::sLock; - -PRCondVar* -MemoryFlusher::sCVar; - -nsIThread* -MemoryFlusher::sThread; - -#endif // NS_MEMORY_FLUSHER_THREAD +#endif // NS_MEMORY_FLUSHER nsresult NS_GetMemoryManager(nsIMemory* *result) diff --git a/mozilla/xpcom/base/nsMemoryImpl.h b/mozilla/xpcom/base/nsMemoryImpl.h index e179b1d52ba..3661780fc60 100644 --- a/mozilla/xpcom/base/nsMemoryImpl.h +++ b/mozilla/xpcom/base/nsMemoryImpl.h @@ -39,8 +39,7 @@ #define nsMemoryImpl_h__ #include "nsIMemory.h" -#include "prlock.h" -#include "plevent.h" +#include "nsIRunnable.h" // nsMemoryImpl is a static object. We can do this because it doesn't have // a constructor/destructor or any instance members. Please don't add @@ -56,26 +55,22 @@ public: NS_DECL_NSIMEMORY - static NS_HIDDEN_(nsresult) Startup(); - static NS_HIDDEN_(void) Shutdown(); + static NS_HIDDEN_(void) InitFlusher(); static NS_METHOD Create(nsISupports* outer, const nsIID& aIID, void **aResult); NS_HIDDEN_(nsresult) FlushMemory(const PRUnichar* aReason, PRBool aImmediate); protected: - struct FlushEvent { - PLEvent mEvent; + struct FlushEvent : public nsIRunnable { + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_NSIRUNNABLE const PRUnichar* mReason; }; NS_HIDDEN_(nsresult) RunFlushers(const PRUnichar* aReason); - static NS_HIDDEN_(void*) PR_CALLBACK HandleFlushEvent(PLEvent* aEvent); - static NS_HIDDEN_(void) PR_CALLBACK DestroyFlushEvent(PLEvent* aEvent); - - static PRLock* sFlushLock; - static PRBool sIsFlushing; + static PRInt32 sIsFlushing; static FlushEvent sFlushEvent; }; diff --git a/mozilla/xpcom/build/dlldeps.cpp b/mozilla/xpcom/build/dlldeps.cpp index 812b7ec8af2..ff432c73c05 100644 --- a/mozilla/xpcom/build/dlldeps.cpp +++ b/mozilla/xpcom/build/dlldeps.cpp @@ -45,7 +45,6 @@ #include "nsIAtom.h" #include "nsFixedSizeAllocator.h" #include "nsRecyclingAllocator.h" -#include "nsIThread.h" #include "nsDeque.h" #include "nsTraceRefcnt.h" #include "nsTraceRefcntImpl.h" @@ -140,7 +139,6 @@ void XXXNeverCalled() a.Init(0, 0, 0, 0, 0); a.Alloc(0); a.Free(0, 0); - nsIThread::GetCurrent(nsnull); nsDeque d(nsnull); nsDequeIterator di(d); nsTraceRefcnt::LogAddCOMPtr(nsnull, nsnull); diff --git a/mozilla/xpcom/build/nsXPCOMCID.h b/mozilla/xpcom/build/nsXPCOMCID.h index 26299091d0b..631fd1716a3 100644 --- a/mozilla/xpcom/build/nsXPCOMCID.h +++ b/mozilla/xpcom/build/nsXPCOMCID.h @@ -188,4 +188,14 @@ { 0xb9, 0xb8, 0xc8, 0x11, 0x75, 0x95, 0x51, 0x99 } } #define NS_HASH_PROPERTY_BAG_CONTRACTID "@mozilla.org/hash-property-bag;1" +/** + * Implementation of nsIThreadManager + */ +#define NS_THREADMANAGER_CONTRACTID "@mozilla.org/thread-manager;1" + +/** + * Implementation of nsIThreadPool + */ +#define NS_THREADPOOL_CONTRACTID "@mozilla.org/thread-pool;1" + #endif diff --git a/mozilla/xpcom/build/nsXPComInit.cpp b/mozilla/xpcom/build/nsXPComInit.cpp index 68758375b4b..54575a527a5 100644 --- a/mozilla/xpcom/build/nsXPComInit.cpp +++ b/mozilla/xpcom/build/nsXPComInit.cpp @@ -1,4 +1,5 @@ /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* vim:set ts=4 sw=4 sts=4 ci et: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -70,9 +71,8 @@ #include "nsIServiceManager.h" #include "nsGenericFactory.h" -#include "nsEventQueueService.h" -#include "nsEventQueue.h" -#include "nsEventQueueUtils.h" +#include "nsThreadManager.h" +#include "nsThreadPool.h" #include "nsIProxyObjectManager.h" #include "nsProxyEventPrivate.h" // access to the impl of nsProxyObjectManager for the generic factory registration. @@ -153,7 +153,6 @@ static NS_DEFINE_CID(kMemoryCID, NS_MEMORY_CID); static NS_DEFINE_CID(kINIParserFactoryCID, NS_INIPARSERFACTORY_CID); NS_GENERIC_FACTORY_CONSTRUCTOR(nsProcess) -NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsEventQueueServiceImpl, Init) #define NS_ENVIRONMENT_CLASSNAME "Environment Service" @@ -225,6 +224,21 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsUUIDGenerator) NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacUtilsImpl) #endif +static NS_METHOD +nsThreadManagerGetSingleton(nsISupports* outer, + const nsIID& aIID, + void* *aInstancePtr) +{ + NS_ASSERTION(aInstancePtr, "null outptr"); + NS_ENSURE_TRUE(!outer, NS_ERROR_NO_AGGREGATION); + + return nsThreadManager::get()->QueryInterface(aIID, aInstancePtr); +} +NS_DECL_CLASSINFO(nsThreadManager) + +NS_GENERIC_FACTORY_CONSTRUCTOR(nsThreadPool) +NS_DECL_CLASSINFO(nsThreadPool) + static NS_METHOD nsXPTIInterfaceInfoManagerGetSingleton(nsISupports* outer, const nsIID& aIID, @@ -357,9 +371,6 @@ static const nsModuleComponentInfo components[] = { #endif COMPONENT(OBSERVERSERVICE, nsObserverService::Create), COMPONENT(GENERICFACTORY, nsGenericFactory::Create), - COMPONENT(EVENTQUEUESERVICE, nsEventQueueServiceImplConstructor), - COMPONENT(EVENTQUEUE, nsEventQueueImpl::Create), - COMPONENT(THREAD, nsThread::Create), #define NS_XPCOMPROXY_CID NS_PROXYEVENT_MANAGER_CID COMPONENT(XPCOMPROXY, nsProxyObjectManager::Create), @@ -396,6 +407,12 @@ static const nsModuleComponentInfo components[] = { COMPONENT(PROCESS, nsProcessConstructor), COMPONENT(ENVIRONMENT, nsEnvironment::Create), + COMPONENT_CI_FLAGS(THREADMANAGER, nsThreadManagerGetSingleton, + nsThreadManager, + nsIClassInfo::THREADSAFE | nsIClassInfo::SINGLETON), + COMPONENT_CI_FLAGS(THREADPOOL, nsThreadPoolConstructor, + nsThreadPool, nsIClassInfo::THREADSAFE), + COMPONENT_CI_FLAGS(STRINGINPUTSTREAM, nsStringInputStreamConstructor, nsStringInputStream, nsIClassInfo::THREADSAFE), COMPONENT(MULTIPLEXINPUTSTREAM, nsMultiplexInputStreamConstructor), @@ -483,17 +500,13 @@ NS_InitXPCOM3(nsIServiceManager* *result, NS_LogInit(); // Establish the main thread here. - rv = nsIThread::SetMainThread(); + rv = nsThreadManager::get()->Init(); if (NS_FAILED(rv)) return rv; // Set up the timer globals/timer thread rv = nsTimerImpl::Startup(); NS_ENSURE_SUCCESS(rv, rv); - // Startup the memory manager - rv = nsMemoryImpl::Startup(); - if (NS_FAILED(rv)) return rv; - #ifndef WINCE // If the locale hasn't already been setup by our embedder, // get us out of the "C" locale and into the system @@ -630,6 +643,9 @@ NS_InitXPCOM3(nsIServiceManager* *result, // to the directory service. nsDirectoryService::gService->RegisterCategoryProviders(); + // Initialize memory flusher + nsMemoryImpl::InitFlusher(); + // Notify observers of xpcom autoregistration start NS_CreateServicesFromCategory(NS_XPCOM_STARTUP_OBSERVER_ID, nsnull, @@ -663,8 +679,9 @@ NS_InitXPCOM3(nsIServiceManager* *result, EXPORT_XPCOM_API(nsresult) NS_ShutdownXPCOM(nsIServiceManager* servMgr) { - nsresult rv; + NS_ENSURE_STATE(NS_IsMainThread()); + nsresult rv; nsCOMPtr moduleLoaders; // Notify observers of xpcom shutting down @@ -672,14 +689,7 @@ NS_ShutdownXPCOM(nsIServiceManager* servMgr) // Block it so that the COMPtr will get deleted before we hit // servicemanager shutdown - // grab the event queue service so that we can process events and - // manage event queues - nsRefPtr eqs; - CallGetService(NS_EVENTQUEUESERVICE_CONTRACTID, - (nsEventQueueServiceImpl**) getter_AddRefs(eqs)); - - nsCOMPtr currentQ; - NS_GetCurrentEventQ(getter_AddRefs(currentQ), eqs); + nsCOMPtr thread = do_GetCurrentThread(); nsRefPtr observerService; CallGetService("@mozilla.org/observer-service;1", @@ -697,28 +707,31 @@ NS_ShutdownXPCOM(nsIServiceManager* servMgr) } } - if (currentQ) - currentQ->ProcessPendingEvents(); - - // Shutdown the timer thread and all timers that might still be alive - nsTimerImpl::Shutdown(); - - if (currentQ) - currentQ->ProcessPendingEvents(); + if (thread) + NS_ProcessPendingEvents(thread); if (observerService) (void) observerService-> NotifyObservers(nsnull, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID, nsnull); - if (currentQ) - currentQ->ProcessPendingEvents(); + if (thread) + NS_ProcessPendingEvents(thread); - if (eqs) - eqs->Shutdown(); + // Shutdown the timer thread and all timers that might still be alive before + // shutting down the component manager + nsTimerImpl::Shutdown(); - if (currentQ) - currentQ->ProcessPendingEvents(); + if (thread) + NS_ProcessPendingEvents(thread); + + // Shutdown all remaining threads. This method does not return until + // all threads created using the thread manager (with the exception of + // the main thread) have exited. + nsThreadManager::get()->Shutdown(); + + if (thread) + NS_ProcessPendingEvents(thread); // We save the "xpcom-shutdown-loaders" observers to notify after // the observerservice is gone. @@ -810,9 +823,7 @@ NS_ShutdownXPCOM(nsIServiceManager* servMgr) ShutdownSpecialSystemDirectory(); EmptyEnumeratorImpl::Shutdown(); - nsMemoryImpl::Shutdown(); - nsThread::Shutdown(); NS_PurgeAtomTable(); NS_IF_RELEASE(gDebug); diff --git a/mozilla/xpcom/components/nsCategoryManager.cpp b/mozilla/xpcom/components/nsCategoryManager.cpp index de75f0ad662..6efed14e216 100644 --- a/mozilla/xpcom/components/nsCategoryManager.cpp +++ b/mozilla/xpcom/components/nsCategoryManager.cpp @@ -59,6 +59,7 @@ #include "nsQuickSort.h" #include "nsEnumeratorUtils.h" #include "nsIProxyObjectManager.h" +#include "nsThreadUtils.h" class nsIComponentLoaderManager; @@ -546,12 +547,13 @@ nsCategoryManager::NotifyObservers( const char *aTopic, return; nsCOMPtr obsProxy; - NS_GetProxyForObject(NS_UI_THREAD_EVENTQ, + NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD, NS_GET_IID(nsIObserverService), observerService, - PROXY_ASYNC, + NS_PROXY_ASYNC, getter_AddRefs(obsProxy)); - if (!obsProxy) return; + if (!obsProxy) + return; if (aEntryName) { nsCOMPtr entry diff --git a/mozilla/xpcom/ds/nsObserverService.cpp b/mozilla/xpcom/ds/nsObserverService.cpp index c5b11be88f9..c13bf96161d 100644 --- a/mozilla/xpcom/ds/nsObserverService.cpp +++ b/mozilla/xpcom/ds/nsObserverService.cpp @@ -47,8 +47,8 @@ #include "nsObserverService.h" #include "nsObserverList.h" #include "nsHashtable.h" +#include "nsThreadUtils.h" #include "nsIWeakReference.h" -#include "nsIThread.h" #include "nsIEnumerator.h" #define NOTIFY_GLOBAL_OBSERVERS @@ -111,7 +111,7 @@ nsObserverService::Create(nsISupports* outer, const nsIID& aIID, void* *aInstanc } #define NS_ENSURE_VALIDCALL \ - if (!nsIThread::IsMainThread()) { \ + if (!NS_IsMainThread()) { \ NS_ERROR("Using observer service off the main thread!"); \ return NS_ERROR_UNEXPECTED; \ } \ diff --git a/mozilla/xpcom/ds/nsRecyclingAllocator.cpp b/mozilla/xpcom/ds/nsRecyclingAllocator.cpp index da79eafc95f..525537a3f1e 100644 --- a/mozilla/xpcom/ds/nsRecyclingAllocator.cpp +++ b/mozilla/xpcom/ds/nsRecyclingAllocator.cpp @@ -238,7 +238,9 @@ nsRecyclingAllocator::Free(void *ptr) (void) NS_NewTimer(&mRecycleTimer, nsRecycleTimerCallback, this, NS_SEC_TO_MS(mRecycleAfter), nsITimer::TYPE_REPEATING_SLACK); - NS_ASSERTION(mRecycleTimer, "nsRecyclingAllocator: Creating timer failed"); + // This can fail during xpcom shutdown + if (!mRecycleTimer) + NS_WARNING("nsRecyclingAllocator: Creating timer failed"); } } diff --git a/mozilla/xpcom/glue/Makefile.in b/mozilla/xpcom/glue/Makefile.in index edea7e622da..71a522ca2a3 100644 --- a/mozilla/xpcom/glue/Makefile.in +++ b/mozilla/xpcom/glue/Makefile.in @@ -85,6 +85,7 @@ EXPORTS = \ nsTHashtable.h \ nsVoidArray.h \ nsTArray.h \ + nsTWeakRef.h \ $(NULL) SDK_HEADERS = \ diff --git a/mozilla/xpcom/glue/nsTWeakRef.h b/mozilla/xpcom/glue/nsTWeakRef.h new file mode 100644 index 00000000000..80432285520 --- /dev/null +++ b/mozilla/xpcom/glue/nsTWeakRef.h @@ -0,0 +1,161 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla code. + * + * The Initial Developer of the Original Code is Google Inc. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Darin Fisher + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsTWeakRef_h__ +#define nsTWeakRef_h__ + +#ifndef nsDebug_h___ +#include "nsDebug.h" +#endif + +/** + * A weak reference class for use with generic C++ objects. + */ +template +class nsTWeakRef { +public: + ~nsTWeakRef() { + if (mRef) + mRef->Release(); + } + + /** + * Construct from an object pointer (may be null). + */ + explicit + nsTWeakRef(Type *obj = nsnull) { + if (obj) { + mRef = new Inner(obj); + } else { + mRef = nsnull; + } + } + + /** + * Construct from another weak reference object. + */ + explicit + nsTWeakRef(const nsTWeakRef &other) : mRef(other.mRef) { + if (mRef) + mRef->AddRef(); + } + + /** + * Assign from an object pointer. + */ + nsTWeakRef &operator=(Type *obj) { + if (mRef) + mRef->Release(); + if (obj) { + mRef = new Inner(obj); + } else { + mRef = nsnull; + } + return *this; + } + + /** + * Assign from another weak reference object. + */ + nsTWeakRef &operator=(const nsTWeakRef &other) { + if (mRef) + mRef->Release(); + mRef = other.mRef; + if (mRef) + mRef->AddRef(); + return *this; + } + + /** + * Get the referenced object. This method may return null if the reference + * has been cleared. + */ + Type *get() const { + return mRef ? mRef->mObj : nsnull; + } + + /** + * Called to "null out" the weak reference. Typically, the object referenced + * by this weak reference calls this method when it is being destroyed. + * @returns The former referenced object. + */ + Type *forget() { + Type *obj; + if (mRef) { + obj = mRef->mObj; + mRef->mObj = nsnull; + mRef->Release(); + mRef = nsnull; + } else { + obj = nsnull; + } + return obj; + } + + /** + * Allow |*this| to be treated as a |Type*| for convenience. + */ + operator Type *() const { + return get(); + } + + /** + * Allow |*this| to be treated as a |Type*| for convenience. Use with + * caution since this method will crash if the referenced object is null. + */ + Type *operator->() const { + NS_ASSERTION(mRef && mRef->mObj, + "You can't dereference a null weak reference with operator->()."); + return get(); + } + +private: + + struct Inner { + int mCnt; + Type *mObj; + + Inner(Type *obj) : mCnt(1), mObj(obj) {} + void AddRef() { ++mCnt; } + void Release() { if (--mCnt == 0) delete this; } + }; + + Inner *mRef; +}; + +#endif // nsTWeakRef_h__ diff --git a/mozilla/xpcom/io/nsIAsyncInputStream.idl b/mozilla/xpcom/io/nsIAsyncInputStream.idl index bb9a46c3cdd..99053fd116e 100644 --- a/mozilla/xpcom/io/nsIAsyncInputStream.idl +++ b/mozilla/xpcom/io/nsIAsyncInputStream.idl @@ -52,7 +52,7 @@ interface nsIEventTarget; * necessary that a non-blocking nsIInputStream implementation also implement * nsIAsyncInputStream. */ -[scriptable, uuid(15a15329-00de-44e8-ab06-0d0b0d43dc5b)] +[scriptable, uuid(a5f255ab-4801-4161-8816-277ac92f6ad1)] interface nsIAsyncInputStream : nsIInputStream { /** diff --git a/mozilla/xpcom/io/nsIAsyncOutputStream.idl b/mozilla/xpcom/io/nsIAsyncOutputStream.idl index f8fbded2f62..c9ea330567f 100644 --- a/mozilla/xpcom/io/nsIAsyncOutputStream.idl +++ b/mozilla/xpcom/io/nsIAsyncOutputStream.idl @@ -52,7 +52,7 @@ interface nsIEventTarget; * necessary that a non-blocking nsIOutputStream implementation also implement * nsIAsyncOutputStream. */ -[scriptable, uuid(10dc9c94-8aff-49c6-8af9-d7fdb7339dae)] +[scriptable, uuid(beb632d3-d77a-4e90-9134-f9ece69e8200)] interface nsIAsyncOutputStream : nsIOutputStream { /** diff --git a/mozilla/xpcom/io/nsStreamUtils.cpp b/mozilla/xpcom/io/nsStreamUtils.cpp index fb7fbce7153..b59f416c917 100644 --- a/mozilla/xpcom/io/nsStreamUtils.cpp +++ b/mozilla/xpcom/io/nsStreamUtils.cpp @@ -40,12 +40,13 @@ #include "nsCOMPtr.h" #include "nsIPipe.h" #include "nsIEventTarget.h" +#include "nsIRunnable.h" #include "nsAutoLock.h" #include "nsString.h" //----------------------------------------------------------------------------- -class nsInputStreamReadyEvent : public PLEvent +class nsInputStreamReadyEvent : public nsIRunnable , public nsIInputStreamCallback { public: @@ -61,28 +62,28 @@ public: private: ~nsInputStreamReadyEvent() { - if (mCallback) { - nsresult rv; - // - // whoa!! looks like we never posted this event. take care to - // release mCallback on the correct thread. if mTarget lives on the - // calling thread, then we are ok. otherwise, we have to try to - // proxy the Release over the right thread. if that thread is dead, - // then there's nothing we can do... better to leak than crash. - // - PRBool val; - rv = mTarget->IsOnCurrentThread(&val); - if (NS_FAILED(rv) || !val) { - nsCOMPtr event; - NS_NewInputStreamReadyEvent(getter_AddRefs(event), mCallback, mTarget); - mCallback = 0; - if (event) { - rv = event->OnInputStreamReady(nsnull); - if (NS_FAILED(rv)) { - NS_NOTREACHED("leaking stream event"); - nsISupports *sup = event; - NS_ADDREF(sup); - } + if (!mCallback) + return; + // + // whoa!! looks like we never posted this event. take care to + // release mCallback on the correct thread. if mTarget lives on the + // calling thread, then we are ok. otherwise, we have to try to + // proxy the Release over the right thread. if that thread is dead, + // then there's nothing we can do... better to leak than crash. + // + PRBool val; + nsresult rv = mTarget->IsOnCurrentThread(&val); + if (NS_FAILED(rv) || !val) { + nsCOMPtr event; + NS_NewInputStreamReadyEvent(getter_AddRefs(event), mCallback, + mTarget); + mCallback = 0; + if (event) { + rv = event->OnInputStreamReady(nsnull); + if (NS_FAILED(rv)) { + NS_NOTREACHED("leaking stream event"); + nsISupports *sup = event; + NS_ADDREF(sup); } } } @@ -93,48 +94,37 @@ public: { mStream = stream; - // will be released when event is handled - NS_ADDREF_THIS(); - - PL_InitEvent(this, nsnull, EventHandler, EventCleanup); - - if (NS_FAILED(mTarget->PostEvent(this))) { - NS_WARNING("PostEvent failed"); - NS_RELEASE_THIS(); + nsresult rv = + mTarget->Dispatch(this, NS_DISPATCH_NORMAL); + if (NS_FAILED(rv)) { + NS_WARNING("Dispatch failed"); return NS_ERROR_FAILURE; } return NS_OK; } + NS_IMETHOD Run() + { + if (mCallback) { + mCallback->OnInputStreamReady(mStream); + mCallback = nsnull; + } + return NS_OK; + } + private: nsCOMPtr mStream; nsCOMPtr mCallback; nsCOMPtr mTarget; - - PR_STATIC_CALLBACK(void *) EventHandler(PLEvent *plevent) - { - nsInputStreamReadyEvent *ev = (nsInputStreamReadyEvent *) plevent; - // bypass event delivery if this is a cleanup event... - if (ev->mCallback) - ev->mCallback->OnInputStreamReady(ev->mStream); - ev->mCallback = 0; - return NULL; - } - - PR_STATIC_CALLBACK(void) EventCleanup(PLEvent *plevent) - { - nsInputStreamReadyEvent *ev = (nsInputStreamReadyEvent *) plevent; - NS_RELEASE(ev); - } }; -NS_IMPL_THREADSAFE_ISUPPORTS1(nsInputStreamReadyEvent, +NS_IMPL_THREADSAFE_ISUPPORTS2(nsInputStreamReadyEvent, nsIRunnable, nsIInputStreamCallback) //----------------------------------------------------------------------------- -class nsOutputStreamReadyEvent : public PLEvent +class nsOutputStreamReadyEvent : public nsIRunnable , public nsIOutputStreamCallback { public: @@ -150,82 +140,64 @@ public: private: ~nsOutputStreamReadyEvent() { - if (mCallback) { - nsresult rv; - // - // whoa!! looks like we never posted this event. take care to - // release mCallback on the correct thread. if mTarget lives on the - // calling thread, then we are ok. otherwise, we have to try to - // proxy the Release over the right thread. if that thread is dead, - // then there's nothing we can do... better to leak than crash. - // - PRBool val; - rv = mTarget->IsOnCurrentThread(&val); - if (NS_FAILED(rv) || !val) { - nsCOMPtr event; - NS_NewOutputStreamReadyEvent(getter_AddRefs(event), mCallback, mTarget); - mCallback = 0; - if (event) { - rv = event->OnOutputStreamReady(nsnull); - if (NS_FAILED(rv)) { - NS_NOTREACHED("leaking stream event"); - nsISupports *sup = event; - NS_ADDREF(sup); - } + if (!mCallback) + return; + // + // whoa!! looks like we never posted this event. take care to + // release mCallback on the correct thread. if mTarget lives on the + // calling thread, then we are ok. otherwise, we have to try to + // proxy the Release over the right thread. if that thread is dead, + // then there's nothing we can do... better to leak than crash. + // + PRBool val; + nsresult rv = mTarget->IsOnCurrentThread(&val); + if (NS_FAILED(rv) || !val) { + nsCOMPtr event; + NS_NewOutputStreamReadyEvent(getter_AddRefs(event), mCallback, + mTarget); + mCallback = 0; + if (event) { + rv = event->OnOutputStreamReady(nsnull); + if (NS_FAILED(rv)) { + NS_NOTREACHED("leaking stream event"); + nsISupports *sup = event; + NS_ADDREF(sup); } } } } public: - void Init(nsIOutputStreamCallback *callback, nsIEventTarget *target) - { - mCallback = callback; - mTarget = target; - - PL_InitEvent(this, nsnull, EventHandler, EventCleanup); - } - NS_IMETHOD OnOutputStreamReady(nsIAsyncOutputStream *stream) { mStream = stream; - // this will be released when the event is handled - NS_ADDREF_THIS(); - - PL_InitEvent(this, nsnull, EventHandler, EventCleanup); - - if (NS_FAILED(mTarget->PostEvent(this))) { + nsresult rv = + mTarget->Dispatch(this, NS_DISPATCH_NORMAL); + if (NS_FAILED(rv)) { NS_WARNING("PostEvent failed"); - NS_RELEASE_THIS(); return NS_ERROR_FAILURE; } return NS_OK; } + NS_IMETHOD Run() + { + if (mCallback) { + mCallback->OnOutputStreamReady(mStream); + mCallback = nsnull; + } + return NS_OK; + } + private: nsCOMPtr mStream; nsCOMPtr mCallback; nsCOMPtr mTarget; - - PR_STATIC_CALLBACK(void *) EventHandler(PLEvent *plevent) - { - nsOutputStreamReadyEvent *ev = (nsOutputStreamReadyEvent *) plevent; - if (ev->mCallback) - ev->mCallback->OnOutputStreamReady(ev->mStream); - ev->mCallback = 0; - return NULL; - } - - PR_STATIC_CALLBACK(void) EventCleanup(PLEvent *ev) - { - nsOutputStreamReadyEvent *event = (nsOutputStreamReadyEvent *) ev; - NS_RELEASE(event); - } }; -NS_IMPL_THREADSAFE_ISUPPORTS1(nsOutputStreamReadyEvent, +NS_IMPL_THREADSAFE_ISUPPORTS2(nsOutputStreamReadyEvent, nsIRunnable, nsIOutputStreamCallback) //----------------------------------------------------------------------------- @@ -260,6 +232,7 @@ NS_NewOutputStreamReadyEvent(nsIOutputStreamCallback **event, // abstract stream copier... class nsAStreamCopier : public nsIInputStreamCallback , public nsIOutputStreamCallback + , public nsIRunnable { public: NS_DECL_ISUPPORTS @@ -386,26 +359,20 @@ public: return NS_OK; } - PR_STATIC_CALLBACK(void*) HandleContinuationEvent(PLEvent *event) + // continuation event handler + NS_IMETHOD Run() { - nsAStreamCopier *self = (nsAStreamCopier *) event->owner; - self->Process(); + Process(); // clear "in process" flag and post any pending continuation event - nsAutoLock lock(self->mLock); - self->mEventInProcess = PR_FALSE; - if (self->mEventIsPending) { - self->mEventIsPending = PR_FALSE; - self->PostContinuationEvent_Locked(); + nsAutoLock lock(mLock); + mEventInProcess = PR_FALSE; + if (mEventIsPending) { + mEventIsPending = PR_FALSE; + PostContinuationEvent_Locked(); } - return nsnull; - } - PR_STATIC_CALLBACK(void) DestroyContinuationEvent(PLEvent *event) - { - nsAStreamCopier *self = (nsAStreamCopier *) event->owner; - NS_RELEASE(self); - delete event; + return NS_OK; } nsresult PostContinuationEvent() @@ -427,23 +394,11 @@ public: if (mEventInProcess) mEventIsPending = PR_TRUE; else { - PLEvent *event = new PLEvent; - if (!event) - rv = NS_ERROR_OUT_OF_MEMORY; - else { - NS_ADDREF_THIS(); - PL_InitEvent(event, this, - HandleContinuationEvent, - DestroyContinuationEvent); - - rv = mTarget->PostEvent(event); - if (NS_SUCCEEDED(rv)) - mEventInProcess = PR_TRUE; - else { - NS_ERROR("unable to post continuation event"); - PL_DestroyEvent(event); - } - } + rv = mTarget->Dispatch(this, NS_DISPATCH_NORMAL); + if (NS_SUCCEEDED(rv)) + mEventInProcess = PR_TRUE; + else + NS_WARNING("unable to post continuation event"); } return rv; } @@ -462,9 +417,10 @@ protected: PRPackedBool mEventIsPending; }; -NS_IMPL_THREADSAFE_ISUPPORTS2(nsAStreamCopier, +NS_IMPL_THREADSAFE_ISUPPORTS3(nsAStreamCopier, nsIInputStreamCallback, - nsIOutputStreamCallback) + nsIOutputStreamCallback, + nsIRunnable) class nsStreamCopierIB : public nsAStreamCopier { diff --git a/mozilla/xpcom/io/nsStreamUtils.h b/mozilla/xpcom/io/nsStreamUtils.h index 9040403ace8..e449642c494 100644 --- a/mozilla/xpcom/io/nsStreamUtils.h +++ b/mozilla/xpcom/io/nsStreamUtils.h @@ -54,12 +54,12 @@ class nsIEventTarget; * the proxy object is destroyed on. * * This function is designed to be used to implement AsyncWait when the - * aEventTarget parameter is non-null. + * aTarget parameter is non-null. */ extern NS_COM nsresult NS_NewInputStreamReadyEvent(nsIInputStreamCallback **aEvent, nsIInputStreamCallback *aNotify, - nsIEventTarget *aEventTarget); + nsIEventTarget *aTarget); /** * A "one-shot" proxy of the OnOutputStreamReady callback. The resulting @@ -69,12 +69,12 @@ NS_NewInputStreamReadyEvent(nsIInputStreamCallback **aEvent, * the proxy object is destroyed on. * * This function is designed to be used to implement AsyncWait when the - * aEventTarget parameter is non-null. + * aTarget parameter is non-null. */ extern NS_COM nsresult NS_NewOutputStreamReadyEvent(nsIOutputStreamCallback **aEvent, nsIOutputStreamCallback *aNotify, - nsIEventTarget *aEventTarget); + nsIEventTarget *aTarget); /* ------------------------------------------------------------------------- */ @@ -102,7 +102,7 @@ typedef void (* nsAsyncCopyCallbackFun)(void *closure, nsresult status); extern NS_COM nsresult NS_AsyncCopy(nsIInputStream *aSource, nsIOutputStream *aSink, - nsIEventTarget *aEventTarget, + nsIEventTarget *aTarget, nsAsyncCopyMode aMode = NS_ASYNCCOPY_VIA_READSEGMENTS, PRUint32 aChunkSize = 4096, nsAsyncCopyCallbackFun aCallbackFun = nsnull, diff --git a/mozilla/xpcom/proxy/public/Makefile.in b/mozilla/xpcom/proxy/public/Makefile.in index d6950b9a751..77c62a8f7ad 100644 --- a/mozilla/xpcom/proxy/public/Makefile.in +++ b/mozilla/xpcom/proxy/public/Makefile.in @@ -50,14 +50,13 @@ XPIDL_MODULE = proxyObjInst endif EXPORTS = \ - nsProxyEvent.h \ nsProxyRelease.h \ nsProxiedService.h \ $(NULL) -XPIDLSRCS = nsIProxyCreateInstance.idl \ - nsIProxyObjectManager.idl \ - $(NULL) +XPIDLSRCS = \ + nsIProxyObjectManager.idl \ + $(NULL) include $(topsrcdir)/config/rules.mk diff --git a/mozilla/xpcom/proxy/public/nsIProxyObjectManager.idl b/mozilla/xpcom/proxy/public/nsIProxyObjectManager.idl index b8de77e198d..1aa16aea677 100644 --- a/mozilla/xpcom/proxy/public/nsIProxyObjectManager.idl +++ b/mozilla/xpcom/proxy/public/nsIProxyObjectManager.idl @@ -36,23 +36,27 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ + #include "nsISupports.idl" -interface nsIEventQueue; + +interface nsIEventTarget; /** * See http://www.mozilla.org/projects/xpcom/Proxies.html */ -[scriptable, uuid(eea90d43-b059-11d2-915e-c12b696c9333)] +[scriptable, uuid(ee8ce1e3-0319-4bd9-8f70-7258b21c7733)] interface nsIProxyObjectManager : nsISupports { /** * Constants for proxyType */ + /** * Synchronous: Block until result available, like function call. */ const long INVOKE_SYNC = 0x0001; + /** * Asynchronous: Return without waiting for result. * (Warning: do not pass &pointers into stack when using this flag.) @@ -64,26 +68,18 @@ interface nsIProxyObjectManager : nsISupports */ const long FORCE_PROXY_CREATION = 0x0004; - - void getProxyForObject(in nsIEventQueue destQueue, + /** + * If target is null, then the current thread is used as the target. + */ + void getProxyForObject(in nsIEventTarget target, in nsIIDRef iid, in nsISupports object, in PRInt32 proxyType, [iid_is(iid),retval] out nsQIResult result); - - void getProxy(in nsIEventQueue destQueue, - in nsIIDRef cid, - in nsISupports aOuter, - in nsIIDRef iid, - in PRInt32 proxyType, - [iid_is(iid),retval] out nsQIResult result); - }; %{C++ -#include "nsProxyEvent.h" - #define NS_XPCOMPROXY_CONTRACTID "@mozilla.org/xpcomproxy;1" #define NS_XPCOMPROXY_CLASSNAME "XPCom Proxy" @@ -92,8 +88,26 @@ interface nsIProxyObjectManager : nsISupports 0xb059, \ 0x11d2, \ {0x91, 0x5e, 0xc1, 0x2b, 0x69, 0x6c, 0x93, 0x33}\ -} +} +// convenience macros +#define NS_PROXY_SYNC nsIProxyObjectManager::INVOKE_SYNC +#define NS_PROXY_ASYNC nsIProxyObjectManager::INVOKE_ASYNC +#define NS_PROXY_ALWAYS nsIProxyObjectManager::FORCE_PROXY_CREATION + +/** + * Pass this value as the target to NS_GetProxyForObject to specify the current + * thread as the target for the proxy object. + */ +#define NS_PROXY_TO_CURRENT_THREAD ((nsIEventTarget *) 0) + +/** + * Pass this value as the target to NS_GetProxyForObject to specify the main + * thread as the target for the proxy object. + */ +#define NS_PROXY_TO_MAIN_THREAD ((nsIEventTarget *) 1) + +#ifdef MOZILLA_INTERNAL_API /** * Helper function for code that already has a link-time dependency on * libxpcom and needs to get proxies in a bunch of different places. @@ -102,9 +116,10 @@ interface nsIProxyObjectManager : nsISupports * readable. */ extern NS_COM nsresult -NS_GetProxyForObject(nsIEventQueue *destQueue, +NS_GetProxyForObject(nsIEventTarget *target, REFNSIID aIID, nsISupports* aObj, PRInt32 proxyType, void** aProxyObject); +#endif %} diff --git a/mozilla/xpcom/proxy/public/nsProxiedService.h b/mozilla/xpcom/proxy/public/nsProxiedService.h index 7ab4adb8808..d3a3ca1ef46 100644 --- a/mozilla/xpcom/proxy/public/nsProxiedService.h +++ b/mozilla/xpcom/proxy/public/nsProxiedService.h @@ -36,8 +36,8 @@ * * ***** END LICENSE BLOCK ***** */ -#ifndef nsProxiedService_h_ -#define nsProxiedService_h_ +#ifndef nsProxiedService_h__ +#define nsProxiedService_h__ #include "nsIServiceManager.h" #include "nsIProxyObjectManager.h" @@ -57,10 +57,10 @@ // if(NS_FAILED(rv)) // return; // nsIMyService pIProxiedObject = NULL; -// rv = pIProxyObjectManager->GetProxyForObject(pIProxyQueue, -// NS_GET_IID(nsIMyService), -// pIMyService, PROXY_SYNC, -// (void**)&pIProxiedObject); +// rv = pIProxyObjectManager->GetProxyForObject(pIDispatchTarget, +// NS_GET_IID(nsIMyService), +// pIMyService, NS_PROXY_SYNC, +// (void**)&pIProxiedObject); // pIProxiedObject->DoIt(...); // Executed on same thread as pIProxyQueue // ... // pIProxiedObject->Release(); // Must be done as not managed for you. @@ -69,7 +69,7 @@ // { // nsresult rv; // NS_WITH_PROXIED_SERVICE(nsIMyService, pIMyService, kMyServiceCID, -// pIProxyQueue, &rv); +// pIDispatchTarget, &rv); // if(NS_FAILED(rv)) // return; // pIMyService->DoIt(...); // Executed on the same thread as pIProxyQueue @@ -96,19 +96,19 @@ class nsProxiedService { public: nsProxiedService(const nsCID &aClass, const nsIID &aIID, - nsIEventQueue* aEventQ, PRBool always, nsresult* rv) + nsIEventTarget* aTarget, PRBool always, nsresult* rv) { nsCOMPtr svc = do_GetService(aClass, rv); if (NS_SUCCEEDED(*rv)) - InitProxy(svc, aIID, aEventQ, always, rv); + InitProxy(svc, aIID, aTarget, always, rv); } nsProxiedService(const char* aContractID, const nsIID &aIID, - nsIEventQueue* aEventQ, PRBool always, nsresult* rv) + nsIEventTarget* aTarget, PRBool always, nsresult* rv) { nsCOMPtr svc = do_GetService(aContractID, rv); if (NS_SUCCEEDED(*rv)) - InitProxy(svc, aIID, aEventQ, always, rv); + InitProxy(svc, aIID, aTarget, always, rv); } operator nsISupports*() const @@ -119,13 +119,13 @@ public: private: void InitProxy(nsISupports *aObj, const nsIID &aIID, - nsIEventQueue* aEventQ, PRBool always, nsresult*rv) + nsIEventTarget* aTarget, PRBool always, nsresult*rv) { - PRInt32 proxyType = PROXY_SYNC; + PRInt32 proxyType = NS_PROXY_SYNC; if (always) - proxyType |= PROXY_ALWAYS; + proxyType |= NS_PROXY_ALWAYS; - *rv = NS_GetProxyForObject(aEventQ, + *rv = NS_GetProxyForObject(aTarget, aIID, aObj, proxyType, @@ -135,4 +135,4 @@ private: nsCOMPtr mProxiedService; }; -#endif // nsProxiedService_h_ +#endif // nsProxiedService_h__ diff --git a/mozilla/xpcom/proxy/public/nsProxyEvent.h b/mozilla/xpcom/proxy/public/nsProxyEvent.h index 1cff90ba832..e69de29bb2d 100644 --- a/mozilla/xpcom/proxy/public/nsProxyEvent.h +++ b/mozilla/xpcom/proxy/public/nsProxyEvent.h @@ -1,185 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef __nsProxyEvent_h_ -#define __nsProxyEvent_h_ - -#include "nsCOMPtr.h" -#include "nsAutoPtr.h" -#include "nscore.h" -#include "nsISupports.h" -#include "nsIFactory.h" - -#include "nsIEventQueueService.h" -#include "nsIEventQueue.h" -#include "plevent.h" -#include "prtypes.h" -#include "xptcall.h" -#include "xptinfo.h" - -class nsProxyObjectCallInfo; - -#define PROXY_SYNC 0x0001 // acts just like a function call. -#define PROXY_ASYNC 0x0002 // fire and forget. This will return immediately and you will lose all return information. -#define PROXY_ALWAYS 0x0004 // ignore check to see if the eventQ is on the same thread as the caller, and alway return a proxied object. - -//#define AUTOPROXIFICATION - -// WARNING about PROXY_ASYNC: -// -// If the calling thread goes away, any function which accesses the calling stack -// will blow up. -// -// example: -// -// myFoo->bar(&x) -// -// ... thread goes away ... -// -// bar(PRInt32 *x) -// { -// *x = 0; <----- You will blow up here. -// -// -// So what gets saved? -// -// You can safely pass base types by value. You can also pass interface pointers. -// I will make sure that the interface pointers are addrefed while they are being -// proxied. You can also pass string and wstring. These I will copy and free. -// -// I do **NOT** copy arrays or strings with size. If you are using these either -// change your interface, or contact me about this feature request. - - - - -class nsProxyObject -{ -public: - nsProxyObject(nsIEventQueue *destQueue, PRInt32 proxyType, nsISupports *realObject, - nsIEventQueueService* eventQService); - nsProxyObject(nsIEventQueue *destQueue, PRInt32 proxyType, const nsCID &aClass, - nsISupports *aDelegate, const nsIID &aIID, nsIEventQueueService* eventQService); - - void AddRef(); - void Release(); - - ~nsProxyObject(); - - nsresult Post( PRUint32 methodIndex, - nsXPTMethodInfo * info, - nsXPTCMiniVariant * params, - nsIInterfaceInfo * interfaceInfo); - - nsresult PostAndWait(nsProxyObjectCallInfo *proxyInfo); - nsISupports* GetRealObject() const { return mRealObject; } - nsIEventQueue* GetQueue() const { return mDestQueue; } - PRInt32 GetProxyType() const { return mProxyType; } - - friend class nsProxyEventObject; -private: - - nsAutoRefCnt mRefCnt; - - PRInt32 mProxyType; - - nsCOMPtr mDestQueue; /* destination queue */ - - nsCOMPtr mRealObject; /* the non-proxy object that this event is referring to. - This is a strong ref. */ - nsCOMPtr mEventQService; - - nsresult convertMiniVariantToVariant(nsXPTMethodInfo * methodInfo, - nsXPTCMiniVariant * params, - nsXPTCVariant **fullParam, - uint8 *paramCount); - -}; - - -class nsProxyObjectCallInfo -{ -public: - - nsProxyObjectCallInfo(nsProxyObject* owner, - nsXPTMethodInfo *methodInfo, - PRUint32 methodIndex, - nsXPTCVariant* parameterList, - PRUint32 parameterCount, - PLEvent *event); - - ~nsProxyObjectCallInfo(); - - PRUint32 GetMethodIndex() const { return mMethodIndex; } - nsXPTCVariant* GetParameterList() const { return mParameterList; } - PRUint32 GetParameterCount() const { return mParameterCount; } - PLEvent* GetPLEvent() const { return mEvent; } - nsresult GetResult() const { return mResult; } - nsProxyObject* GetProxyObject() const { return mOwner; } - - PRBool GetCompleted(); - void SetCompleted(); - void PostCompleted(); - - void SetResult(nsresult rv) {mResult = rv; } - - nsIEventQueue* GetCallersQueue(); - void SetCallersQueue(nsIEventQueue* queue); - -private: - - nsresult mResult; /* this is the return result of the called function */ - nsXPTMethodInfo *mMethodInfo; - PRUint32 mMethodIndex; /* which method to be called? */ - nsXPTCVariant *mParameterList; /* marshalled in parameter buffer */ - PRUint32 mParameterCount; /* number of params */ - PLEvent *mEvent; /* the current plevent */ - PRInt32 mCompleted; /* is true when the method has been called. */ - - nsCOMPtr mCallersEventQ; /* this is the eventQ that we must post a message back to - when we are done invoking the method (only PROXY_SYNC). - */ - - nsRefPtr mOwner; /* this is the strong referenced nsProxyObject */ - - void RefCountInInterfacePointers(PRBool addRef); - void CopyStrings(PRBool copy); - -}; - - -#endif diff --git a/mozilla/xpcom/proxy/public/nsProxyRelease.h b/mozilla/xpcom/proxy/public/nsProxyRelease.h index 9792736b380..5253f7e30fb 100644 --- a/mozilla/xpcom/proxy/public/nsProxyRelease.h +++ b/mozilla/xpcom/proxy/public/nsProxyRelease.h @@ -38,7 +38,7 @@ #ifndef nsProxyRelease_h_ #define nsProxyRelease_h__ -#include "nsIEventQueueService.h" +#include "nsIEventTarget.h" #include "pratom.h" #include "prmem.h" @@ -58,55 +58,4 @@ NS_COM nsresult NS_ProxyRelease (nsIEventTarget *target, nsISupports *doomed, PRBool alwaysProxy=PR_FALSE); - -#define NS_IMPL_PROXY_RELEASE(_class) \ -NS_IMETHODIMP_(nsrefcnt) _class::Release(void) \ -{ \ - NS_PRECONDITION(0 != mRefCnt, "dup release"); \ - nsrefcnt count = PR_AtomicDecrement((PRInt32 *)&mRefCnt); \ - NS_LOG_RELEASE(this, count, #_class); \ - \ - if (count == 0) \ - { \ - mRefCnt = 1; /* stabilize */ \ - PRBool callDirectly = PR_TRUE; \ - static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); \ - nsCOMPtr eventQService \ - = do_GetService(kEventQueueServiceCID); \ - NS_ASSERTION(eventQService, "event queue service is unavailable"); \ - \ - nsCOMPtr eventQ; \ - if (eventQService) { \ - eventQService->GetThreadEventQueue(NS_UI_THREAD, getter_AddRefs(eventQ)); \ - if (eventQ) \ - eventQ->IsOnCurrentThread(&callDirectly); \ - } \ - \ - if (callDirectly) \ - { \ - NS_RELEASE(this); \ - return 0; \ - } \ - PLEvent *event = new PLEvent; \ - if (event == nsnull) \ - { \ - NS_ASSERTION(0, "Could not create a plevent. Deleting on wrong thread!"); \ - NS_DELETEXPCOM(this); \ - return 0; \ - } \ - \ - PL_InitEvent(event, \ - NS_STATIC_CAST(nsISupports*, this), \ - ReleaseDestructorEventHandler, \ - ReleaseDestructorDestroyHandler); \ - \ - eventQ->PostEvent(event); \ - return 0; \ - } \ - return count; \ -} \ - - - - #endif diff --git a/mozilla/xpcom/proxy/src/Makefile.in b/mozilla/xpcom/proxy/src/Makefile.in index ba36ed6bb0a..93ab33ac2a7 100644 --- a/mozilla/xpcom/proxy/src/Makefile.in +++ b/mozilla/xpcom/proxy/src/Makefile.in @@ -58,6 +58,7 @@ CPPSRCS = \ $(NULL) DEFINES += -D_IMPL_NS_COM -DEXPORT_XPTC_API +LOCAL_INCLUDES += -I$(top_srcdir)/xpcom/threads/ # No shared lib; Force creation of static lib FORCE_STATIC_LIB = 1 diff --git a/mozilla/xpcom/proxy/src/nsProxyEvent.cpp b/mozilla/xpcom/proxy/src/nsProxyEvent.cpp index cf93367abdb..aa98c7e6c94 100644 --- a/mozilla/xpcom/proxy/src/nsProxyEvent.cpp +++ b/mozilla/xpcom/proxy/src/nsProxyEvent.cpp @@ -1,4 +1,6 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* vim:set ts=4 sw=4 sts=4 ci et: */ +/* * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 @@ -57,12 +59,19 @@ #include "prmem.h" #include "xptcall.h" +#include "nsXPCOMCID.h" +#include "nsServiceManagerUtils.h" #include "nsIComponentManager.h" +#include "nsIThreadInternal.h" +#include "nsThreadUtils.h" +#include "nsEventQueue.h" #include "nsMemory.h" -#include "nsIEventQueueService.h" -#include "nsIThread.h" -#include "nsIAtom.h" //hack! Need a way to define a component as threadsafe (ie. sta). +#include "prlog.h" +#ifdef PR_LOGGING +static PRLogModuleInfo *sLog = PR_NewLogModule("xpcomproxy"); +#endif +#define LOG(args) PR_LOG(sLog, PR_LOG_DEBUG, args) /** * Map the nsAUTF8String, nsUTF8String classes to the nsACString and @@ -72,19 +81,169 @@ #define nsAUTF8String nsACString #define nsUTF8String nsCString -static void* PR_CALLBACK EventHandler(PLEvent *self); -static void PR_CALLBACK DestroyHandler(PLEvent *self); -static void* PR_CALLBACK CompletedEventHandler(PLEvent *self); -static void PR_CALLBACK CompletedDestroyHandler(PLEvent *self) ; -static void* PR_CALLBACK ProxyDestructorEventHandler(PLEvent *self); -static void PR_CALLBACK ProxyDestructorDestroyHandler(PLEvent *self) ; +//----------------------------------------------------------------------------- -nsProxyObjectCallInfo::nsProxyObjectCallInfo( nsProxyObject* owner, - nsXPTMethodInfo *methodInfo, - PRUint32 methodIndex, - nsXPTCVariant* parameterList, - PRUint32 parameterCount, - PLEvent *event) +#define NS_PROXYEVENT_IID \ +{ /* 9a24dc5e-2b42-4a5a-aeca-37b8c8fd8ccd */ \ + 0x9a24dc5e, \ + 0x2b42, \ + 0x4a5a, \ + {0xae, 0xca, 0x37, 0xb8, 0xc8, 0xfd, 0x8c, 0xcd} \ +} + +class nsProxyEvent : public nsIRunnable +{ +public: + NS_DECLARE_STATIC_IID_ACCESSOR(NS_PROXYEVENT_IID) + NS_DECL_ISUPPORTS + + nsProxyEvent(nsProxyObjectCallInfo *info = nsnull) + : mInfo(info) + , mHasRun(PR_FALSE) + {} + + void SetInfo(nsProxyObjectCallInfo *info) + { + mInfo = info; + } + + PRBool IsSyncProxyEvent() + { + return mInfo->GetProxyObject()->GetProxyType() & NS_PROXY_SYNC; + } + + PRBool HasRun() + { + return mHasRun; + } + +protected: + NS_IMETHOD Run() + { + mHasRun = PR_TRUE; + return NS_OK; + } + + nsProxyObjectCallInfo *mInfo; + PRPackedBool mHasRun; +}; +NS_DEFINE_STATIC_IID_ACCESSOR(nsProxyEvent, NS_PROXYEVENT_IID) +NS_IMPL_THREADSAFE_ISUPPORTS2(nsProxyEvent, nsProxyEvent, nsIRunnable) + +//----------------------------------------------------------------------------- + +class nsProxyThreadFilter : public nsIThreadEventFilter +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSITHREADEVENTFILTER +}; + +NS_IMPL_THREADSAFE_ISUPPORTS1(nsProxyThreadFilter, nsIThreadEventFilter) + +NS_IMETHODIMP_(PRBool) +nsProxyThreadFilter::AcceptEvent(nsIRunnable *event) +{ + LOG(("PROXY(%p): filter event [%p]\n", this, event)); + + // If we encounter one of our proxy events that is for a synchronous method + // call, then we want to put it in our event queue for processing. Else, + // we want to allow the event to be dispatched to the thread's event queue + // for processing later once we complete the current sync method call. + + nsCOMPtr pe = do_QueryInterface(event); + return pe && pe->IsSyncProxyEvent(); +} + +//----------------------------------------------------------------------------- + +class nsProxyCallEvent : public nsProxyEvent +{ +public: + nsProxyCallEvent() + : nsProxyEvent() + {} + + NS_IMETHOD Run() + { + nsProxyEvent::Run(); + + Invoke(); + if (IsSyncProxyEvent()) { + mInfo->PostCompleted(); + } else { + delete mInfo; + mInfo = nsnull; + } + return NS_OK; + } + + void Invoke() + { + LOG(("PROXY(%p): Invoke\n", this)); + + nsProxyObject *proxyObject = mInfo->GetProxyObject(); + if (proxyObject) + { + // invoke the magic of xptc... + nsresult rv = XPTC_InvokeByIndex(proxyObject->GetRealObject(), + mInfo->GetMethodIndex(), + mInfo->GetParameterCount(), + mInfo->GetParameterList()); + mInfo->SetResult(rv); + } + else + { + mInfo->SetResult(NS_ERROR_OUT_OF_MEMORY); + } + } +}; + +//----------------------------------------------------------------------------- + +class nsProxyCallCompletedEvent : public nsProxyEvent +{ +public: + nsProxyCallCompletedEvent(nsProxyObjectCallInfo *info) + : nsProxyEvent(info) + {} + + NS_IMETHOD Run() + { + nsProxyEvent::Run(); + + mInfo->SetCompleted(); + return NS_OK; + } +}; + +//----------------------------------------------------------------------------- + +class nsProxyDestructorEvent : public nsRunnable +{ +public: + nsProxyDestructorEvent(nsProxyObject *doomed) + : mDoomed(doomed) + {} + + NS_IMETHOD Run() + { + delete mDoomed; + return NS_OK; + } + +private: + nsProxyObject *mDoomed; +}; + +//----------------------------------------------------------------------------- + +nsProxyObjectCallInfo::nsProxyObjectCallInfo(nsProxyObject* owner, + nsXPTMethodInfo *methodInfo, + PRUint32 methodIndex, + nsXPTCVariant* parameterList, + PRUint32 parameterCount, + nsIRunnable *event) { NS_ASSERTION(owner, "No nsProxyObject!"); NS_ASSERTION(methodInfo, "No nsXPTMethodInfo!"); @@ -94,14 +253,14 @@ nsProxyObjectCallInfo::nsProxyObjectCallInfo( nsProxyObject* owner, mMethodIndex = methodIndex; mParameterList = parameterList; mParameterCount = parameterCount; - mEvent = event; + mEvent = event; // XXX strong or weak ref? mMethodInfo = methodInfo; - mCallersEventQ = nsnull; + mCallersTarget = nsnull; mOwner = owner; RefCountInInterfacePointers(PR_TRUE); - if (mOwner->GetProxyType() & PROXY_ASYNC) + if (mOwner->GetProxyType() & NS_PROXY_ASYNC) CopyStrings(PR_TRUE); } @@ -109,15 +268,13 @@ nsProxyObjectCallInfo::nsProxyObjectCallInfo( nsProxyObject* owner, nsProxyObjectCallInfo::~nsProxyObjectCallInfo() { RefCountInInterfacePointers(PR_FALSE); - if (mOwner->GetProxyType() & PROXY_ASYNC) + if (mOwner->GetProxyType() & NS_PROXY_ASYNC) CopyStrings(PR_FALSE); mOwner = nsnull; - PR_FREEIF(mEvent); - if (mParameterList) - free( (void*) mParameterList); + free((void*) mParameterList); } void @@ -137,7 +294,7 @@ nsProxyObjectCallInfo::RefCountInInterfacePointers(PRBool addRef) if (anInterface) { - if(addRef) + if (addRef) anInterface->AddRef(); else anInterface->Release(); @@ -155,7 +312,7 @@ nsProxyObjectCallInfo::CopyStrings(PRBool copy) { const nsXPTParamInfo paramInfo = mMethodInfo->GetParam(i); - if(paramInfo.IsIn()) + if (paramInfo.IsIn()) { const nsXPTType& type = paramInfo.GetType(); uint8 type_tag = type.TagPart(); @@ -230,67 +387,48 @@ nsProxyObjectCallInfo::GetCompleted() void nsProxyObjectCallInfo::SetCompleted() { + LOG(("PROXY(%p): SetCompleted\n", this)); PR_AtomicSet(&mCompleted, 1); } void nsProxyObjectCallInfo::PostCompleted() { - if (mCallersEventQ) + LOG(("PROXY(%p): PostCompleted\n", this)); + + if (mCallersTarget) { - PLEvent *event = PR_NEW(PLEvent); - - PL_InitEvent(event, - this, - CompletedEventHandler, - CompletedDestroyHandler); - - mCallersEventQ->PostSynchronousEvent(event, nsnull); - PR_FREEIF(event); + nsCOMPtr event = + new nsProxyCallCompletedEvent(this); + // XXX check for out-of-memory! + // XXX dispatch sync will spin the current thread's event queue, which + // may not be what we want! + mCallersTarget->Dispatch(event, NS_DISPATCH_NORMAL); } else { - // caller does not have an eventQ? This is an error! + // caller does not have a target? This is an error! SetCompleted(); } } -nsIEventQueue* -nsProxyObjectCallInfo::GetCallersQueue() +nsIEventTarget* +nsProxyObjectCallInfo::GetCallersTarget() { - return mCallersEventQ; -} -void -nsProxyObjectCallInfo::SetCallersQueue(nsIEventQueue* queue) -{ - mCallersEventQ = queue; -} - - -nsProxyObject::nsProxyObject(nsIEventQueue *destQueue, PRInt32 proxyType, nsISupports *realObject, - nsIEventQueueService* eventQService) -{ - mEventQService = eventQService; - - mRealObject = realObject; - mDestQueue = do_QueryInterface(destQueue); - mProxyType = proxyType; + return mCallersTarget; } - -nsProxyObject::nsProxyObject(nsIEventQueue *destQueue, PRInt32 proxyType, const nsCID &aClass, - nsISupports *aDelegate, const nsIID &aIID, nsIEventQueueService* eventQService) +void +nsProxyObjectCallInfo::SetCallersTarget(nsIEventTarget* target) { - mEventQService = eventQService; + mCallersTarget = target; +} - nsCOMPtr compMgr; - NS_GetComponentManager(getter_AddRefs(compMgr)); - compMgr->CreateInstance(aClass, - aDelegate, - aIID, - getter_AddRefs(mRealObject)); - - mDestQueue = do_QueryInterface(destQueue); +nsProxyObject::nsProxyObject(nsIEventTarget *target, PRInt32 proxyType, + nsISupports *realObject) +{ + mRealObject = realObject; + mTarget = target; mProxyType = proxyType; } @@ -300,10 +438,9 @@ nsProxyObject::~nsProxyObject() // do not remove assignments. mRealObject = 0; - mDestQueue = 0; + mTarget = 0; } - void nsProxyObject::AddRef() { @@ -314,92 +451,76 @@ nsProxyObject::AddRef() void nsProxyObject::Release(void) { - NS_PRECONDITION(0 != mRefCnt, "dup release"); + NS_PRECONDITION(0 != mRefCnt, "dup release"); - nsrefcnt count = PR_AtomicDecrement((PRInt32 *)&mRefCnt); - NS_LOG_RELEASE(this, count, "nsProxyObject"); + nsrefcnt count = PR_AtomicDecrement((PRInt32 *)&mRefCnt); + NS_LOG_RELEASE(this, count, "nsProxyObject"); - if (count == 0) - { - mRefCnt = 1; /* stabilize */ + if (count == 0) + { + mRefCnt = 1; /* stabilize */ - PRBool callDirectly; - mDestQueue->IsOnCurrentThread(&callDirectly); + PRBool callDirectly; + mTarget->IsOnCurrentThread(&callDirectly); - if (callDirectly) - { - delete this; - return; - } + if (callDirectly) + { + delete this; + return; + } - // need to do something special here so that - // the real object will always be deleted on - // the correct thread.. + // need to do something special here so that + // the real object will always be deleted on + // the correct thread.. - PLEvent *event = PR_NEW(PLEvent); - if (event == nsnull) - { - NS_ASSERTION(0, "Could not create a plevent. Leaking nsProxyObject!"); - return; // if this happens we are going to leak. - } - - PL_InitEvent(event, - this, - ProxyDestructorEventHandler, - ProxyDestructorDestroyHandler); + nsCOMPtr event = new nsProxyDestructorEvent(this); + if (event == nsnull) + { + NS_NOTREACHED("Leaking nsProxyObject!"); + return; // if this happens we are going to leak. + } - mDestQueue->PostEvent(event); - } -} + mTarget->Dispatch(event, NS_DISPATCH_NORMAL); + } +} nsresult nsProxyObject::PostAndWait(nsProxyObjectCallInfo *proxyInfo) { - if (proxyInfo == nsnull || mEventQService == nsnull) - return NS_ERROR_NULL_POINTER; - - PRBool eventLoopCreated = PR_FALSE; - nsresult rv; + LOG(("PROXY(%p): PostAndWait enter [%p]\n", this, proxyInfo)); - nsCOMPtr eventQ; - rv = mEventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(eventQ)); - if (NS_FAILED(rv)) - { - rv = mEventQService->CreateMonitoredThreadEventQueue(); - eventLoopCreated = PR_TRUE; - if (NS_FAILED(rv)) - return rv; - - rv = mEventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(eventQ)); - } + NS_ENSURE_ARG_POINTER(proxyInfo); - if (NS_FAILED(rv)) - return rv; - - proxyInfo->SetCallersQueue(eventQ); - - PLEvent* event = proxyInfo->GetPLEvent(); + nsIRunnable* event = proxyInfo->GetEvent(); if (!event) return NS_ERROR_NULL_POINTER; + + nsCOMPtr thread = do_GetCurrentThread(); + nsCOMPtr threadInt = do_QueryInterface(thread); + NS_ENSURE_STATE(threadInt); + + // Install thread filter to limit event processing only to subclasses of + // nsProxyEvent. XXX Add support for sequencing? + nsRefPtr filter = new nsProxyThreadFilter(); + if (!filter) + return NS_ERROR_OUT_OF_MEMORY; + threadInt->PushEventQueue(filter); + + proxyInfo->SetCallersTarget(thread); - mDestQueue->PostEvent(event); + mTarget->Dispatch(event, NS_DISPATCH_NORMAL); - while (! proxyInfo->GetCompleted()) - { - PLEvent *nextEvent; - rv = eventQ->WaitForEvent(&nextEvent); - if (NS_FAILED(rv)) break; - - eventQ->HandleEvent(nextEvent); - } - - if (eventLoopCreated) - { - mEventQService->DestroyThreadEventQueue(); - eventQ = 0; + nsresult rv = NS_OK; + while (!proxyInfo->GetCompleted()) { + rv = thread->ProcessNextEvent(); + if (NS_FAILED(rv)) + break; } - + + threadInt->PopEventQueue(); + + LOG(("PROXY(%p): PostAndWait exit [%p %x]\n", this, proxyInfo, rv)); return rv; } @@ -424,7 +545,7 @@ nsProxyObject::convertMiniVariantToVariant(nsXPTMethodInfo *methodInfo, for (int i = 0; i < paramCount; i++) { const nsXPTParamInfo& paramInfo = methodInfo->GetParam(i); - if ((mProxyType & PROXY_ASYNC) && paramInfo.IsDipper()) + if ((mProxyType & NS_PROXY_ASYNC) && paramInfo.IsDipper()) { NS_WARNING("Async proxying of out parameters is not supported"); return NS_ERROR_PROXY_INVALID_OUT_PARAMETER; @@ -444,7 +565,7 @@ nsProxyObject::Post( PRUint32 methodIndex, { nsresult rv = NS_OK; - if (! mDestQueue || ! mRealObject) + if (! mTarget || ! mRealObject) return NS_ERROR_OUT_OF_MEMORY; if (methodInfo->IsNotXPCOM()) @@ -461,10 +582,10 @@ nsProxyObject::Post( PRUint32 methodIndex, // see if we should call into the method directly. Either it is a QI function call // (methodIndex == 0), or it is a sync proxy and this code is running on the same thread - // as the destination event queue. + // as the destination dispatch target. if ( (methodIndex == 0) || - (mProxyType & PROXY_SYNC && - NS_SUCCEEDED(mDestQueue->IsOnCurrentThread(&callDirectly)) && + (mProxyType & NS_PROXY_SYNC && + NS_SUCCEEDED(mTarget->IsOnCurrentThread(&callDirectly)) && callDirectly)) { @@ -479,34 +600,30 @@ nsProxyObject::Post( PRUint32 methodIndex, return rv; } - PLEvent *event = PR_NEW(PLEvent); - - if (event == nsnull) { + nsRefPtr event = new nsProxyCallEvent(); + if (!event) { if (fullParam) free(fullParam); return NS_ERROR_OUT_OF_MEMORY; } - - nsProxyObjectCallInfo *proxyInfo = new nsProxyObjectCallInfo(this, - methodInfo, - methodIndex, - fullParam, // will be deleted by ~() - paramCount, - event); // will be deleted by ~() - if (proxyInfo == nsnull) { - PR_DELETE(event); + nsProxyObjectCallInfo *proxyInfo = + new nsProxyObjectCallInfo(this, + methodInfo, + methodIndex, + fullParam, // will be deleted by ~() + paramCount, + event); // will be deleted by ~() + + if (!proxyInfo) { if (fullParam) free(fullParam); return NS_ERROR_OUT_OF_MEMORY; } - PL_InitEvent(event, - proxyInfo, - EventHandler, - DestroyHandler); - - if (mProxyType & PROXY_SYNC) + event->SetInfo(proxyInfo); + + if (mProxyType & NS_PROXY_SYNC) { rv = PostAndWait(proxyInfo); @@ -516,78 +633,10 @@ nsProxyObject::Post( PRUint32 methodIndex, return rv; } - if (mProxyType & PROXY_ASYNC) + if (mProxyType & NS_PROXY_ASYNC) { - mDestQueue->PostEvent(event); + mTarget->Dispatch(event, NS_DISPATCH_NORMAL); return NS_OK; } return NS_ERROR_UNEXPECTED; } - - - -static void DestroyHandler(PLEvent *self) -{ - nsProxyObjectCallInfo* owner = (nsProxyObjectCallInfo*)PL_GetEventOwner(self); - nsProxyObject* proxyObject = owner->GetProxyObject(); - - if (proxyObject == nsnull) - return; - - if (proxyObject->GetProxyType() & PROXY_ASYNC) - { - delete owner; - } - else - { - owner->PostCompleted(); - } - -} - -static void* EventHandler(PLEvent *self) -{ - nsProxyObjectCallInfo *info = (nsProxyObjectCallInfo*)PL_GetEventOwner(self); - NS_ASSERTION(info, "No nsProxyObjectCallInfo!"); - - nsProxyObject *proxyObject = info->GetProxyObject(); - - if (proxyObject) - { - // invoke the magic of xptc... - nsresult rv = XPTC_InvokeByIndex( proxyObject->GetRealObject(), - info->GetMethodIndex(), - info->GetParameterCount(), - info->GetParameterList()); - info->SetResult(rv); - } - else - { - info->SetResult(NS_ERROR_OUT_OF_MEMORY); - } - return NULL; -} - -static void CompletedDestroyHandler(PLEvent *self) -{ -} - -static void* CompletedEventHandler(PLEvent *self) -{ - nsProxyObjectCallInfo* owner = (nsProxyObjectCallInfo*)PL_GetEventOwner(self); - owner->SetCompleted(); - return nsnull; -} - -static void* ProxyDestructorEventHandler(PLEvent *self) -{ - nsProxyObject* owner = (nsProxyObject*) PL_GetEventOwner(self); - NS_DELETEXPCOM(owner); - return nsnull; -} - -static void ProxyDestructorDestroyHandler(PLEvent *self) -{ - PR_DELETE(self); -} - diff --git a/mozilla/xpcom/proxy/src/nsProxyEventClass.cpp b/mozilla/xpcom/proxy/src/nsProxyEventClass.cpp index 769a973fb7e..bf30578a9b5 100644 --- a/mozilla/xpcom/proxy/src/nsProxyEventClass.cpp +++ b/mozilla/xpcom/proxy/src/nsProxyEventClass.cpp @@ -1,4 +1,5 @@ /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* vim:set ts=4 sw=4 sts=4 ci et: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -76,12 +77,13 @@ nsProxyEventClass::GetNewOrUsedClass(REFNSIID aIID) /* find in our hash table */ nsProxyObjectManager *manager = nsProxyObjectManager::GetInstance(); - if (manager == nsnull) return nsnull; + if (manager == nsnull) + return nsnull; - // don't need to lock the map, because this is only called - // by nsProxyEventClass::GetNewOrUsed which locks it for us. + // don't need to lock the map, because this is only called by + // nsProxyEventClass::GetNewOrUsed which locks it for us. - nsHashtable *iidToClassMap = manager->GetIIDToProxyClassMap(); + nsHashtable *iidToClassMap = manager->GetIIDToProxyClassMap(); if (iidToClassMap == nsnull) { @@ -94,7 +96,7 @@ nsProxyEventClass::GetNewOrUsedClass(REFNSIID aIID) #ifdef PROXYEVENTCLASS_DEBUG char* iidStr = aIID.ToString(); printf("GetNewOrUsedClass %s\n", iidStr); - nsCRT::free(iidStr); + PR_Free(iidStr); #endif clazz = (nsProxyEventClass*) iidToClassMap->Get(&key); @@ -104,7 +106,7 @@ nsProxyEventClass::GetNewOrUsedClass(REFNSIID aIID) #ifdef PROXYEVENTCLASS_DEBUG char* iidStr = aIID.ToString(); printf("GetNewOrUsedClass %s hit\n", iidStr); - nsCRT::free(iidStr); + PR_Free(iidStr); #endif } else @@ -142,7 +144,7 @@ nsProxyEventClass::GetNewOrUsedClass(REFNSIID aIID) if (isISupportsDescendent) { clazz = new nsProxyEventClass(aIID, info); - if(!clazz->mDescriptors) + if (!clazz->mDescriptors) NS_RELEASE(clazz); // sets clazz to NULL } } @@ -153,12 +155,12 @@ nsProxyEventClass::GetNewOrUsedClass(REFNSIID aIID) nsProxyEventClass::nsProxyEventClass() { - NS_WARNING("This constructor should never be called"); + NS_NOTREACHED("This constructor should never be called"); } nsProxyEventClass::nsProxyEventClass(REFNSIID aIID, nsIInterfaceInfo* aInfo) -: mIID(aIID), - mDescriptors(NULL) + : mIID(aIID), + mDescriptors(NULL) { NS_ADDREF_THIS(); @@ -168,7 +170,8 @@ nsProxyEventClass::nsProxyEventClass(REFNSIID aIID, nsIInterfaceInfo* aInfo) nsIDKey key(aIID); nsProxyObjectManager *manager = nsProxyObjectManager::GetInstance(); - if (manager == nsnull) return; + if (manager == nsnull) + return; // don't need to lock the map, because this is only called // by GetNewOrUsed which locks it for us. @@ -184,7 +187,7 @@ nsProxyEventClass::nsProxyEventClass(REFNSIID aIID, nsIInterfaceInfo* aInfo) #ifdef PROXYEVENTCLASS_DEBUG char* iidStr = aIID.ToString(); printf("GetNewOrUsedClass %s put\n", iidStr); - nsCRT::free(iidStr); + PR_Free(iidStr); #endif } @@ -208,7 +211,7 @@ nsProxyEventClass::nsProxyEventClass(REFNSIID aIID, nsIInterfaceInfo* aInfo) nsProxyEventClass::~nsProxyEventClass() { - if(mDescriptors && mDescriptors != &zero_methods_descriptor) + if (mDescriptors && mDescriptors != &zero_methods_descriptor) delete [] mDescriptors; if (nsProxyObjectManager::IsManagerShutdown()) @@ -227,7 +230,7 @@ nsProxyEventClass::~nsProxyEventClass() #ifdef PROXYEVENTCLASS_DEBUG char* iidStr = mIID.ToString(); printf("GetNewOrUsedClass %s remove\n", iidStr); - nsCRT::free(iidStr); + PR_Free(iidStr); #endif } #endif @@ -242,7 +245,6 @@ nsProxyEventClass::CallQueryInterfaceOnProxy(nsProxyEventObject* self, REFNSIID *aInstancePtr = nsnull; // in case of error. - // The functions we will call: QueryInterface(REFNSIID aIID, void** aInstancePtr) nsXPTCMiniVariant var[2]; @@ -278,7 +280,7 @@ nsProxyEventClass::CallQueryInterfaceOnProxy(nsProxyEventObject* self, REFNSIID return NS_ERROR_FAILURE; } - rv = manager->GetProxyForObject(self->GetQueue(), + rv = manager->GetProxyForObject(self->GetTarget(), aIID, self->GetRealObject(), self->GetProxyType(), @@ -311,7 +313,7 @@ public: static ProxyEventClassIdentity* singleton = NULL; if(!singleton) singleton = new ProxyEventClassIdentity(); - return (void*) singleton; + return singleton; } }; @@ -333,41 +335,41 @@ nsProxyEventClass::DelegatedQueryInterface(nsProxyEventObject* self, nsProxyEventObject* sibling; { - nsProxyObjectManager* manager = nsProxyObjectManager::GetInstance(); - nsAutoMonitor mon(manager->GetMonitor()); + nsProxyObjectManager* manager = nsProxyObjectManager::GetInstance(); + nsAutoMonitor mon(manager->GetMonitor()); - // This includes checking for nsISupports and the iid of self. - // And it also checks for other wrappers that have been constructed - // for this object. - if(nsnull != (sibling = self->LockedFind(aIID))) - { - NS_ADDREF(sibling); - *aInstancePtr = (void*) sibling; - return NS_OK; - } - - // check if asking for an interface that we inherit from - nsCOMPtr current = GetInterfaceInfo(); - nsCOMPtr parent; - - while(NS_SUCCEEDED(current->GetParent(getter_AddRefs(parent))) && parent) - { - current = parent; - - nsIID* iid; - if(NS_SUCCEEDED(current->GetInterfaceIID(&iid)) && iid) + // This includes checking for nsISupports and the iid of self. + // And it also checks for other wrappers that have been constructed + // for this object. + if (nsnull != (sibling = self->LockedFind(aIID))) { - PRBool found = aIID.Equals(*iid); - nsMemory::Free(iid); - if(found) + NS_ADDREF(sibling); + *aInstancePtr = (void*) sibling; + return NS_OK; + } + + // check if asking for an interface that we inherit from + nsCOMPtr current = GetInterfaceInfo(); + nsCOMPtr parent; + + while (NS_SUCCEEDED(current->GetParent(getter_AddRefs(parent))) && parent) + { + current = parent; + + nsIID* iid; + if (NS_SUCCEEDED(current->GetInterfaceIID(&iid)) && iid) { - *aInstancePtr = (void*) self; - NS_ADDREF(self); - return NS_OK; + PRBool found = aIID.Equals(*iid); + nsMemory::Free(iid); + if (found) + { + *aInstancePtr = (void*) self; + NS_ADDREF(self); + return NS_OK; + } } } } - } return CallQueryInterfaceOnProxy(self, aIID, (nsProxyEventObject**)aInstancePtr); } diff --git a/mozilla/xpcom/proxy/src/nsProxyEventObject.cpp b/mozilla/xpcom/proxy/src/nsProxyEventObject.cpp index 5c8cfa3aef7..f1c577dbf4e 100644 --- a/mozilla/xpcom/proxy/src/nsProxyEventObject.cpp +++ b/mozilla/xpcom/proxy/src/nsProxyEventObject.cpp @@ -44,7 +44,6 @@ #include "nsIProxyObjectManager.h" #include "nsProxyEventPrivate.h" -#include "nsIEventQueueService.h" #include "nsServiceManagerUtils.h" #include "nsHashtable.h" @@ -55,36 +54,35 @@ #include "nsAutoLock.h" static NS_DEFINE_IID(kProxyObject_Identity_Class_IID, NS_PROXYEVENT_IDENTITY_CLASS_IID); -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); //////////////////////////////////////////////////////////////////////////////// class nsProxyEventKey : public nsHashKey { public: - nsProxyEventKey(void* rootObjectKey, void* destQueueKey, PRInt32 proxyType) - : mRootObjectKey(rootObjectKey), mDestQueueKey(destQueueKey), mProxyType(proxyType) { + nsProxyEventKey(void* rootObjectKey, void* targetKey, PRInt32 proxyType) + : mRootObjectKey(rootObjectKey), mTargetKey(targetKey), mProxyType(proxyType) { } PRUint32 HashCode(void) const { return NS_PTR_TO_INT32(mRootObjectKey) ^ - NS_PTR_TO_INT32(mDestQueueKey) ^ mProxyType; + NS_PTR_TO_INT32(mTargetKey) ^ mProxyType; } PRBool Equals(const nsHashKey *aKey) const { const nsProxyEventKey* other = (const nsProxyEventKey*)aKey; return mRootObjectKey == other->mRootObjectKey - && mDestQueueKey == other->mDestQueueKey + && mTargetKey == other->mTargetKey && mProxyType == other->mProxyType; } nsHashKey *Clone() const { - return new nsProxyEventKey(mRootObjectKey, mDestQueueKey, mProxyType); + return new nsProxyEventKey(mRootObjectKey, mTargetKey, mProxyType); } protected: void* mRootObjectKey; - void* mDestQueueKey; + void* mTargetKey; PRInt32 mProxyType; }; @@ -127,7 +125,7 @@ nsProxyEventObject::DebugDump(const char * message, PRUint32 hashKey) printf("%s wrapper around @ %x\n", isRoot ? "ROOT":"non-root\n", GetRealObject()); nsCOMPtr rootObject = do_QueryInterface(mProxyObject->mRealObject); - nsCOMPtr rootQueue = do_QueryInterface(mProxyObject->mDestQueue); + nsCOMPtr rootQueue = do_QueryInterface(mProxyObject->mTarget); nsProxyEventKey key(rootObject, rootQueue, mProxyObject->mProxyType); printf("Hashkey: %d\n", key.HashCode()); @@ -167,7 +165,7 @@ nsProxyEventObject::DebugDump(const char * message, PRUint32 hashKey) // ////////////////////////////////////////////////////////////////////////////////////////////////// nsProxyEventObject* -nsProxyEventObject::GetNewOrUsedProxy(nsIEventQueue *destQueue, +nsProxyEventObject::GetNewOrUsedProxy(nsIEventTarget *target, PRInt32 proxyType, nsISupports *aObj, REFNSIID aIID) @@ -199,7 +197,7 @@ nsProxyEventObject::GetNewOrUsedProxy(nsIEventQueue *destQueue, // if you hit this assertion, you might want to check out how // you are using proxies. You shouldn't need to be creating // a proxy from a proxy. -- dougt@netscape.com - NS_ASSERTION(0, "Someone is building a proxy from a proxy"); + NS_WARNING("Someone is building a proxy from a proxy"); NS_ASSERTION(identificationObject, "where did my identification object go!"); if (!identificationObject) { @@ -229,7 +227,7 @@ nsProxyEventObject::GetNewOrUsedProxy(nsIEventQueue *destQueue, // Get the root nsISupports of the event queue... This is used later, // as part of the hashtable key... - nsCOMPtr destQRoot = do_QueryInterface(destQueue, &rv); + nsCOMPtr destQRoot = do_QueryInterface(target, &rv); if (NS_FAILED(rv) || !destQRoot) { return nsnull; } @@ -247,10 +245,6 @@ nsProxyEventObject::GetNewOrUsedProxy(nsIEventQueue *destQueue, return nsnull; } - nsCOMPtr eventQService(do_GetService(kEventQueueServiceCID, &rv)); - if (NS_FAILED(rv)) - return nsnull; - nsAutoMonitor mon(manager->GetMonitor()); // Get the hash table containing root proxy objects... @@ -299,12 +293,11 @@ nsProxyEventObject::GetNewOrUsedProxy(nsIEventQueue *destQueue, return nsnull; } - peo = new nsProxyEventObject(destQueue, + peo = new nsProxyEventObject(target, proxyType, rootObject, rootClazz, - nsnull, - eventQService); + nsnull); if(!peo) { // Ouch... Out of memory! return nsnull; @@ -352,12 +345,11 @@ nsProxyEventObject::GetNewOrUsedProxy(nsIEventQueue *destQueue, return nsnull; } - peo = new nsProxyEventObject(destQueue, + peo = new nsProxyEventObject(target, proxyType, rawInterface, proxyClazz, - rootProxy, - eventQService); + rootProxy); if (!peo) { // Ouch... Out of memory! return nsnull; @@ -402,19 +394,18 @@ nsProxyEventObject::nsProxyEventObject() NS_WARNING("This constructor should never be called"); } -nsProxyEventObject::nsProxyEventObject(nsIEventQueue *destQueue, +nsProxyEventObject::nsProxyEventObject(nsIEventTarget *target, PRInt32 proxyType, nsISupports* aObj, nsProxyEventClass* aClass, - nsProxyEventObject* root, - nsIEventQueueService* eventQService) + nsProxyEventObject* root) : mClass(aClass), mRoot(root), mNext(nsnull) { NS_IF_ADDREF(mRoot); - mProxyObject = new nsProxyObject(destQueue, proxyType, aObj, eventQService); + mProxyObject = new nsProxyObject(target, proxyType, aObj); #ifdef DEBUG_xpcom_proxy DebugDump("Create", 0); @@ -456,7 +447,7 @@ nsProxyEventObject::~nsProxyEventObject() if (realToProxyMap != nsnull) { nsCOMPtr rootObject = do_QueryInterface(mProxyObject->mRealObject); - nsCOMPtr rootQueue = do_QueryInterface(mProxyObject->mDestQueue); + nsCOMPtr rootQueue = do_QueryInterface(mProxyObject->mTarget); nsProxyEventKey key(rootObject, rootQueue, mProxyObject->mProxyType); #ifdef DEBUG_dougt void* value = diff --git a/mozilla/xpcom/proxy/src/nsProxyEventPrivate.h b/mozilla/xpcom/proxy/src/nsProxyEventPrivate.h index 07ad7141dac..d153d159992 100644 --- a/mozilla/xpcom/proxy/src/nsProxyEventPrivate.h +++ b/mozilla/xpcom/proxy/src/nsProxyEventPrivate.h @@ -36,20 +36,19 @@ * * ***** END LICENSE BLOCK ***** */ -#ifndef __nsProxyEventPrivate_h_ -#define __nsProxyEventPrivate_h_ +#ifndef nsProxyEventPrivate_h__ +#define nsProxyEventPrivate_h__ #include "nscore.h" #include "nsISupports.h" #include "nsIFactory.h" #include "nsHashtable.h" -#include "plevent.h" #include "xptcall.h" // defines nsXPTCVariant -#include "nsIEventQueue.h" #include "nsProxyEvent.h" #include "nsIProxyObjectManager.h" +#include "prmon.h" class nsProxyEventObject; class nsProxyEventClass; @@ -113,7 +112,7 @@ public: NS_DECLARE_STATIC_IID_ACCESSOR(NS_PROXYEVENT_OBJECT_IID) - static nsProxyEventObject* GetNewOrUsedProxy(nsIEventQueue *destQueue, + static nsProxyEventObject* GetNewOrUsedProxy(nsIEventTarget *target, PRInt32 proxyType, nsISupports *aObj, REFNSIID aIID); @@ -126,17 +125,16 @@ public: nsProxyEventClass* GetClass() const { return mClass; } - nsIEventQueue* GetQueue() const { return (mProxyObject ? mProxyObject->GetQueue() : nsnull);} + nsIEventTarget* GetTarget() const { return (mProxyObject ? mProxyObject->GetTarget() : nsnull);} nsISupports* GetRealObject() const { return (mProxyObject ? mProxyObject->GetRealObject(): nsnull);} PRInt32 GetProxyType() const { return (mProxyObject ? mProxyObject->GetProxyType() : nsnull);} nsProxyEventObject(); - nsProxyEventObject(nsIEventQueue *destQueue, + nsProxyEventObject(nsIEventTarget *target, PRInt32 proxyType, nsISupports* aObj, nsProxyEventClass* aClass, - nsProxyEventObject* root, - nsIEventQueueService* eventQService); + nsProxyEventObject* root); nsProxyEventObject* LockedFind(REFNSIID aIID); @@ -170,11 +168,9 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsProxyEventObject, NS_PROXYEVENT_OBJECT_IID) class nsProxyObjectManager: public nsIProxyObjectManager { public: - NS_DECL_ISUPPORTS NS_DECL_NSIPROXYOBJECTMANAGER - static NS_METHOD Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr); nsProxyObjectManager(); @@ -199,4 +195,4 @@ private: }; -#endif +#endif // nsProxyEventPrivate_h__ diff --git a/mozilla/xpcom/proxy/src/nsProxyObjectManager.cpp b/mozilla/xpcom/proxy/src/nsProxyObjectManager.cpp index 566c4e8199d..0f4edabcd93 100644 --- a/mozilla/xpcom/proxy/src/nsProxyObjectManager.cpp +++ b/mozilla/xpcom/proxy/src/nsProxyObjectManager.cpp @@ -50,59 +50,15 @@ #include "nsProxyEvent.h" #include "nsIProxyObjectManager.h" #include "nsProxyEventPrivate.h" - -#include "nsIProxyCreateInstance.h" +#include "nsThreadUtils.h" #include "nsIComponentManager.h" #include "nsIServiceManager.h" #include "nsCOMPtr.h" -#include "nsIEventQueueService.h" #include "nsIThread.h" -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); - -/***************************************************************************/ -/* nsProxyCreateInstance */ -/* This private class will allow us to create Instances on another thread */ -/***************************************************************************/ -class nsProxyCreateInstance : public nsIProxyCreateInstance -{ - NS_DECL_ISUPPORTS - NS_IMETHOD CreateInstanceByIID(const nsIID & cid, nsISupports *aOuter, const nsIID & iid, void * *result); - NS_IMETHOD CreateInstanceByContractID(const char *aContractID, nsISupports *aOuter, const nsIID & iid, void * *result); - - nsProxyCreateInstance() - { - NS_GetComponentManager(getter_AddRefs(mCompMgr)); - NS_ASSERTION(mCompMgr, "no component manager"); - } - -private: - - nsCOMPtr mCompMgr; -}; - -NS_IMPL_ISUPPORTS1(nsProxyCreateInstance, nsIProxyCreateInstance) - -NS_IMETHODIMP nsProxyCreateInstance::CreateInstanceByIID(const nsIID & cid, nsISupports *aOuter, const nsIID & iid, void * *result) -{ - return mCompMgr->CreateInstance(cid, - aOuter, - iid, - result); -} - - -NS_IMETHODIMP nsProxyCreateInstance::CreateInstanceByContractID(const char *aContractID, nsISupports *aOuter, const nsIID & iid, void * *result) -{ - return mCompMgr->CreateInstanceByContractID(aContractID, - aOuter, - iid, - result); -} - ///////////////////////////////////////////////////////////////////////// // nsProxyObjectManager ///////////////////////////////////////////////////////////////////////// @@ -118,20 +74,20 @@ nsProxyObjectManager::nsProxyObjectManager() mProxyCreationMonitor = PR_NewMonitor(); } -static PRBool PurgeProxyClasses(nsHashKey *aKey, void *aData, void* closure) +static PRIntn +PurgeProxyClasses(nsHashKey *aKey, void *aData, void* closure) { - nsProxyEventClass* ptr = NS_REINTERPRET_CAST(nsProxyEventClass*, aData); + nsProxyEventClass* ptr = NS_STATIC_CAST(nsProxyEventClass*, aData); NS_RELEASE(ptr); - return PR_TRUE; + return kHashEnumerateNext; } nsProxyObjectManager::~nsProxyObjectManager() { - mProxyClassMap.Reset((nsHashtableEnumFunc)PurgeProxyClasses, nsnull); + mProxyClassMap.Reset(PurgeProxyClasses, nsnull); - if (mProxyCreationMonitor) { + if (mProxyCreationMonitor) PR_DestroyMonitor(mProxyCreationMonitor); - } nsProxyObjectManager::mInstance = nsnull; } @@ -139,158 +95,71 @@ nsProxyObjectManager::~nsProxyObjectManager() PRBool nsProxyObjectManager::IsManagerShutdown() { - if (mInstance) - return PR_FALSE; - return PR_TRUE; + return mInstance == nsnull; } nsProxyObjectManager * nsProxyObjectManager::GetInstance() { - if (! mInstance) - { + if (!mInstance) mInstance = new nsProxyObjectManager(); - } return mInstance; } - void nsProxyObjectManager::Shutdown() { mInstance = nsnull; } - -// Helpers NS_IMETHODIMP -nsProxyObjectManager::Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr) +nsProxyObjectManager::Create(nsISupports* outer, const nsIID& aIID, + void* *aInstancePtr) { nsProxyObjectManager *proxyObjectManager = GetInstance(); - - if (proxyObjectManager == nsnull) + if (!proxyObjectManager) return NS_ERROR_OUT_OF_MEMORY; return proxyObjectManager->QueryInterface(aIID, aInstancePtr); } - NS_IMETHODIMP -nsProxyObjectManager::GetProxyForObject(nsIEventQueue *destQueue, +nsProxyObjectManager::GetProxyForObject(nsIEventTarget* aTarget, REFNSIID aIID, nsISupports* aObj, PRInt32 proxyType, void** aProxyObject) { - if (!aObj) return NS_ERROR_NULL_POINTER; - if (!aProxyObject) return NS_ERROR_NULL_POINTER; - - nsresult rv; - nsCOMPtr postQ; - + NS_ENSURE_ARG_POINTER(aTarget); + NS_ENSURE_ARG_POINTER(aObj); *aProxyObject = nsnull; - // check to see if the destination Q is a special case. + nsCOMPtr currentThread; + if (!aTarget) { + currentThread = do_GetCurrentThread(); + aTarget = currentThread.get(); + } + + // check to see if the target is on our thread. If so, just return the + // real object. - nsCOMPtr eventQService = - do_GetService(kEventQueueServiceCID, &rv); - if (NS_FAILED(rv)) - return rv; - - rv = eventQService->ResolveEventQueue(destQueue, getter_AddRefs(postQ)); - if (NS_FAILED(rv)) - return rv; - - // check to see if the eventQ is on our thread. If so, just return the real object. - - if (postQ && !(proxyType & PROXY_ASYNC) && !(proxyType & PROXY_ALWAYS)) + if (!(proxyType & NS_PROXY_ASYNC) && !(proxyType & NS_PROXY_ALWAYS)) { - PRBool aResult; - postQ->IsOnCurrentThread(&aResult); + PRBool result; + aTarget->IsOnCurrentThread(&result); - if (aResult) - { + if (result) return aObj->QueryInterface(aIID, aProxyObject); - } } // check to see if proxy is there or not. - *aProxyObject = nsProxyEventObject::GetNewOrUsedProxy(postQ, proxyType, aObj, aIID); - - if (*aProxyObject == nsnull) - return NS_ERROR_NO_INTERFACE; //fix error code? + *aProxyObject = nsProxyEventObject::GetNewOrUsedProxy(aTarget, proxyType, + aObj, aIID); + if (!*aProxyObject) + return NS_ERROR_UNEXPECTED; - return NS_OK; -} - - -NS_IMETHODIMP -nsProxyObjectManager::GetProxy( nsIEventQueue *destQueue, - const nsCID &aClass, - nsISupports *aDelegate, - const nsIID &aIID, - PRInt32 proxyType, - void** aProxyObject) -{ - if (!aProxyObject) return NS_ERROR_NULL_POINTER; - *aProxyObject = nsnull; - - // 1. Create a proxy for creating an instance on another thread. - - nsIProxyCreateInstance* ciProxy = nsnull; - - nsProxyCreateInstance* ciObject = new nsProxyCreateInstance(); - - if (ciObject == nsnull) - return NS_ERROR_NULL_POINTER; - - NS_ADDREF(ciObject); - - nsresult rv = GetProxyForObject(destQueue, - NS_GET_IID(nsIProxyCreateInstance), - ciObject, - PROXY_SYNC, - (void**)&ciProxy); - - if (NS_FAILED(rv)) - { - NS_RELEASE(ciObject); - return rv; - } - - // 2. now create a new instance of the request object via our proxy. - - nsISupports* aObj; - - rv = ciProxy->CreateInstanceByIID(aClass, - aDelegate, - aIID, - (void**)&aObj); - - - // 3. Delete the create instance proxy and its real object. - - NS_RELEASE(ciProxy); - NS_RELEASE(ciObject); - - // 4. Check to see if creating the requested instance failed. - if ( NS_FAILED(rv)) - { - return rv; - } - - // 5. Now create a proxy object for the requested object. - - rv = GetProxyForObject(destQueue, aIID, aObj, proxyType, aProxyObject); - - // 6. release ownership of aObj so that aProxyObject owns it. - - NS_RELEASE(aObj); - - // 7. return the error returned from GetProxyForObject. Either way, we our out of here. - - return rv; + return NS_OK; } /** @@ -301,7 +170,7 @@ nsProxyObjectManager::GetProxy( nsIEventQueue *destQueue, * readable. */ NS_COM nsresult -NS_GetProxyForObject(nsIEventQueue *destQueue, +NS_GetProxyForObject(nsIEventTarget *target, REFNSIID aIID, nsISupports* aObj, PRInt32 proxyType, @@ -309,18 +178,23 @@ NS_GetProxyForObject(nsIEventQueue *destQueue, { static NS_DEFINE_CID(proxyObjMgrCID, NS_PROXYEVENT_MANAGER_CID); - nsresult rv; // temp for return value + nsresult rv; + + nsCOMPtr mainThread; + if (target == NS_PROXY_TO_MAIN_THREAD) { + mainThread = do_GetMainThread(); + target = mainThread.get(); + } // get the proxy object manager // nsCOMPtr proxyObjMgr = do_GetService(proxyObjMgrCID, &rv); - if (NS_FAILED(rv)) - return NS_ERROR_FAILURE; + return rv; // and try to get the proxy object // - return proxyObjMgr->GetProxyForObject(destQueue, aIID, aObj, + return proxyObjMgr->GetProxyForObject(target, aIID, aObj, proxyType, aProxyObject); } diff --git a/mozilla/xpcom/proxy/src/nsProxyRelease.cpp b/mozilla/xpcom/proxy/src/nsProxyRelease.cpp index 3ceeb6674bf..7d9c308cf1f 100644 --- a/mozilla/xpcom/proxy/src/nsProxyRelease.cpp +++ b/mozilla/xpcom/proxy/src/nsProxyRelease.cpp @@ -1,21 +1,65 @@ +/* vim:set ts=4 sw=4 sts=4 et cin: */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2003 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Darin Fisher + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + #include "nsProxyRelease.h" +#include "nsThreadUtils.h" +#include "nsAutoPtr.h" -PR_STATIC_CALLBACK(void*) -HandleProxyReleaseEvent(PLEvent *self) -{ - nsISupports* owner = (nsISupports*) self->owner; - NS_RELEASE(owner); - return nsnull; -} - -PR_STATIC_CALLBACK(void) -DestroyProxyReleaseEvent(PLEvent *self) +class nsProxyReleaseEvent : public nsRunnable { - delete self; -} +public: + nsProxyReleaseEvent(nsISupports *doomed) + : mDoomed(doomed) { + } + + NS_IMETHOD Run() + { + mDoomed->Release(); + return NS_OK; + } + +private: + nsISupports *mDoomed; +}; NS_COM nsresult -NS_ProxyRelease(nsIEventTarget *target, nsISupports *doomed, PRBool alwaysProxy) +NS_ProxyRelease(nsIEventTarget *target, nsISupports *doomed, + PRBool alwaysProxy) { nsresult rv; @@ -33,21 +77,16 @@ NS_ProxyRelease(nsIEventTarget *target, nsISupports *doomed, PRBool alwaysProxy) } } - PLEvent *ev = new PLEvent; + nsRefPtr ev = new nsProxyReleaseEvent(doomed); if (!ev) { // we do not release doomed here since it may cause a delete on the // wrong thread. better to leak than crash. return NS_ERROR_OUT_OF_MEMORY; } - PL_InitEvent(ev, doomed, - HandleProxyReleaseEvent, - DestroyProxyReleaseEvent); - - rv = target->PostEvent(ev); + rv = target->Dispatch(ev, NS_DISPATCH_NORMAL); if (NS_FAILED(rv)) { NS_WARNING("failed to post proxy release event"); - PL_DestroyEvent(ev); // again, it is better to leak the doomed object than risk crashing as // a result of deleting it on the wrong thread. } diff --git a/mozilla/xpcom/proxy/tests/proxytests.cpp b/mozilla/xpcom/proxy/tests/proxytests.cpp index 71346b24250..f1498c9ccb7 100644 --- a/mozilla/xpcom/proxy/tests/proxytests.cpp +++ b/mozilla/xpcom/proxy/tests/proxytests.cpp @@ -42,7 +42,9 @@ #include "nsIComponentManager.h" #include "nsIComponentRegistrar.h" #include "nsIServiceManager.h" +#include "nsAutoPtr.h" #include "nsCOMPtr.h" +#include "nsCOMArray.h" #include "nscore.h" #include "nspr.h" @@ -50,12 +52,29 @@ #include "nsITestProxy.h" +#include "nsIRunnable.h" #include "nsIProxyObjectManager.h" -#include "nsIEventQueueService.h" #include "nsComponentManagerUtils.h" #include "nsServiceManagerUtils.h" +#include "nsThreadUtils.h" -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); +#include "prlog.h" +#ifdef PR_LOGGING +static PRLogModuleInfo *sLog = PR_NewLogModule("Test"); +#define LOG(args) PR_LOG(sLog, PR_LOG_DEBUG, args) +#else +#define LOG(args) printf args +#endif + +static nsresult +GetThreadFromPRThread(PRThread *prthread, nsIThread **result) +{ + LOG(("TEST: GetThreadFromPRThread [%p]\n", prthread)); + + nsCOMPtr tm = do_GetService(NS_THREADMANAGER_CONTRACTID); + NS_ENSURE_STATE(tm); + return tm->GetThreadFromPRThread(prthread, result); +} /***************************************************************************/ /* nsTestXPCFoo */ @@ -79,7 +98,7 @@ NS_IMPL_ISUPPORTS1(nsTestXPCFoo, nsITestProxy) NS_IMETHODIMP nsTestXPCFoo::Test(PRInt32 p1, PRInt32 p2, PRInt32* retval) { - printf("Thread (%d) Test Called successfully! Party on...\n", p1); + LOG(("TEST: Thread (%d) Test Called successfully! Party on...\n", p1)); *retval = p1+p2; return NS_OK; } @@ -87,7 +106,7 @@ NS_IMETHODIMP nsTestXPCFoo::Test(PRInt32 p1, PRInt32 p2, PRInt32* retval) NS_IMETHODIMP nsTestXPCFoo::Test2() { - printf("The quick brown netscape jumped over the old lazy ie..\n"); + LOG(("TEST: The quick brown netscape jumped over the old lazy ie..\n")); return NS_OK; } @@ -103,7 +122,7 @@ NS_IMETHODIMP nsTestXPCFoo::Test3(nsISupports *p1, nsISupports **p2) test->Test2(); PRInt32 a; test->Test( 1, 2, &a); - printf("\n1+2=%d\n",a); + LOG(("TEST: \n1+2=%d\n",a)); } @@ -133,28 +152,31 @@ NS_IMPL_THREADSAFE_ISUPPORTS1(nsTestXPCFoo2, nsITestProxy) NS_IMETHODIMP nsTestXPCFoo2::Test(PRInt32 p1, PRInt32 p2, PRInt32* retval) { - printf("calling back to caller!\n\n"); + LOG(("TEST: calling back to caller!\n")); nsCOMPtr manager = do_GetService(NS_XPCOMPROXY_CONTRACTID); - printf("ProxyObjectManager: %p \n", (void *) manager.get()); + LOG(("TEST: ProxyObjectManager: %p \n", (void *) manager.get())); PR_ASSERT(manager); + nsCOMPtr thread; + GetThreadFromPRThread((PRThread *) p1, getter_AddRefs(thread)); + NS_ENSURE_STATE(thread); + nsCOMPtr proxyObject; - manager->GetProxyForObject((nsIEventQueue*)p1, NS_GET_IID(nsITestProxy), - this, PROXY_SYNC, (void**)&proxyObject); + manager->GetProxyForObject(thread, NS_GET_IID(nsITestProxy), this, NS_PROXY_SYNC, (void**)&proxyObject); proxyObject->Test3(nsnull, nsnull); - printf("Deleting Proxy Object\n"); + LOG(("TEST: Deleting Proxy Object\n")); return NS_OK; } NS_IMETHODIMP nsTestXPCFoo2::Test2() { - printf("nsTestXPCFoo2::Test2() called\n"); + LOG(("TEST: nsTestXPCFoo2::Test2() called\n")); return NS_OK; } @@ -162,17 +184,17 @@ NS_IMETHODIMP nsTestXPCFoo2::Test2() NS_IMETHODIMP nsTestXPCFoo2::Test3(nsISupports *p1, nsISupports **p2) { - printf("Got called"); + LOG(("TEST: Got called")); return NS_OK; } -typedef struct _ArgsStruct -{ - nsIEventQueue* queue; - PRInt32 threadNumber; -}ArgsStruct; +#if 0 +struct ArgsStruct { + nsIThread* thread; + PRInt32 threadNumber; +}; @@ -199,9 +221,9 @@ void TestCase_TwoClassesOneInterface(void *arg) PR_ASSERT(foo2); - manager->GetProxyForObject(argsStruct->queue, NS_GET_IID(nsITestProxy), foo, PROXY_SYNC, (void**)&proxyObject); + manager->GetProxyForObject(argsStruct->thread, NS_GET_IID(nsITestProxy), foo, NS_PROXY_SYNC, (void**)&proxyObject); - manager->GetProxyForObject(argsStruct->queue, NS_GET_IID(nsITestProxy), foo2, PROXY_SYNC, (void**)&proxyObject2); + manager->GetProxyForObject(argsStruct->thread, NS_GET_IID(nsITestProxy), foo2, NS_PROXY_SYNC, (void**)&proxyObject2); @@ -242,17 +264,16 @@ void TestCase_TwoClassesOneInterface(void *arg) PR_Sleep( PR_MillisecondsToInterval(1000) ); // If your thread goes away, your stack goes away. Only use ASYNC on calls that do not have out parameters } +#endif -void TestCase_NestedLoop(void *arg) +void TestCase_NestedLoop(nsIThread *thread, PRInt32 index) { - ArgsStruct *argsStruct = (ArgsStruct*) arg; - nsCOMPtr manager = do_GetService(NS_XPCOMPROXY_CONTRACTID); - printf("ProxyObjectManager: %p\n", (void *) manager.get()); + LOG(("TEST: ProxyObjectManager: %p\n", (void *) manager.get())); PR_ASSERT(manager); @@ -262,40 +283,30 @@ void TestCase_NestedLoop(void *arg) PR_ASSERT(foo); - manager->GetProxyForObject(argsStruct->queue, NS_GET_IID(nsITestProxy), foo, PROXY_SYNC, (void**)&proxyObject); + manager->GetProxyForObject(thread, NS_GET_IID(nsITestProxy), foo, NS_PROXY_SYNC, (void**)&proxyObject); if (proxyObject) { // release ownership of the real object. nsresult rv; - PRInt32 threadNumber = argsStruct->threadNumber; - printf("Deleting real Object (%d)\n", threadNumber); + LOG(("TEST: Deleting real Object (%d)\n", index)); NS_RELEASE(foo); PRInt32 retval; - printf("Getting EventQueue...\n"); + LOG(("TEST: Getting EventThread...\n")); - nsIEventQueue* eventQ; - nsCOMPtr eventQService = - do_GetService(kEventQueueServiceCID, &rv); - if (NS_SUCCEEDED(rv)) + //nsCOMPtr curThread = do_GetCurrentThread(); + PRThread *curThread = PR_GetCurrentThread(); + if (curThread) { - rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &eventQ); - if (NS_FAILED(rv)) - rv = eventQService->CreateThreadEventQueue(); - if (NS_FAILED(rv)) - return; - else - rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &eventQ); - - printf("Thread (%d) Prior to calling proxyObject->Test.\n", threadNumber); - rv = proxyObject->Test(NS_PTR_TO_INT32(eventQ), 0, &retval); - printf("Thread (%d) proxyObject error: %d.\n", threadNumber, rv); + LOG(("TEST: Thread (%d) Prior to calling proxyObject->Test.\n", index)); + rv = proxyObject->Test(NS_PTR_TO_INT32((void*)curThread), 0, &retval); // XXX broken on 64-bit arch + LOG(("TEST: Thread (%d) proxyObject error: %x.\n", index, rv)); - printf("Deleting Proxy Object (%d)\n", threadNumber ); + LOG(("TEST: Deleting Proxy Object (%d)\n", index)); NS_RELEASE(proxyObject); } @@ -304,34 +315,7 @@ void TestCase_NestedLoop(void *arg) } - -void TestCase_2(void *arg) -{ - - ArgsStruct *argsStruct = (ArgsStruct*) arg; - - nsCOMPtr manager = - do_GetService(NS_XPCOMPROXY_CONTRACTID); - - PR_ASSERT(manager); - - nsITestProxy *proxyObject; - - manager->GetProxy(argsStruct->queue, - NS_GET_IID(nsITestProxy), // should be CID! - nsnull, - NS_GET_IID(nsITestProxy), - PROXY_SYNC, - (void**)&proxyObject); - - if (proxyObject != nsnull) - { - NS_RELEASE(proxyObject); - } -} - - - +#if 0 void TestCase_nsISupports(void *arg) { @@ -347,7 +331,7 @@ void TestCase_nsISupports(void *arg) PR_ASSERT(foo); - manager->GetProxyForObject(argsStruct->queue, NS_GET_IID(nsITestProxy), foo, PROXY_SYNC, (void**)&proxyObject); + manager->GetProxyForObject(argsStruct->thread, NS_GET_IID(nsITestProxy), foo, NS_PROXY_SYNC, (void**)&proxyObject); if (proxyObject != nsnull) { @@ -365,96 +349,74 @@ void TestCase_nsISupports(void *arg) NS_RELEASE(proxyObject); } } - - - - +#endif /***************************************************************************/ /* ProxyTest */ /***************************************************************************/ -static void PR_CALLBACK ProxyTest( void *arg ) +class ProxyTest : public nsIRunnable { - //TestCase_TwoClassesOneInterface(arg); - // TestCase_2(arg); - //TestCase_nsISupports(arg); - TestCase_NestedLoop(arg); +public: + NS_DECL_ISUPPORTS - NS_RELEASE( ((ArgsStruct*) arg)->queue); - free((void*) arg); -} + ProxyTest(PRThread *eventLoopThread, PRInt32 index) + : mEventLoopThread(eventLoopThread) + , mIndex(index) + {} -nsIEventQueue *gEventQueue = nsnull; - -static void PR_CALLBACK EventLoop( void *arg ) -{ - nsresult rv; - printf("Creating EventQueue...\n"); - - nsIEventQueue* eventQ; - nsCOMPtr eventQService = - do_GetService(kEventQueueServiceCID, &rv); - if (NS_SUCCEEDED(rv)) { - rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &eventQ); - if (NS_FAILED(rv)) - rv = eventQService->CreateThreadEventQueue(); - if (NS_FAILED(rv)) - return; - else - rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &eventQ); - } - if (NS_FAILED(rv)) return; - - rv = eventQ->QueryInterface(NS_GET_IID(nsIEventQueue), (void**)&gEventQueue); - if (NS_FAILED(rv)) return; - - - printf("Verifing calling Proxy on eventQ thread.\n"); - - nsCOMPtr manager = - do_GetService(NS_XPCOMPROXY_CONTRACTID); - - PR_ASSERT(manager); - - nsITestProxy *proxyObject; - nsTestXPCFoo* foo = new nsTestXPCFoo(); - - PR_ASSERT(foo); - - manager->GetProxyForObject(gEventQueue, NS_GET_IID(nsITestProxy), foo, PROXY_SYNC, (void**)&proxyObject); - - PRInt32 a; - proxyObject->Test(1, 2, &a); - proxyObject->Test2(); - - - NS_RELEASE(proxyObject); - delete foo; - - printf("End of Verification calling Proxy on eventQ thread.\n"); - - - printf("Looping for events.\n"); - - PLEvent* event = nsnull; - - while ( PR_SUCCESS == PR_Sleep( PR_MillisecondsToInterval(1)) ) + NS_IMETHOD Run() { - rv = gEventQueue->GetEvent(&event); - if (NS_FAILED(rv)) - return; - gEventQueue->HandleEvent(event); + //TestCase_TwoClassesOneInterface(arg); + //TestCase_nsISupports(arg); + nsCOMPtr thread; + GetThreadFromPRThread(mEventLoopThread, getter_AddRefs(thread)); + TestCase_NestedLoop(thread, mIndex); + + return NS_OK; } - gEventQueue->ProcessPendingEvents(); +private: + PRThread *mEventLoopThread; + PRInt32 mIndex; +}; +NS_IMPL_THREADSAFE_ISUPPORTS1(ProxyTest, nsIRunnable) - printf("Closing down Event Queue.\n"); - delete gEventQueue; - gEventQueue = nsnull; +class TestSyncProxyToSelf : public nsIRunnable +{ +public: + NS_DECL_ISUPPORTS - printf("End looping for events.\n\n"); -} + NS_IMETHOD Run() + { + LOG(("TEST: Verifing calling Proxy on eventQ thread.\n")); + + nsCOMPtr thread = do_GetCurrentThread(); + + nsITestProxy *proxyObject; + nsTestXPCFoo *foo = new nsTestXPCFoo(); + NS_ENSURE_STATE(foo); + + nsCOMPtr manager = + do_GetService(NS_XPCOMPROXY_CONTRACTID); + + manager->GetProxyForObject(thread, + NS_GET_IID(nsITestProxy), foo, + NS_PROXY_SYNC, (void**)&proxyObject); + + PRInt32 a; + proxyObject->Test(1, 2, &a); + proxyObject->Test2(); + + NS_RELEASE(proxyObject); + delete foo; + + LOG(("TEST: End of Verification calling Proxy on eventQ thread.\n")); + + return NS_OK; + } +}; +NS_IMPL_THREADSAFE_ISUPPORTS1(TestSyncProxyToSelf, nsIRunnable) int main(int argc, char **argv) @@ -464,72 +426,58 @@ main(int argc, char **argv) if (argc > 1) numberOfThreads = atoi(argv[1]); - nsCOMPtr servMan; - NS_InitXPCOM2(getter_AddRefs(servMan), nsnull, nsnull); - nsCOMPtr registrar = do_QueryInterface(servMan); - NS_ASSERTION(registrar, "Null nsIComponentRegistrar"); - registrar->AutoRegister(nsnull); - - static PRThread** threads = (PRThread**) calloc(sizeof(PRThread*), numberOfThreads); - static PRThread* aEventThread; - - aEventThread = PR_CreateThread(PR_USER_THREAD, - EventLoop, - NULL, - PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD, - PR_JOINABLE_THREAD, - 0 ); + NS_InitXPCOM2(nsnull, nsnull, nsnull); - - PR_Sleep(PR_MillisecondsToInterval(1000)); - - NS_ASSERTION(gEventQueue, "no main event queue"); // BAD BAD BAD. EVENT THREAD DID NOT CREATE QUEUE. This may be a timing issue, set the - // sleep about longer, and try again. - - printf("Spawn Threads:\n"); - for (PRInt32 spawn = 0; spawn < numberOfThreads; spawn++) + // Scope code so everything is destroyed before we run call NS_ShutdownXPCOM { + nsCOMPtr registrar; + NS_GetComponentRegistrar(getter_AddRefs(registrar)); + registrar->AutoRegister(nsnull); - ArgsStruct *args = (ArgsStruct *) malloc (sizeof(ArgsStruct)); + nsCOMPtr eventLoopThread; + NS_NewThread(getter_AddRefs(eventLoopThread), nsnull, + "proxytests.eventloop"); + + nsCOMPtr test = new TestSyncProxyToSelf(); + eventLoopThread->Dispatch(test, NS_DISPATCH_NORMAL); + + PRThread *eventLoopPRThread; + eventLoopThread->GetPRThread(&eventLoopPRThread); + PR_ASSERT(eventLoopPRThread); - args->queue = gEventQueue; - NS_ADDREF(args->queue); - args->threadNumber = spawn; + LOG(("TEST: Spawn Threads:\n")); + nsCOMArray threads; + for (PRInt32 spawn = 0; spawn < numberOfThreads; spawn++) + { + test = new ProxyTest(eventLoopPRThread, spawn); - threads[spawn] = PR_CreateThread(PR_USER_THREAD, - ProxyTest, - args, - PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD, - PR_JOINABLE_THREAD, - 0 ); + nsCOMPtr thread; + NS_NewThread(getter_AddRefs(thread), test); - printf("\tThread (%d) spawned\n", spawn); + threads.AppendObject(thread); - PR_Sleep( PR_MillisecondsToInterval(250) ); + LOG(("TEST: \tThread (%d) spawned\n", spawn)); + + PR_Sleep( PR_MillisecondsToInterval(250) ); + } + + LOG(("TEST: All Threads Spawned.\n")); + + LOG(("TEST: Wait for threads.\n")); + for (PRInt32 i = 0; i < numberOfThreads; i++) + { + LOG(("TEST: Thread (%d) Join...\n", i)); + nsresult rv = threads[i]->Shutdown(); + LOG(("TEST: Thread (%d) Joined. (error: %x).\n", i, rv)); + } + + LOG(("TEST: Shutting down event loop thread\n")); + eventLoopThread->Shutdown(); } - printf("All Threads Spawned.\n\n"); - - - - printf("Wait for threads.\n"); - for (PRInt32 i = 0; i < numberOfThreads; i++) - { - PRStatus rv; - printf("Thread (%d) Join...\n", i); - rv = PR_JoinThread(threads[i]); - printf("Thread (%d) Joined. (error: %d).\n", i, rv); - } + LOG(("TEST: Calling Cleanup.\n")); + NS_ShutdownXPCOM(nsnull); - PR_Interrupt(aEventThread); - PR_JoinThread(aEventThread); - - - printf("Calling Cleanup.\n"); - PR_Cleanup(); - - printf("Return zero.\n"); + LOG(("TEST: Return zero.\n")); return 0; } diff --git a/mozilla/xpcom/tests/Makefile.in b/mozilla/xpcom/tests/Makefile.in index 2e425474000..40ae0bbc763 100644 --- a/mozilla/xpcom/tests/Makefile.in +++ b/mozilla/xpcom/tests/Makefile.in @@ -84,6 +84,7 @@ CPPSRCS += \ TestPermanentAtoms.cpp \ TestPipes.cpp \ TestThreads.cpp \ + TestThreadPool.cpp \ TestXPIDLString.cpp \ TestDeque.cpp \ TestStrings.cpp \ diff --git a/mozilla/xpcom/tests/TestPipes.cpp b/mozilla/xpcom/tests/TestPipes.cpp index 644c8a9bf3d..834348f9c9f 100644 --- a/mozilla/xpcom/tests/TestPipes.cpp +++ b/mozilla/xpcom/tests/TestPipes.cpp @@ -41,6 +41,7 @@ #include "nsIInputStream.h" #include "nsIOutputStream.h" #include "nsIServiceManager.h" +#include "nsThreadUtils.h" #include "prprf.h" #include "prinrval.h" #include "plstr.h" @@ -134,7 +135,7 @@ TestPipe(nsIInputStream* in, nsIOutputStream* out) if (receiver == nsnull) return NS_ERROR_OUT_OF_MEMORY; NS_ADDREF(receiver); - rv = NS_NewThread(&thread, receiver, 0, PR_JOINABLE_THREAD); + rv = NS_NewThread(&thread, receiver, "TestPipe"); if (NS_FAILED(rv)) return rv; PRUint32 total = 0; @@ -160,7 +161,7 @@ TestPipe(nsIInputStream* in, nsIOutputStream* out) PRIntervalTime end = PR_IntervalNow(); - thread->Join(); + thread->Shutdown(); printf("wrote %d bytes, time = %dms\n", total, PR_IntervalToMilliseconds(end - start)); @@ -247,7 +248,7 @@ TestShortWrites(nsIInputStream* in, nsIOutputStream* out) if (receiver == nsnull) return NS_ERROR_OUT_OF_MEMORY; NS_ADDREF(receiver); - rv = NS_NewThread(&thread, receiver, 0, PR_JOINABLE_THREAD); + rv = NS_NewThread(&thread, receiver, "TestShortWrites"); if (NS_FAILED(rv)) return rv; PRUint32 total = 0; @@ -274,7 +275,7 @@ TestShortWrites(nsIInputStream* in, nsIOutputStream* out) rv = out->Close(); if (NS_FAILED(rv)) return rv; - thread->Join(); + thread->Shutdown(); printf("wrote %d bytes\n", total); NS_RELEASE(thread); @@ -472,7 +473,7 @@ TestChainedPipes() if (pump == nsnull) return NS_ERROR_OUT_OF_MEMORY; NS_ADDREF(pump); - rv = NS_NewThread(&thread, pump, 0, PR_JOINABLE_THREAD); + rv = NS_NewThread(&thread, pump, "TestChainedPipes.pump"); if (NS_FAILED(rv)) return rv; nsIThread* receiverThread; @@ -480,7 +481,7 @@ TestChainedPipes() if (receiver == nsnull) return NS_ERROR_OUT_OF_MEMORY; NS_ADDREF(receiver); - rv = NS_NewThread(&receiverThread, receiver, 0, PR_JOINABLE_THREAD); + rv = NS_NewThread(&receiverThread, receiver, "TestChainedPipes.receiver"); if (NS_FAILED(rv)) return rv; PRUint32 total = 0; @@ -504,8 +505,8 @@ TestChainedPipes() rv = out1->Close(); if (NS_FAILED(rv)) return rv; - thread->Join(); - receiverThread->Join(); + thread->Shutdown(); + receiverThread->Shutdown(); NS_RELEASE(thread); NS_RELEASE(pump); diff --git a/mozilla/xpcom/tests/TestThreadPool.cpp b/mozilla/xpcom/tests/TestThreadPool.cpp new file mode 100644 index 00000000000..4c708e0c54a --- /dev/null +++ b/mozilla/xpcom/tests/TestThreadPool.cpp @@ -0,0 +1,49 @@ +#include +#include "nsXPCOM.h" +#include "nsIThreadPool.h" +#include "nsComponentManagerUtils.h" +#include "nsCOMPtr.h" +#include "nsIRunnable.h" + +class Task : public nsIRunnable +{ +public: + NS_DECL_ISUPPORTS + + Task(int i) : mIndex(i) {} + + NS_IMETHOD Run() + { + printf("###(%d) running from thread: %p\n", mIndex, (void *) PR_GetCurrentThread()); + PR_Sleep(PR_MillisecondsToInterval(50)); + return NS_OK; + } + +private: + int mIndex; +}; +NS_IMPL_THREADSAFE_ISUPPORTS1(Task, nsIRunnable) + +static nsresult +RunTests() +{ + nsCOMPtr pool = do_CreateInstance(NS_THREADPOOL_CONTRACTID); + NS_ENSURE_STATE(pool); + + for (int i = 0; i < 100; ++i) { + nsCOMPtr task = new Task(i); + pool->Dispatch(task, NS_DISPATCH_NORMAL); + } + + pool->Shutdown(); + return NS_OK; +} + +int +main(int argc, char **argv) +{ + NS_InitXPCOM2(nsnull, nsnull, nsnull); + RunTests(); + NS_ShutdownXPCOM(nsnull); + return 0; +} diff --git a/mozilla/xpcom/tests/TestThreads.cpp b/mozilla/xpcom/tests/TestThreads.cpp index 4caac3ae73d..34f0ed74f33 100644 --- a/mozilla/xpcom/tests/TestThreads.cpp +++ b/mozilla/xpcom/tests/TestThreads.cpp @@ -36,8 +36,7 @@ * * ***** END LICENSE BLOCK ***** */ -#include "nsIThread.h" -#include "nsIRunnable.h" +#include "nsThreadUtils.h" #include #include #include "nspr.h" @@ -51,7 +50,7 @@ public: NS_IMETHOD Run() { nsCOMPtr thread; - nsresult rv = nsIThread::GetCurrent(getter_AddRefs(thread)); + nsresult rv = NS_GetCurrentThread(getter_AddRefs(thread)); if (NS_FAILED(rv)) { printf("failed to get current thread\n"); return rv; @@ -79,54 +78,29 @@ TestThreads() { nsresult rv; + nsCOMPtr event = new nsRunner(0); + if (!event) + return NS_ERROR_OUT_OF_MEMORY; + nsCOMPtr runner; - rv = NS_NewThread(getter_AddRefs(runner), new nsRunner(0), 0, PR_JOINABLE_THREAD); + rv = NS_NewThread(getter_AddRefs(runner), event, "TestThreads"); if (NS_FAILED(rv)) { printf("failed to create thread\n"); return rv; } nsCOMPtr thread; - rv = nsIThread::GetCurrent(getter_AddRefs(thread)); + rv = NS_GetCurrentThread(getter_AddRefs(thread)); if (NS_FAILED(rv)) { printf("failed to get current thread\n"); return rv; } - PRThreadScope scope; - rv = runner->GetScope(&scope); - if (NS_FAILED(rv)) { - printf("runner already exited\n"); - } - - rv = runner->Join(); // wait for the runner to die before quitting + rv = runner->Shutdown(); // wait for the runner to die before quitting if (NS_FAILED(rv)) { printf("join failed\n"); } - rv = runner->GetScope(&scope); // this should fail after Join - if (NS_SUCCEEDED(rv)) { - printf("get scope failed\n"); - } - - rv = runner->Interrupt(); // this should fail after Join - if (NS_SUCCEEDED(rv)) { - printf("interrupt failed\n"); - } - - //////////////////////////////////////////////////////////////////////////// - // try an unjoinable thread - rv = NS_NewThread(getter_AddRefs(runner), new nsRunner(1)); - if (NS_FAILED(rv)) { - printf("failed to create thread\n"); - return rv; - } - - rv = runner->Join(); // wait for the runner to die before quitting - if (NS_SUCCEEDED(rv)) { - printf("shouldn't have been able to join an unjoinable thread\n"); - } - PR_Sleep(PR_MillisecondsToInterval(100)); // hopefully the runner will quit here return NS_OK; @@ -181,15 +155,13 @@ static int Stress(int loops, int threads) for (k = 0; k < threads; k++) { nsCOMPtr t; - nsresult rv = NS_NewThread(getter_AddRefs(t), - new nsStressRunner(k), - 0, PR_JOINABLE_THREAD); + nsresult rv = NS_NewThread(getter_AddRefs(t), new nsStressRunner(k)); NS_ASSERTION(NS_SUCCEEDED(rv), "can't create thread"); NS_ADDREF(array[k] = t); } for (k = threads-1; k >= 0; k--) { - array[k]->Join(); + array[k]->Shutdown(); NS_RELEASE(array[k]); } delete [] array; diff --git a/mozilla/xpcom/threads/Makefile.in b/mozilla/xpcom/threads/Makefile.in index 2cb9bc61a04..58ee2976a41 100644 --- a/mozilla/xpcom/threads/Makefile.in +++ b/mozilla/xpcom/threads/Makefile.in @@ -55,37 +55,36 @@ MOZILLA_INTERNAL_API = 1 REQUIRES = string \ $(NULL) -CSRCS = \ - plevent.c \ - $(NULL) - CPPSRCS = \ nsAutoLock.cpp \ - nsEnvironment.cpp \ nsEventQueue.cpp \ - nsEventQueueService.cpp \ + nsEnvironment.cpp \ + nsThreadUtils.cpp \ nsThread.cpp \ - nsTimerImpl.cpp \ + nsThreadManager.cpp \ + nsThreadPool.cpp \ nsProcessCommon.cpp \ + nsTimerImpl.cpp \ TimerThread.cpp \ $(NULL) EXPORTS = \ nsAutoLock.h \ - plevent.h \ nsProcess.h \ - nsEventQueueUtils.h \ + nsThreadUtils.h \ + nsEventQueue.h \ $(NULL) XPIDLSRCS = \ + nsIEventTarget.idl \ nsIThread.idl \ + nsIThreadInternal.idl \ + nsIThreadManager.idl \ + nsIThreadPool.idl \ nsITimer.idl \ nsITimerInternal.idl \ nsITimerManager.idl \ nsIRunnable.idl \ - nsIEventTarget.idl \ - nsIEventQueue.idl \ - nsIEventQueueService.idl \ nsIEnvironment.idl \ nsIProcess.idl \ nsISupportsPriority.idl \ diff --git a/mozilla/xpcom/threads/TimerThread.cpp b/mozilla/xpcom/threads/TimerThread.cpp index 1fc949cb0fb..d438d606b32 100644 --- a/mozilla/xpcom/threads/TimerThread.cpp +++ b/mozilla/xpcom/threads/TimerThread.cpp @@ -42,6 +42,7 @@ #include "TimerThread.h" #include "nsAutoLock.h" +#include "nsThreadUtils.h" #include "pratom.h" #include "nsIObserverService.h" @@ -105,29 +106,19 @@ nsresult TimerThread::Init() if (PR_AtomicSet(&mInitInProgress, 1) == 0) { nsresult rv; + nsCOMPtr observerService + (do_GetService("@mozilla.org/observer-service;1", &rv)); - mEventQueueService = do_GetService("@mozilla.org/event-queue-service;1", &rv); if (NS_SUCCEEDED(rv)) { - nsCOMPtr observerService - (do_GetService("@mozilla.org/observer-service;1", &rv)); - - if (NS_SUCCEEDED(rv)) { - // We hold on to mThread to keep the thread alive. - rv = NS_NewThread(getter_AddRefs(mThread), - NS_STATIC_CAST(nsIRunnable*, this), - 0, - PR_JOINABLE_THREAD, - PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD); - - if (NS_FAILED(rv)) { - mThread = nsnull; - } - else { - // We'll be released at xpcom shutdown - observerService->AddObserver(this, "sleep_notification", PR_FALSE); - observerService->AddObserver(this, "wake_notification", PR_FALSE); - } + // We hold on to mThread to keep the thread alive. + rv = NS_NewThread(getter_AddRefs(mThread), this, "xpcom.timer"); + if (NS_FAILED(rv)) { + mThread = nsnull; + } + else { + // We'll be released at xpcom shutdown + observerService->AddObserver(this, "sleep_notification", PR_FALSE); + observerService->AddObserver(this, "wake_notification", PR_FALSE); } } @@ -171,7 +162,7 @@ nsresult TimerThread::Shutdown() } } - mThread->Join(); // wait for the thread to die + mThread->Shutdown(); // wait for the thread to die return NS_OK; } diff --git a/mozilla/xpcom/threads/TimerThread.h b/mozilla/xpcom/threads/TimerThread.h index 039eea68c5c..367f50aff86 100644 --- a/mozilla/xpcom/threads/TimerThread.h +++ b/mozilla/xpcom/threads/TimerThread.h @@ -41,7 +41,6 @@ #ifndef TimerThread_h___ #define TimerThread_h___ -#include "nsIEventQueueService.h" #include "nsIObserver.h" #include "nsIRunnable.h" #include "nsIThread.h" @@ -78,9 +77,6 @@ public: void UpdateFilter(PRUint32 aDelay, PRIntervalTime aTimeout, PRIntervalTime aNow); - // For use by nsTimerImpl::Fire() - nsCOMPtr mEventQueueService; - void DoBeforeSleep(); void DoAfterSleep(); diff --git a/mozilla/xpcom/threads/nsEventQueue.cpp b/mozilla/xpcom/threads/nsEventQueue.cpp index 66e0bcd28f9..4909e4eb451 100644 --- a/mozilla/xpcom/threads/nsEventQueue.cpp +++ b/mozilla/xpcom/threads/nsEventQueue.cpp @@ -1,4 +1,5 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -12,18 +13,18 @@ * for the specific language governing rights and limitations under the * License. * - * The Original Code is Mozilla Communicator client code. + * The Original Code is Mozilla code. * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 + * The Initial Developer of the Original Code is Google Inc. + * Portions created by the Initial Developer are Copyright (C) 2006 * the Initial Developer. All Rights Reserved. * * Contributor(s): + * Darin Fisher * * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to @@ -35,635 +36,85 @@ * * ***** END LICENSE BLOCK ***** */ -#include "nsCOMPtr.h" #include "nsEventQueue.h" -#include "nsIEventQueueService.h" -#include "nsIThread.h" +#include "nsAutoLock.h" +#include "nsCOMPtr.h" -#include "nsIServiceManager.h" -#include "nsIObserverService.h" - -#include "nsString.h" - -#include "prlog.h" - -#ifdef NS_DEBUG -#include "prprf.h" -#endif - -#if defined(PR_LOGGING) && defined(DEBUG_danm) -/* found these logs useful in conjunction with netlibStreamEvent logging - from netwerk. */ -PRLogModuleInfo* gEventQueueLog = 0; -PRUint32 gEventQueueLogCount = 0; -PRUint32 gEventQueueLogPPCount = 0; -static int gEventQueueLogPPLevel = 0; -static PLEventQueue *gEventQueueLogQueue = 0; -static PRThread *gEventQueueLogThread = 0; -#endif - -// in a real system, these would be members in a header class... -static const char gActivatedNotification[] = "nsIEventQueueActivated"; -static const char gDestroyedNotification[] = "nsIEventQueueDestroyed"; - -nsEventQueueImpl::nsEventQueueImpl() +nsEventQueue::nsEventQueue() + : mMonitor(nsAutoMonitor::NewMonitor("xpcom.eventqueue")) + , mHead(nsnull) + , mTail(nsnull) + , mOffsetHead(0) + , mOffsetTail(0) { - NS_ADDREF_THIS(); - /* The slightly weird ownership model for eventqueues goes like this: - - General: - There's an addref from the factory generally held by whoever asked for - the queue. The queue addrefs itself (right here) and releases itself - after someone calls StopAcceptingEvents() on the queue and when it is - dark and empty (in CheckForDeactivation()). - - Chained queues: - - Eldest queue: - The eldest queue in a chain is held on to by the EventQueueService - in a hash table, so it is possible that the eldest queue may not be - released until the EventQueueService is shutdown. - You may not call StopAcceptingEvents() on this queue until you have - done so on all younger queues. - - General: - Each queue holds a reference to their immediate elder link and a weak - reference to their immediate younger link. Because you must shut down - queues from youngest to eldest, all the references will be removed. - - It happens something like: - queue->StopAcceptingEvents() - { - CheckForDeactivation() - { - -- hopefully we are able to shutdown now -- - Unlink() - { - -- remove the reference we hold to our elder queue -- - -- NULL out our elder queues weak reference to us -- - } - RELEASE ourself (to balance the ADDREF here in the constructor) - -- and we should go away. -- - } - } - - - Notes: - A dark queue no longer accepts events. An empty queue simply has no events. - */ - -#if defined(PR_LOGGING) && defined(DEBUG_danm) - PR_LOG(gEventQueueLog, PR_LOG_DEBUG, - ("EventQueue: Created [queue=%lx]",(long)mEventQueue)); - ++gEventQueueLogCount; -#endif - - mYoungerQueue = nsnull; - mEventQueue = nsnull; - mAcceptingEvents = PR_TRUE; - mCouldHaveEvents = PR_TRUE; } -nsEventQueueImpl::~nsEventQueueImpl() +nsEventQueue::~nsEventQueue() { - Unlink(); + nsAutoMonitor::DestroyMonitor(mMonitor); +} -#if defined(PR_LOGGING) && defined(DEBUG_danm) - PR_LOG(gEventQueueLog, PR_LOG_DEBUG, - ("EventQueue: Destroyed [queue=%lx]",(long)mEventQueue)); - ++gEventQueueLogCount; -#endif +PRBool +nsEventQueue::GetEvent(PRBool mayWait, nsIRunnable **result) +{ + nsAutoMonitor mon(mMonitor); - if (mEventQueue) { - // Perhaps CheckForDeactivation wasn't called... - if (mCouldHaveEvents) - NotifyObservers(gDestroyedNotification); - PL_DestroyEventQueue(mEventQueue); + while (IsEmpty()) { + if (!mayWait) { + if (result) + *result = nsnull; + return PR_FALSE; + } + mon.Wait(); } + + if (result) + *result = mHead->mEvents[mOffsetHead++]; + + // Check if mHead points to empty Page + if (mOffsetHead == EVENTS_PER_PAGE) { + Page *dead = mHead; + mHead = mHead->mNext; + FreePage(dead); + mOffsetHead = 0; + } + + return PR_TRUE; } -NS_IMETHODIMP -nsEventQueueImpl::Init(PRBool aNative) +PRBool +nsEventQueue::PutEvent(nsIRunnable *runnable) { - PRThread *thread = PR_GetCurrentThread(); - if (aNative) - mEventQueue = PL_CreateNativeEventQueue("Thread event queue...", thread); - else - mEventQueue = PL_CreateMonitoredEventQueue("Thread event queue...", thread); - if (!mEventQueue) - return NS_ERROR_FAILURE; - NotifyObservers(gActivatedNotification); - return NS_OK; -} - -NS_IMETHODIMP -nsEventQueueImpl::InitFromPRThread(PRThread* thread, PRBool aNative) -{ - if (thread == NS_CURRENT_THREAD) + // Avoid calling AddRef+Release while holding our monitor. + nsCOMPtr event(runnable); + PRBool rv = PR_TRUE; { - thread = PR_GetCurrentThread(); - } - else if (thread == NS_UI_THREAD) - { - nsCOMPtr mainIThread; - nsresult rv; + nsAutoMonitor mon(mMonitor); - // Get the primordial thread - rv = nsIThread::GetMainThread(getter_AddRefs(mainIThread)); - if (NS_FAILED(rv)) return rv; - - rv = mainIThread->GetPRThread(&thread); - if (NS_FAILED(rv)) return rv; - } - - if (aNative) - mEventQueue = PL_CreateNativeEventQueue("Thread event queue...", thread); - else - mEventQueue = PL_CreateMonitoredEventQueue("Thread event queue...", thread); - if (!mEventQueue) - return NS_ERROR_FAILURE; - - NotifyObservers(gActivatedNotification); - return NS_OK; -} - -NS_IMETHODIMP -nsEventQueueImpl::InitFromPLQueue(PLEventQueue* aQueue) -{ - mEventQueue = aQueue; - NotifyObservers(gActivatedNotification); - return NS_OK; -} - -/* nsISupports interface implementation... */ -NS_IMPL_THREADSAFE_ISUPPORTS3(nsEventQueueImpl, - nsIEventQueue, - nsIEventTarget, - nsPIEventQueueChain) - -/* nsIEventQueue interface implementation... */ - -NS_IMETHODIMP -nsEventQueueImpl::StopAcceptingEvents() -{ - if (mYoungerQueue) { - NS_ERROR("Should not shut down eventq while child queues are active"); - mYoungerQueue->StopAcceptingEvents(); - } - - // XXXThis method can be called from any thread: do we need to protect this - // with a lock? - mAcceptingEvents = PR_FALSE; - CheckForDeactivation(); -#if defined(PR_LOGGING) && defined(DEBUG_danm) - PR_LOG(gEventQueueLog, PR_LOG_DEBUG, - ("EventQueue: StopAccepting [queue=%lx, accept=%d, could=%d]", - (long)mEventQueue,(int)mAcceptingEvents,(int)mCouldHaveEvents)); - ++gEventQueueLogCount; -#endif - return NS_OK; -} - -// utility funtion to send observers a notification -void -nsEventQueueImpl::NotifyObservers(const char *aTopic) -{ - // only send out this notification for native event queues - if (!PL_IsQueueNative(mEventQueue)) - return; - - // we should not call out to the observer service from background threads! - NS_ASSERTION(nsIThread::IsMainThread(), - "Native event queues should only be used on the main thread"); - - nsresult rv; - nsCOMPtr os = do_GetService("@mozilla.org/observer-service;1", &rv); - if (NS_SUCCEEDED(rv)) { - nsCOMPtr kungFuDeathGrip(this); - nsCOMPtr us(do_QueryInterface(kungFuDeathGrip)); - os->NotifyObservers(us, aTopic, NULL); - } -} - -void -nsEventQueueImpl::CheckForDeactivation() -{ - if (mCouldHaveEvents && !mAcceptingEvents && !PL_EventAvailable(mEventQueue)) { - if (PL_IsQueueOnCurrentThread(mEventQueue)) { - mCouldHaveEvents = PR_FALSE; - NotifyObservers(gDestroyedNotification); - NS_RELEASE_THIS(); // balance ADDREF from the constructor - } else - NS_ERROR("CheckForDeactivation called from wrong thread!"); - } -} - - -NS_IMETHODIMP -nsEventQueueImpl::InitEvent(PLEvent* aEvent, - void* owner, - PLHandleEventProc handler, - PLDestroyEventProc destructor) -{ - PL_InitEvent(aEvent, owner, handler, destructor); - return NS_OK; -} - - -NS_IMETHODIMP -nsEventQueueImpl::PostEvent(PLEvent* aEvent) -{ - if (!mAcceptingEvents) { -#if defined(PR_LOGGING) && defined(DEBUG_danm) - PR_LOG(gEventQueueLog, PR_LOG_DEBUG, - ("EventQueue: Punt posted event [queue=%lx, accept=%d, could=%d]", - (long)mEventQueue,(int)mAcceptingEvents,(int)mCouldHaveEvents)); - ++gEventQueueLogCount; -#endif - nsresult rv = NS_ERROR_FAILURE; - NS_ASSERTION(mElderQueue, "event dropped because event chain is dead"); - if (mElderQueue) { - nsCOMPtr elder(do_QueryInterface(mElderQueue)); - if (elder) - rv = elder->PostEvent(aEvent); + if (!mHead) { + mHead = NewPage(); + if (!mHead) { + rv = PR_FALSE; + } else { + mTail = mHead; + mOffsetHead = 0; + mOffsetTail = 0; + } + } else if (mOffsetTail == EVENTS_PER_PAGE) { + Page *page = NewPage(); + if (!page) { + rv = PR_FALSE; + } else { + mTail->mNext = page; + mTail = page; + mOffsetTail = 0; + } } - return rv; - } -#if defined(PR_LOGGING) && defined(DEBUG_danm) - PR_LOG(gEventQueueLog, PR_LOG_DEBUG, - ("EventQueue: Posting event [queue=%lx]", (long)mEventQueue)); - ++gEventQueueLogCount; -#endif - return PL_PostEvent(mEventQueue, aEvent) == PR_SUCCESS ? NS_OK : NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -nsEventQueueImpl::PostSynchronousEvent(PLEvent* aEvent, void** aResult) -{ - if (!mAcceptingEvents) { -#if defined(PR_LOGGING) && defined(DEBUG_danm) - PR_LOG(gEventQueueLog, PR_LOG_DEBUG, - ("EventQueue: Punt posted synchronous event [queue=%lx, accept=%d, could=%d]", - (long)mEventQueue,(int)mAcceptingEvents,(int)mCouldHaveEvents)); - ++gEventQueueLogCount; -#endif - nsresult rv = NS_ERROR_NO_INTERFACE; - NS_ASSERTION(mElderQueue, "event dropped because event chain is dead"); - if (mElderQueue) { - nsCOMPtr elder(do_QueryInterface(mElderQueue)); - if (elder) - rv = elder->PostSynchronousEvent(aEvent, aResult); - return rv; + if (rv) { + event.swap(mTail->mEvents[mOffsetTail]); + ++mOffsetTail; + mon.NotifyAll(); } - return NS_ERROR_ABORT; - } - -#if defined(PR_LOGGING) && defined(DEBUG_danm) - PR_LOG(gEventQueueLog, PR_LOG_DEBUG, - ("EventQueue: Posting synchronous event [queue=%lx]", (long)mEventQueue)); - ++gEventQueueLogCount; -#endif - void* result = PL_PostSynchronousEvent(mEventQueue, aEvent); - if (aResult) - *aResult = result; - - return NS_OK; -} - -NS_IMETHODIMP -nsEventQueueImpl::EnterMonitor() -{ - PL_ENTER_EVENT_QUEUE_MONITOR(mEventQueue); - return NS_OK; -} - -NS_IMETHODIMP -nsEventQueueImpl::ExitMonitor() -{ - PL_EXIT_EVENT_QUEUE_MONITOR(mEventQueue); - return NS_OK; -} - - -NS_IMETHODIMP -nsEventQueueImpl::RevokeEvents(void* owner) -{ - nsCOMPtr youngest; - GetYoungest(getter_AddRefs(youngest)); - NS_ASSERTION(youngest, "How could we possibly not have a youngest queue?"); - nsCOMPtr youngestAsChain(do_QueryInterface(youngest)); - NS_ASSERTION(youngestAsChain, "RevokeEvents won't work; expect crashes"); - return youngestAsChain->RevokeEventsInternal(owner); -} - - -NS_IMETHODIMP -nsEventQueueImpl::GetPLEventQueue(PLEventQueue** aEventQueue) -{ - if (!mEventQueue) - return NS_ERROR_NULL_POINTER; - - *aEventQueue = mEventQueue; - return NS_OK; -} - -NS_IMETHODIMP -nsEventQueueImpl::IsOnCurrentThread(PRBool *aResult) -{ - *aResult = PL_IsQueueOnCurrentThread( mEventQueue ); - return NS_OK; -} - - -NS_IMETHODIMP -nsEventQueueImpl::IsQueueNative(PRBool *aResult) -{ - *aResult = PL_IsQueueNative(mEventQueue); - return NS_OK; -} - -NS_IMETHODIMP -nsEventQueueImpl::PendingEvents(PRBool *aResult) -{ - *aResult = PL_EventAvailable(mEventQueue); - if (!*aResult && mElderQueue) { - nsCOMPtr elder(do_QueryInterface(mElderQueue)); - if (elder) - return elder->EventAvailable(*aResult); - } - return NS_OK; -} - - -NS_IMETHODIMP -nsEventQueueImpl::ProcessPendingEvents() -{ - PRBool correctThread = PL_IsQueueOnCurrentThread(mEventQueue); - - NS_ASSERTION(correctThread, "attemping to process events on the wrong thread"); - - if (!correctThread) - return NS_ERROR_FAILURE; -#if defined(PR_LOGGING) && defined(DEBUG_danm) - ++gEventQueueLogPPLevel; - if ((gEventQueueLogQueue != mEventQueue || gEventQueueLogThread != PR_GetCurrentThread() || - gEventQueueLogCount != gEventQueueLogPPCount) && gEventQueueLogPPLevel == 1) { - PR_LOG(gEventQueueLog, PR_LOG_DEBUG, - ("EventQueue: Process pending [queue=%lx, accept=%d, could=%d]", - (long)mEventQueue,(int)mAcceptingEvents,(int)mCouldHaveEvents)); - gEventQueueLogPPCount = ++gEventQueueLogCount; - gEventQueueLogQueue = mEventQueue; - gEventQueueLogThread = PR_GetCurrentThread(); - } -#endif - PL_ProcessPendingEvents(mEventQueue); - - // if we're no longer accepting events and there are still events in the - // queue, then process remaining events. - if (!mAcceptingEvents && PL_EventAvailable(mEventQueue)) - PL_ProcessPendingEvents(mEventQueue); - - CheckForDeactivation(); - - if (mElderQueue) { - nsCOMPtr elder(do_QueryInterface(mElderQueue)); - if (elder) - elder->ProcessPendingEvents(); - } -#if defined(PR_LOGGING) && defined(DEBUG_danm) - --gEventQueueLogPPLevel; -#endif - return NS_OK; -} - -NS_IMETHODIMP -nsEventQueueImpl::EventLoop() -{ - PRBool correctThread = PL_IsQueueOnCurrentThread(mEventQueue); - - NS_ASSERTION(correctThread, "attemping to process events on the wrong thread"); - - if (!correctThread) - return NS_ERROR_FAILURE; - - PL_EventLoop(mEventQueue); - return NS_OK; -} - -NS_IMETHODIMP -nsEventQueueImpl::EventAvailable(PRBool& aResult) -{ - aResult = PL_EventAvailable(mEventQueue); - return NS_OK; -} - -NS_IMETHODIMP -nsEventQueueImpl::GetEvent(PLEvent** aResult) -{ - *aResult = PL_GetEvent(mEventQueue); - CheckForDeactivation(); - return NS_OK; -} - -NS_IMETHODIMP -nsEventQueueImpl::HandleEvent(PLEvent* aEvent) -{ - PRBool correctThread = PL_IsQueueOnCurrentThread(mEventQueue); - NS_ASSERTION(correctThread, "attemping to process events on the wrong thread"); - if (!correctThread) - return NS_ERROR_FAILURE; - -#if defined(PR_LOGGING) && defined(DEBUG_danm) - PR_LOG(gEventQueueLog, PR_LOG_DEBUG, - ("EventQueue: handle event [queue=%lx, accept=%d, could=%d]", - (long)mEventQueue,(int)mAcceptingEvents,(int)mCouldHaveEvents)); - ++gEventQueueLogCount; -#endif - PL_HandleEvent(aEvent); - return NS_OK; -} - -NS_IMETHODIMP -nsEventQueueImpl::WaitForEvent(PLEvent** aResult) -{ - PRBool correctThread = PL_IsQueueOnCurrentThread(mEventQueue); - NS_ASSERTION(correctThread, "attemping to process events on the wrong thread"); - if (!correctThread) - return NS_ERROR_FAILURE; - -#if defined(PR_LOGGING) && defined(DEBUG_danm) -PR_LOG(gEventQueueLog, PR_LOG_DEBUG, - ("EventQueue: wait for event [queue=%lx, accept=%d, could=%d]", - (long)mEventQueue,(int)mAcceptingEvents,(int)mCouldHaveEvents)); -++gEventQueueLogCount; -#endif - *aResult = PL_WaitForEvent(mEventQueue); - CheckForDeactivation(); - return NS_OK; -} - -NS_IMETHODIMP_(PRInt32) -nsEventQueueImpl::GetEventQueueSelectFD() -{ - return PL_GetEventQueueSelectFD(mEventQueue); -} - -NS_METHOD -nsEventQueueImpl::Create(nsISupports *aOuter, - REFNSIID aIID, - void **aResult) -{ - nsEventQueueImpl* evt = new nsEventQueueImpl(); - if (evt == NULL) - return NS_ERROR_OUT_OF_MEMORY; - nsresult rv = evt->QueryInterface(aIID, aResult); - if (NS_FAILED(rv)) { - delete evt; } return rv; } - -// ---------------- nsPIEventQueueChain ----------------- - -NS_IMETHODIMP -nsEventQueueImpl::AppendQueue(nsIEventQueue *aQueue) -{ - nsresult rv; - nsCOMPtr end; - nsCOMPtr queueChain(do_QueryInterface(aQueue)); - - if (!aQueue) - return NS_ERROR_NO_INTERFACE; - -/* this would be nice - NS_ASSERTION(aQueue->mYoungerQueue == NULL && aQueue->mElderQueue == NULL, - "event queue repeatedly appended to queue chain"); -*/ - rv = NS_ERROR_NO_INTERFACE; - -#ifdef NS_DEBUG - int depth = 0; - nsEventQueueImpl *next = this; - while (next && depth < 100) { - next = NS_STATIC_CAST(nsEventQueueImpl *, next->mYoungerQueue); - ++depth; - } - if (depth > 5) { - char warning[80]; - PR_snprintf(warning, sizeof(warning), - "event queue chain length is %d. this is almost certainly a leak.", depth); - NS_WARNING(warning); - } -#endif - - // (be careful doing this outside nsEventQueueService's mEventQMonitor) - - GetYoungest(getter_AddRefs(end)); - nsCOMPtr endChain(do_QueryInterface(end)); - if (endChain) { - endChain->SetYounger(queueChain); - queueChain->SetElder(endChain); - rv = NS_OK; - } - return rv; -} - -NS_IMETHODIMP -nsEventQueueImpl::Unlink() -{ - nsCOMPtr young = mYoungerQueue, - old = mElderQueue; - -#if defined(PR_LOGGING) && defined(DEBUG_danm) - PR_LOG(gEventQueueLog, PR_LOG_DEBUG, - ("EventQueue: unlink [queue=%lx, younger=%lx, elder=%lx]", - (long)mEventQueue,(long)mYoungerQueue, (long)mElderQueue.get())); - ++gEventQueueLogCount; -#endif - - // this is probably OK, but shouldn't happen by design, so tell me if it does - NS_ASSERTION(!mYoungerQueue, "event queue chain broken in middle"); - - // break links early in case the Release cascades back onto us - mYoungerQueue = nsnull; - mElderQueue = nsnull; - - if (young) - young->SetElder(old); - if (old) { - old->SetYounger(young); - } - return NS_OK; -} - -NS_IMETHODIMP -nsEventQueueImpl::GetYoungest(nsIEventQueue **aQueue) -{ - if (mYoungerQueue) - return mYoungerQueue->GetYoungest(aQueue); - - nsIEventQueue *answer = NS_STATIC_CAST(nsIEventQueue *, this); - NS_ADDREF(answer); - *aQueue = answer; - return NS_OK; -} - -NS_IMETHODIMP -nsEventQueueImpl::GetYoungestActive(nsIEventQueue **aQueue) -{ - nsCOMPtr answer; - - if (mYoungerQueue) - mYoungerQueue->GetYoungestActive(getter_AddRefs(answer)); - if (!answer) { - if (mAcceptingEvents && mCouldHaveEvents) - answer = NS_STATIC_CAST(nsIEventQueue *, this); - } - *aQueue = answer; - NS_IF_ADDREF(*aQueue); - return NS_OK; -} - -NS_IMETHODIMP -nsEventQueueImpl::SetYounger(nsPIEventQueueChain *aQueue) -{ - mYoungerQueue = aQueue; - return NS_OK; -} - -NS_IMETHODIMP -nsEventQueueImpl::SetElder(nsPIEventQueueChain *aQueue) -{ - mElderQueue = aQueue; - return NS_OK; -} - -NS_IMETHODIMP -nsEventQueueImpl::GetYounger(nsIEventQueue **aQueue) -{ - if (!mYoungerQueue) { - *aQueue = nsnull; - return NS_OK; - } - return mYoungerQueue->QueryInterface(NS_GET_IID(nsIEventQueue), (void**)&aQueue); -} - -NS_IMETHODIMP -nsEventQueueImpl::GetElder(nsIEventQueue **aQueue) -{ - if (!mElderQueue) { - *aQueue = nsnull; - return NS_OK; - } - return mElderQueue->QueryInterface(NS_GET_IID(nsIEventQueue), (void**)&aQueue); -} - -NS_IMETHODIMP -nsEventQueueImpl::RevokeEventsInternal(void* aOwner) -{ - PL_RevokeEvents(mEventQueue, aOwner); - if (mElderQueue) { - mElderQueue->RevokeEventsInternal(aOwner); - } - return NS_OK; -} diff --git a/mozilla/xpcom/threads/nsEventQueue.h b/mozilla/xpcom/threads/nsEventQueue.h index 8cffe436667..329eb850764 100644 --- a/mozilla/xpcom/threads/nsEventQueue.h +++ b/mozilla/xpcom/threads/nsEventQueue.h @@ -1,4 +1,5 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -12,19 +13,18 @@ * for the specific language governing rights and limitations under the * License. * - * The Original Code is Mozilla Communicator client code. + * The Original Code is Mozilla code. * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 + * The Initial Developer of the Original Code is Google Inc. + * Portions created by the Initial Developer are Copyright (C) 2006 * the Initial Developer. All Rights Reserved. * * Contributor(s): - * Pierre Phaneuf + * Darin Fisher * * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to @@ -36,44 +36,79 @@ * * ***** END LICENSE BLOCK ***** */ -#include "prmon.h" -#include "nsIEventQueue.h" -#include "nsPIEventQueueChain.h" +#ifndef nsEventQueue_h__ +#define nsEventQueue_h__ -class nsEventQueueImpl : public nsPIEventQueueChain +#include +#include "prmon.h" +#include "nsIRunnable.h" + +// A threadsafe FIFO event queue... +class NS_COM nsEventQueue { public: - nsEventQueueImpl(); + nsEventQueue(); + ~nsEventQueue(); - NS_DECL_ISUPPORTS - NS_DECL_NSIEVENTTARGET - NS_DECL_NSIEVENTQUEUE + // This method adds a new event on the pending event queue. + PRBool PutEvent(nsIRunnable *runnable); - // Helpers - static NS_METHOD Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr); + // This method gets an event from the event queue. If mayWait is true, then + // the method will block the calling thread until an event is available. If + // runnable is null, then the method returns immediately indicating whether + // or not an event is pending. + PRBool GetEvent(PRBool mayWait, nsIRunnable **runnable); - static const nsCID& CID() { static nsCID cid = NS_EVENTQUEUE_CID; return cid; } + // This method returns true if there is a pending event. + PRBool HasPendingEvent() { + return GetEvent(PR_FALSE, nsnull); + } - // nsPIEventQueueChain interface - NS_IMETHOD AppendQueue(nsIEventQueue *aQueue); - NS_IMETHOD Unlink(); - NS_IMETHOD GetYoungest(nsIEventQueue **aQueue); - NS_IMETHOD GetYoungestActive(nsIEventQueue **aQueue); - NS_IMETHOD SetYounger(nsPIEventQueueChain *aQueue); - NS_IMETHOD GetYounger(nsIEventQueue **aQueue); - NS_IMETHOD SetElder(nsPIEventQueueChain *aQueue); - NS_IMETHOD GetElder(nsIEventQueue **aQueue); - NS_IMETHOD RevokeEventsInternal(void* aOwner); + // This method returns the next pending event or null. + PRBool GetPendingEvent(nsIRunnable **runnable) { + return GetEvent(PR_FALSE, runnable); + } + + // This method waits for and returns the next pending event. + PRBool WaitPendingEvent(nsIRunnable **runnable) { + return GetEvent(PR_TRUE, runnable); + } + + // Expose the event queue's monitor for "power users" + PRMonitor *Monitor() { + return mMonitor; + } private: - ~nsEventQueueImpl(); - PLEventQueue *mEventQueue; - PRBool mAcceptingEvents, // accept new events or pass them on? - mCouldHaveEvents; // accepting new ones, or still have old ones? - nsCOMPtr mElderQueue; // younger can hold on to elder - nsPIEventQueueChain *mYoungerQueue; // but elder can't hold on to younger + PRBool IsEmpty() { + return !mHead || (mHead == mTail && mOffsetHead == mOffsetTail); + } - void NotifyObservers(const char *aTopic); - void CheckForDeactivation(); + enum { EVENTS_PER_PAGE = 15 }; + + struct Page { + struct Page *mNext; + nsIRunnable *mEvents[EVENTS_PER_PAGE]; + + Page() : mNext(nsnull) {} + }; + + static Page *NewPage() { + return NS_STATIC_CAST(Page *, calloc(1, sizeof(Page))); + } + + static void FreePage(Page *p) { + free(p); + } + + PRMonitor *mMonitor; + + Page *mHead; + Page *mTail; + + PRUint16 mOffsetHead; // offset into mHead where next item is removed + PRUint16 mOffsetTail; // offset into mTail where next item is added }; + +#endif // nsEventQueue_h__ diff --git a/mozilla/xpcom/threads/nsIEventTarget.idl b/mozilla/xpcom/threads/nsIEventTarget.idl index 3b19d9ca0a7..fc856a70f0a 100644 --- a/mozilla/xpcom/threads/nsIEventTarget.idl +++ b/mozilla/xpcom/threads/nsIEventTarget.idl @@ -1,3 +1,5 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -11,14 +13,14 @@ * for the specific language governing rights and limitations under the * License. * - * The Original Code is Mozilla. + * The Original Code is Mozilla code. * - * The Initial Developer of the Original Code is IBM Corporation. - * Portions created by IBM Corporation are Copyright (C) 2003 - * IBM Corporation. All Rights Reserved. + * The Initial Developer of the Original Code is Google Inc. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. * * Contributor(s): - * IBM Corp. + * Darin Fisher * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -36,32 +38,35 @@ #include "nsISupports.idl" -%{C++ -#include "plevent.h" -%} +interface nsIRunnable; -[ptr] native PLEventPtr(PLEvent); - -/** - * nsIEventTarget - * - * This interface is used to dispatch events to a particular thread. In many - * cases the event target also supports nsIEventQueue. - */ -[scriptable, uuid(ea99ad5b-cc67-4efb-97c9-2ef620a59f2a)] +[scriptable, uuid(4e8febe4-6631-49dc-8ac9-308c1cb9b09c)] interface nsIEventTarget : nsISupports { - /** - * Method for posting an asynchronous event to the event target. If this - * method succeeds, then the event will be dispatched on the target thread. - * - * @param aEvent - * The event to dispatched. - */ - [noscript] void postEvent(in PLEventPtr aEvent); - - /** - * This method returns true if the event target is the current thread. - */ - boolean isOnCurrentThread(); + /** + * Dispatch an event to the event target. This function may be called from + * any thread. If flags specifies DISPATCH_SYNC, then the dispatch method + * will not return until the event has been run. + * + * NOTE: Calling dispatch with DISPATCH_SYNC may have the side-effect of + * processing other events on the current thread while waiting for the given + * event to be processed. This method is thread-safe and re-entrant. + * + * @throws NS_ERROR_INVALID_ARG if event is null. + */ + void dispatch(in nsIRunnable event, in unsigned long flags); + const unsigned long DISPATCH_NORMAL = 0; + const unsigned long DISPATCH_SYNC = 1; + + /** + * Returns true if events dispatched to this event target will run on the + * current thread (i.e., the thread calling this method). + */ + boolean isOnCurrentThread(); }; + +%{C++ +// convenient aliases: +#define NS_DISPATCH_NORMAL nsIEventTarget::DISPATCH_NORMAL +#define NS_DISPATCH_SYNC nsIEventTarget::DISPATCH_SYNC +%} diff --git a/mozilla/xpcom/threads/nsIThread.idl b/mozilla/xpcom/threads/nsIThread.idl index f28d6ec942b..fca129e54af 100644 --- a/mozilla/xpcom/threads/nsIThread.idl +++ b/mozilla/xpcom/threads/nsIThread.idl @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -12,18 +13,18 @@ * for the specific language governing rights and limitations under the * License. * - * The Original Code is mozilla.org code. + * The Original Code is Mozilla code. * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 + * The Initial Developer of the Original Code is Google Inc. + * Portions created by the Initial Developer are Copyright (C) 2006 * the Initial Developer. All Rights Reserved. * * Contributor(s): + * Darin Fisher * * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to @@ -35,110 +36,42 @@ * * ***** END LICENSE BLOCK ***** */ -#include "nsISupports.idl" - -%{C++ -#include "prthread.h" - -#define NS_THREAD_CID \ -{ /* 85CE5510-7808-11d3-A181-0050041CAF44 */ \ - 0x85ce5510, \ - 0x7808, \ - 0x11d3, \ - {0xa1, 0x81, 0x00, 0x50, 0x04, 0x1c, 0xaf, 0x44} \ -} - -#define NS_THREAD_CONTRACTID "@mozilla.org/thread;1" -#define NS_THREAD_CLASSNAME "Thread" -#if 0 -%} - -typedef PRUint32 PRThreadPriority; -typedef PRUint32 PRThreadScope; -typedef PRUint32 PRThreadState; - -%{C++ -#endif -%} - -interface nsIRunnable; +#include "nsIEventTarget.idl" [ptr] native PRThread(PRThread); -[scriptable, uuid(6be5e380-6886-11d3-9382-00104ba0fd40)] -interface nsIThread : nsISupports +[scriptable, uuid(9c889946-a73a-4af3-ae9a-ea64f7d4e3ca)] +interface nsIThread : nsIEventTarget { - // These must all match the values used in prthread.h - const PRUint32 PRIORITY_LOW = 0; - const PRUint32 PRIORITY_NORMAL = 1; - const PRUint32 PRIORITY_HIGH = 2; - const PRUint32 PRIORITY_URGENT = 3; + /** + * Returns the name of the thread, which may be empty if this thread is + * anonymous. + */ + readonly attribute ACString name; - const PRUint32 SCOPE_LOCAL = 0; - const PRUint32 SCOPE_GLOBAL = 1; - const PRUint32 SCOPE_BOUND = 2; + /** + * Returns the NSPR thread object corresponding to this nsIThread. + */ + [noscript] PRThread getPRThread(); - const PRUint32 STATE_JOINABLE = 0; - const PRUint32 STATE_UNJOINABLE = 1; + /** + * Shutdown the thread. This method may not be executed from the thread + * itself. Instead, it is meant to be executed from another thread (usually + * the thread that created this thread). When this function returns, the + * thread will be shutdown, and it will no longer be possible to dispatch + * tasks to the thread. + */ + void shutdown(); - void join(); - void interrupt(); + /** + * Returns true if this thread has one or more pending events. + */ + boolean hasPendingEvents(); - attribute PRThreadPriority priority; - readonly attribute PRThreadScope scope; - readonly attribute PRThreadState state; - - [noscript] PRThread GetPRThread(); - - void init(in nsIRunnable aRunnable, - in PRUint32 aStackSize, - in PRThreadPriority aPriority, - in PRThreadScope aScope, - in PRThreadState aState); - - /* - * Get the currently running thread (really a static method sort of thing). - */ - readonly attribute nsIThread currentThread; - - /* - * Sleep to at least this many milliseconds (only works on currrent thread). - */ - void sleep(in PRUint32 msec); - -%{C++ - // returns the nsIThread for the current thread: - static NS_COM nsresult GetCurrent(nsIThread* *result); - - // returns the nsIThread for an arbitrary PRThread: - static NS_COM nsresult GetIThread(PRThread* prthread, nsIThread* *result); - - // initializes the "main" thread (really, just saves the current thread - // at time of calling. meant to be called once at app startup, in lieu - // of proper static initializers, to save the primordial thread - // for later recall.) - static NS_COM nsresult SetMainThread(); - - // return the "main" thread - static NS_COM nsresult GetMainThread(nsIThread **result); - - static NS_COM PRBool IsMainThread(); -%} + /** + * Process the next event. If there are no pending events, then this method + * will wait until an event is dispatched to this thread. This method is + * re-entrant but may only be called if this thread is the current thread. + */ + void processNextEvent(); }; - -%{C++ -extern NS_COM nsresult -NS_NewThread(nsIThread* *result, - nsIRunnable* runnable, - PRUint32 stackSize = 0, - PRThreadState state = PR_UNJOINABLE_THREAD, - PRThreadPriority priority = PR_PRIORITY_NORMAL, - PRThreadScope scope = PR_GLOBAL_THREAD); - -extern NS_COM nsresult -NS_NewThread(nsIThread* *result, - PRUint32 stackSize = 0, - PRThreadState state = PR_UNJOINABLE_THREAD, - PRThreadPriority priority = PR_PRIORITY_NORMAL, - PRThreadScope scope = PR_GLOBAL_THREAD); -%} diff --git a/mozilla/xpcom/threads/nsIThreadManager.idl b/mozilla/xpcom/threads/nsIThreadManager.idl new file mode 100644 index 00000000000..31501eb0124 --- /dev/null +++ b/mozilla/xpcom/threads/nsIThreadManager.idl @@ -0,0 +1,97 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla code. + * + * The Initial Developer of the Original Code is Google Inc. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Darin Fisher + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" + +[ptr] native PRThread(PRThread); + +interface nsIThread; + +[scriptable, uuid(056216f5-8803-46b4-9199-d95bc1f0446f)] +interface nsIThreadManager : nsISupports +{ + /** + * Create a new named thread (a global, user PRThread). If the name is + * non-empty, then the name of the thread must be unique. Specifying an + * empty name results in an anonymous thread that cannot be found later on + * using the getThread method. + */ + nsIThread newThread(in ACString name); + + /** + * Find a named thread. If no thread exists with the given name, then null + * is returned. + */ + nsIThread getThread(in ACString name); + + /** + * Get the nsIThread object (if any) corresponding to the given PRThread. + * This method returns null if there is no corresponding nsIThread. + */ + [noscript] nsIThread getThreadFromPRThread(in PRThread thread); + + /** + * Get the main thread. + */ + readonly attribute nsIThread mainThread; + + /** + * Get the current thread. + */ + readonly attribute nsIThread currentThread; + + /** + * This attribute is true if the calling thread is the main thread of the + * application process. + */ + readonly attribute boolean isMainThread; + + /** + * Set an external nsIThread instance (or null) as the nsIThread for the + * current thread. If a nsIThread is already associated with the calling + * thread, then this function will replace it with the given nsIThread. If + * the given nsIThread is non-null, then its name attribute must be unique. + * Its name may be equal to the name of the nsIThread being replaced. This + * method returns the nsIThread that was replaced by this method call or null + * if there was no previous nsIThread associated with the current thread. + * + * XXX We might want something else here. This allows the current nsIThread + * to change, and that may freak out some consumers. + */ + // XXX nsIThread setCurrentThread(in nsIThread thread); +}; diff --git a/mozilla/xpcom/threads/nsIThreadPool.idl b/mozilla/xpcom/threads/nsIThreadPool.idl new file mode 100644 index 00000000000..e0fc0ce086f --- /dev/null +++ b/mozilla/xpcom/threads/nsIThreadPool.idl @@ -0,0 +1,73 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla code. + * + * The Initial Developer of the Original Code is Google Inc. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Darin Fisher + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsIEventTarget.idl" + +/** + * An interface to a thread pool. A thread pool creates a limited number of + * anonymous (unnamed) worker threads. An event dispatched to the thread pool + * will be run on the next available worker thread. + */ +[scriptable, uuid(394c29f0-225f-487f-86d3-4c259da76cab)] +interface nsIThreadPool : nsIEventTarget +{ + /** + * Shutdown the thread pool. This method may not be executed from any thread + * in the thread pool. Instead, it is meant to be executed from another + * thread (usually the thread that created this thread pool). When this + * function returns, the thread pool and all of its threads will be shutdown, + * and it will no longer be possible to dispatch tasks to the thread pool. + */ + void shutdown(); + + /** + * Get/set the maximum number of threads allowed at one time in this pool. + */ + attribute unsigned long threadLimit; + + /** + * Get/set the maximum number of idle threads kept alive. + */ + attribute unsigned long idleThreadLimit; + + /** + * Get/set the amount of time in milliseconds before an idle thread is + * destroyed. + */ + attribute unsigned long idleThreadTimeout; +}; diff --git a/mozilla/xpcom/threads/nsThread.cpp b/mozilla/xpcom/threads/nsThread.cpp index 46c923d9298..87cf1b9f05a 100644 --- a/mozilla/xpcom/threads/nsThread.cpp +++ b/mozilla/xpcom/threads/nsThread.cpp @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -12,18 +13,18 @@ * for the specific language governing rights and limitations under the * License. * - * The Original Code is mozilla.org code. + * The Original Code is Mozilla code. * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 + * The Initial Developer of the Original Code is Google Inc. + * Portions created by the Initial Developer are Copyright (C) 2006 * the Initial Developer. All Rights Reserved. * * Contributor(s): + * Darin Fisher * * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to @@ -36,450 +37,487 @@ * ***** END LICENSE BLOCK ***** */ #include "nsThread.h" -#include "prmem.h" -#include "prlog.h" +#include "nsThreadManager.h" #include "nsAutoLock.h" +#include "nsAutoPtr.h" +#include "nsCOMPtr.h" +#include "prlog.h" -PRUintn nsThread::kIThreadSelfIndex = 0; -static nsIThread *gMainThread = 0; +#ifdef PR_LOGGING +static PRLogModuleInfo *sLog = PR_NewLogModule("nsThread"); +#endif +#define LOG(args) PR_LOG(sLog, PR_LOG_DEBUG, args) -#if defined(PR_LOGGING) -// -// Log module for nsIThread logging... -// -// To enable logging (see prlog.h for full details): -// -// set NSPR_LOG_MODULES=nsIThread:5 -// set NSPR_LOG_FILE=nspr.log -// -// this enables PR_LOG_DEBUG level information and places all output in -// the file nspr.log -// -// gSocketLog is defined in nsSocketTransport.cpp -// -PRLogModuleInfo* nsIThreadLog = nsnull; +NS_DECL_CI_INTERFACE_GETTER(nsThread) -#endif /* PR_LOGGING */ +//----------------------------------------------------------------------------- +// Because we do not have our own nsIFactory, we have to implement nsIClassInfo +// somewhat manually. -//////////////////////////////////////////////////////////////////////////////// +class nsThreadClassInfo : public nsIClassInfo { +public: + NS_DECL_ISUPPORTS_INHERITED // no mRefCnt + NS_DECL_NSICLASSINFO -nsThread::nsThread() - : mThread(nsnull), mDead(PR_FALSE), mStartLock(nsnull) + nsThreadClassInfo() {} +}; + +static nsThreadClassInfo sThreadClassInfo; + +NS_IMETHODIMP_(nsrefcnt) nsThreadClassInfo::AddRef() { return 2; } +NS_IMETHODIMP_(nsrefcnt) nsThreadClassInfo::Release() { return 1; } +NS_IMPL_QUERY_INTERFACE1(nsThreadClassInfo, nsIClassInfo) + +NS_IMETHODIMP +nsThreadClassInfo::GetInterfaces(PRUint32 *count, nsIID ***array) { -#if defined(PR_LOGGING) - // - // Initialize the global PRLogModule for nsIThread logging - // if necessary... - // - if (nsIThreadLog == nsnull) { - nsIThreadLog = PR_NewLogModule("nsIThread"); - } -#endif /* PR_LOGGING */ + return NS_CI_INTERFACE_GETTER_NAME(nsThread)(count, array); +} - // enforce matching of constants to enums in prthread.h - NS_ASSERTION(int(nsIThread::PRIORITY_LOW) == int(PR_PRIORITY_LOW) && - int(nsIThread::PRIORITY_NORMAL) == int(PRIORITY_NORMAL) && - int(nsIThread::PRIORITY_HIGH) == int(PRIORITY_HIGH) && - int(nsIThread::PRIORITY_URGENT) == int(PRIORITY_URGENT) && - int(nsIThread::SCOPE_LOCAL) == int(PR_LOCAL_THREAD) && - int(nsIThread::SCOPE_GLOBAL) == int(PR_GLOBAL_THREAD) && - int(nsIThread::STATE_JOINABLE) == int(PR_JOINABLE_THREAD) && - int(nsIThread::STATE_UNJOINABLE) == int(PR_UNJOINABLE_THREAD), - "Bad constant in nsIThread!"); +NS_IMETHODIMP +nsThreadClassInfo::GetHelperForLanguage(PRUint32 lang, nsISupports **result) +{ + *result = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +nsThreadClassInfo::GetContractID(char **result) +{ + *result = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +nsThreadClassInfo::GetClassDescription(char **result) +{ + *result = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +nsThreadClassInfo::GetClassID(nsCID **result) +{ + *result = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +nsThreadClassInfo::GetImplementationLanguage(PRUint32 *result) +{ + *result = nsIProgrammingLanguage::CPLUSPLUS; + return NS_OK; +} + +NS_IMETHODIMP +nsThreadClassInfo::GetFlags(PRUint32 *result) +{ + *result = THREADSAFE; + return NS_OK; +} + +NS_IMETHODIMP +nsThreadClassInfo::GetClassIDNoAlloc(nsCID *result) +{ + return NS_ERROR_NOT_AVAILABLE; +} + +//----------------------------------------------------------------------------- + +NS_IMPL_THREADSAFE_ADDREF(nsThread) +NS_IMPL_THREADSAFE_RELEASE(nsThread) +NS_INTERFACE_MAP_BEGIN(nsThread) + NS_INTERFACE_MAP_ENTRY(nsIThread) + NS_INTERFACE_MAP_ENTRY(nsIThreadInternal) + NS_INTERFACE_MAP_ENTRY(nsIEventTarget) + NS_INTERFACE_MAP_ENTRY(nsISupportsPriority) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIThread) + if (aIID.Equals(NS_GET_IID(nsIClassInfo))) { + foundInterface = NS_STATIC_CAST(nsIClassInfo*, &sThreadClassInfo); + } else +NS_INTERFACE_MAP_END +NS_IMPL_CI_INTERFACE_GETTER4(nsThread, nsIThread, nsIThreadInternal, + nsIEventTarget, nsISupportsPriority) + +//----------------------------------------------------------------------------- + +class nsThreadShutdownEvent : public nsRunnable { +public: + nsThreadShutdownEvent(nsThread *thr) + : mThread(thr) { + } + + NS_IMETHODIMP Run() { + mThread->mActive = PR_FALSE; + return NS_OK; + } + +private: + nsRefPtr mThread; +}; + +//----------------------------------------------------------------------------- + +// This class is used to convey initialization info to the newly created thread. +class nsThreadStartup : public nsRunnable { +public: + nsThreadStartup() + : mMon(nsAutoMonitor::NewMonitor("xpcom.threadstartup")) + , mInitialized(PR_FALSE) { + } + + NS_IMETHOD Run() { + nsAutoMonitor mon(mMon); + mInitialized = PR_TRUE; + mon.Notify(); + return NS_OK; + } + + void Wait() { + nsAutoMonitor mon(mMon); + while (!mInitialized) + mon.Wait(); + } + +private: + virtual ~nsThreadStartup() { + nsAutoMonitor::DestroyMonitor(mMon); + } + + PRMonitor *mMon; + PRBool mInitialized; +}; + +//----------------------------------------------------------------------------- + +/*static*/ void +nsThread::ThreadFunc(void *arg) +{ + nsThread *self = NS_STATIC_CAST(nsThread *, arg); // strong reference + self->mThread = PR_GetCurrentThread(); + + // Inform the ThreadManager + nsThreadManager::get()->SetupCurrentThread(self, nsnull); + + // Wait for and process startup event + nsCOMPtr event; + if (!self->GetEvent(PR_TRUE, getter_AddRefs(event))) { + NS_WARNING("failed waiting for thread startup event"); + return; + } + event->Run(); // unblocks nsThread::Init + + // Now, process incoming events... + while (self->mActive) + self->ProcessNextEvent(); + + // Inform the threadmanager that this thread is going away + nsThreadManager::get()->SetupCurrentThread(nsnull, self); + + NS_RELEASE(self); +} + +//----------------------------------------------------------------------------- + +nsThread::nsThread(const nsACString &name) + : mLock(PR_NewLock()) + , mEvents(&mEventsRoot) + , mName(name) +{ } nsThread::~nsThread() { - if (mStartLock) - PR_DestroyLock(mStartLock); - - PR_LOG(nsIThreadLog, PR_LOG_DEBUG, - ("nsIThread %p destroyed\n", this)); - - // This code used to free the nsIThreadLog loginfo stuff - // Don't do that; loginfo structures are owned by nspr - // and would be freed if we ever called PR_Cleanup() - // see bug 142072 + PR_DestroyLock(mLock); } -void -nsThread::Main(void* arg) -{ - nsThread* self = (nsThread*)arg; - - self->WaitUntilReadyToStartMain(); - - nsresult rv = NS_OK; - rv = self->RegisterThreadSelf(); - NS_ASSERTION(rv == NS_OK, "failed to set thread self"); - - PR_LOG(nsIThreadLog, PR_LOG_DEBUG, - ("nsIThread %p start run %p\n", self, self->mRunnable.get())); - rv = self->mRunnable->Run(); - NS_ASSERTION(NS_SUCCEEDED(rv), "runnable failed"); - -#ifdef DEBUG - // Because a thread can die after gMainThread dies and takes nsIThreadLog with it, - // we need to check for it being null so that we don't crash on shutdown. - if (nsIThreadLog) { - PRThreadState state; - rv = self->GetState(&state); - PR_LOG(nsIThreadLog, PR_LOG_DEBUG, - ("nsIThread %p end run %p\n", self, self->mRunnable.get())); - } -#endif - - // explicitly drop the runnable now in case there are circular references - // between it and the thread object - self->mRunnable = nsnull; -} - -void -nsThread::Exit(void* arg) -{ - nsThread* self = (nsThread*)arg; - - if (self->mDead) { - NS_ERROR("attempt to Exit() thread twice"); - return; - } - - self->mDead = PR_TRUE; - -#if defined(PR_LOGGING) - if (nsIThreadLog) { - PR_LOG(nsIThreadLog, PR_LOG_DEBUG, - ("nsIThread %p exited\n", self)); - } -#endif - NS_RELEASE(self); -} - -NS_METHOD -nsThread::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult) -{ - nsThread* thread = new nsThread(); - if (!thread) return NS_ERROR_OUT_OF_MEMORY; - nsresult rv = thread->QueryInterface(aIID, aResult); - if (NS_FAILED(rv)) delete thread; - return rv; -} - -NS_IMPL_THREADSAFE_ISUPPORTS1(nsThread, nsIThread) - -NS_IMETHODIMP -nsThread::Join() -{ - // don't check for mDead here because nspr calls Exit (cleaning up - // thread-local storage) before they let us join with the thread - - PR_LOG(nsIThreadLog, PR_LOG_DEBUG, - ("nsIThread %p start join\n", this)); - if (!mThread) - return NS_ERROR_NOT_INITIALIZED; - PRStatus status = PR_JoinThread(mThread); - // XXX can't use NS_RELEASE here because the macro wants to set - // this to null (bad c++) - PR_LOG(nsIThreadLog, PR_LOG_DEBUG, - ("nsIThread %p end join\n", this)); - if (status != PR_SUCCESS) - return NS_ERROR_FAILURE; - - NS_RELEASE_THIS(); // most likely the final release of this thread - return NS_OK; -} - -NS_IMETHODIMP -nsThread::GetPriority(PRThreadPriority *result) -{ - if (mDead) - return NS_ERROR_FAILURE; - if (!mThread) - return NS_ERROR_NOT_INITIALIZED; - *result = PR_GetThreadPriority(mThread); - return NS_OK; -} - -NS_IMETHODIMP -nsThread::SetPriority(PRThreadPriority value) -{ - if (mDead) - return NS_ERROR_FAILURE; - if (!mThread) - return NS_ERROR_NOT_INITIALIZED; - PR_SetThreadPriority(mThread, value); - return NS_OK; -} - -NS_IMETHODIMP -nsThread::Interrupt() -{ - if (mDead) - return NS_ERROR_FAILURE; - if (!mThread) - return NS_ERROR_NOT_INITIALIZED; - PRStatus status = PR_Interrupt(mThread); - return status == PR_SUCCESS ? NS_OK : NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -nsThread::GetScope(PRThreadScope *result) -{ - if (mDead) - return NS_ERROR_FAILURE; - if (!mThread) - return NS_ERROR_NOT_INITIALIZED; - *result = PR_GetThreadScope(mThread); - return NS_OK; -} - -NS_IMETHODIMP -nsThread::GetState(PRThreadState *result) -{ - if (mDead) - return NS_ERROR_FAILURE; - if (!mThread) - return NS_ERROR_NOT_INITIALIZED; - *result = PR_GetThreadState(mThread); - return NS_OK; -} - -NS_IMETHODIMP -nsThread::GetPRThread(PRThread* *result) -{ - if (mDead) { - *result = nsnull; - return NS_ERROR_FAILURE; - } - *result = mThread; - return NS_OK; -} - -NS_IMETHODIMP -nsThread::Init(nsIRunnable* runnable, - PRUint32 stackSize, - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state) -{ - NS_ENSURE_ARG_POINTER(runnable); - if (mRunnable) - return NS_ERROR_ALREADY_INITIALIZED; - - mRunnable = runnable; - - if (mStartLock) - return NS_ERROR_ALREADY_INITIALIZED; - - mStartLock = PR_NewLock(); - if (mStartLock == nsnull) { - mRunnable = nsnull; - return NS_ERROR_OUT_OF_MEMORY; - } - - NS_ADDREF_THIS(); // released in nsThread::Exit - if (state == PR_JOINABLE_THREAD) - NS_ADDREF_THIS(); // released in nsThread::Join - - PR_Lock(mStartLock); - mDead = PR_FALSE; - mThread = PR_CreateThread(PR_USER_THREAD, Main, this, - priority, scope, state, stackSize); - /* As soon as we PR_Unlock(mStartLock), if mThread was successfully - * created, it could run and exit very quickly. In which case, it - * would null mThread and therefore if we check if (mThread) we could - * confuse a successfully created, yet already exited thread with - * OOM - failure to create the thread. So instead we store a local thr - * which we check to see if we really failed to create the thread. - */ - PRThread *thr = mThread; - PR_Unlock(mStartLock); - - if (thr == nsnull) { - mDead = PR_TRUE; // otherwise cleared in nsThread::Exit - mRunnable = nsnull; // otherwise cleared in nsThread::Main(when done) - PR_DestroyLock(mStartLock); - mStartLock = nsnull; - NS_RELEASE_THIS(); // otherwise released in nsThread::Exit - if (state == PR_JOINABLE_THREAD) - NS_RELEASE_THIS(); // otherwise released in nsThread::Join - return NS_ERROR_OUT_OF_MEMORY; - } - - PR_LOG(nsIThreadLog, PR_LOG_DEBUG, - ("nsIThread %p created\n", this)); - - return NS_OK; -} - -/* readonly attribute nsIThread currentThread; */ -NS_IMETHODIMP -nsThread::GetCurrentThread(nsIThread * *aCurrentThread) -{ - return GetIThread(PR_GetCurrentThread(), aCurrentThread); -} - -/* void sleep (in PRUint32 msec); */ -NS_IMETHODIMP -nsThread::Sleep(PRUint32 msec) -{ - if (PR_GetCurrentThread() != mThread) - return NS_ERROR_FAILURE; - - if (PR_Sleep(PR_MillisecondsToInterval(msec)) != PR_SUCCESS) - return NS_ERROR_FAILURE; - - return NS_OK; -} - -NS_COM nsresult -NS_NewThread(nsIThread* *result, - nsIRunnable* runnable, - PRUint32 stackSize, - PRThreadState state, - PRThreadPriority priority, - PRThreadScope scope) -{ - nsresult rv; - nsThread* thread = new nsThread(); - if (thread == nsnull) - return NS_ERROR_OUT_OF_MEMORY; - NS_ADDREF(thread); - - rv = thread->Init(runnable, stackSize, priority, scope, state); - if (NS_FAILED(rv)) { - NS_RELEASE(thread); - return rv; - } - - *result = thread; - return NS_OK; -} - -NS_COM nsresult -NS_NewThread(nsIThread* *result, - PRUint32 stackSize, - PRThreadState state, - PRThreadPriority priority, - PRThreadScope scope) -{ - nsThread* thread = new nsThread(); - if (thread == nsnull) - return NS_ERROR_OUT_OF_MEMORY; - NS_ADDREF(thread); - *result = thread; - return NS_OK; -} - -//////////////////////////////////////////////////////////////////////////////// - nsresult -nsThread::RegisterThreadSelf() +nsThread::Init() { - PRStatus status; + // spawn thread and wait until it is fully setup + + nsRefPtr startup = new nsThreadStartup(); + if (!startup) + return NS_ERROR_OUT_OF_MEMORY; - if (kIThreadSelfIndex == 0) { - status = PR_NewThreadPrivateIndex(&kIThreadSelfIndex, Exit); - if (status != PR_SUCCESS) return NS_ERROR_FAILURE; - } + NS_ADDREF_THIS(); + + mActive = PR_TRUE; - status = PR_SetThreadPrivate(kIThreadSelfIndex, this); - if (status != PR_SUCCESS) return NS_ERROR_FAILURE; + // ThreadFunc is responsible for setting mThread + PRThread *thr = PR_CreateThread(PR_USER_THREAD, ThreadFunc, this, + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, + PR_JOINABLE_THREAD, 0); + if (!thr) { + NS_RELEASE_THIS(); + return NS_ERROR_OUT_OF_MEMORY; + } - return NS_OK; + // ThreadFunc will wait for this event to be run before it tries to access + // mThread. By delaying insertion of this event into the queue, we ensure + // that mThread is set properly. + { + nsAutoLock lock(mLock); + mEvents->PutEvent(startup); + } + + // Wait for thread to call ThreadManager::SetCurrentThread, which completes + // initialization of ThreadFunc. + startup->Wait(); + + return NS_OK; } -void -nsThread::WaitUntilReadyToStartMain() +nsresult +nsThread::InitCurrentThread() { - PR_Lock(mStartLock); - PR_Unlock(mStartLock); - PR_DestroyLock(mStartLock); - mStartLock = nsnull; + mActive = PR_TRUE; + mThread = PR_GetCurrentThread(); + + return nsThreadManager::get()->SetupCurrentThread(this, nsnull); } -NS_COM nsresult -nsIThread::GetCurrent(nsIThread* *result) +PRBool +nsThread::PutEvent(nsIRunnable *event) { - return GetIThread(PR_GetCurrentThread(), result); + PRBool rv; + { + nsAutoLock lock(mLock); + rv = mEvents->PutEvent(event); + } + if (!rv) + return PR_FALSE; + + nsCOMPtr obs = GetObserver(); + if (obs) + obs->OnDispatchedEvent(this); + + return PR_TRUE; } -NS_COM nsresult -nsIThread::GetIThread(PRThread* prthread, nsIThread* *result) +//----------------------------------------------------------------------------- +// nsIEventTarget + +NS_IMETHODIMP +nsThread::Dispatch(nsIRunnable *event, PRUint32 flags) { - PRStatus status; - nsThread* thread; + LOG(("THRD(%p) Dispatch [%p %x]\n", this, event, flags)); - if (nsThread::kIThreadSelfIndex == 0) { - status = PR_NewThreadPrivateIndex(&nsThread::kIThreadSelfIndex, nsThread::Exit); - if (status != PR_SUCCESS) return NS_ERROR_FAILURE; - } + NS_ENSURE_ARG_POINTER(event); + NS_ENSURE_STATE(mThread); - thread = (nsThread*)PR_GetThreadPrivate(nsThread::kIThreadSelfIndex); - if (thread == nsnull) { - // if the current thread doesn't have an nsIThread associated - // with it, make one - thread = new nsThread(); - if (thread == nsnull) - return NS_ERROR_OUT_OF_MEMORY; - NS_ADDREF(thread); // released by Exit - thread->SetPRThread(prthread); - nsresult rv = thread->RegisterThreadSelf(); - if (NS_FAILED(rv)) return rv; - } - NS_ADDREF(thread); - *result = thread; - return NS_OK; + if (flags & DISPATCH_SYNC) { + nsCOMPtr thread; + nsThreadManager::get()->GetCurrentThread(getter_AddRefs(thread)); + NS_ENSURE_STATE(thread); + + // XXX we should be able to do something better here... we should + // be able to monitor the slot occupied by this event and use + // that to tell us when the event has been processed. + + nsRefPtr wrapper = new nsThreadSyncDispatch(event); + PutEvent(wrapper); + + while (wrapper->IsPending()) + thread->ProcessNextEvent(); + } else { + NS_ASSERTION(flags == NS_DISPATCH_NORMAL, "unexpected dispatch flags"); + PutEvent(event); + } + return NS_OK; } -NS_COM nsresult -nsIThread::SetMainThread() +NS_IMETHODIMP +nsThread::IsOnCurrentThread(PRBool *result) { - // strictly speaking, it could be set twice. but practically speaking, - // it's almost certainly an error if it is - if (gMainThread != 0) { - NS_ERROR("Setting main thread twice?"); - return NS_ERROR_FAILURE; - } - return GetCurrent(&gMainThread); + *result = (PR_GetCurrentThread() == mThread); + return NS_OK; } -NS_COM nsresult -nsIThread::GetMainThread(nsIThread **result) +//----------------------------------------------------------------------------- +// nsIThread + +NS_IMETHODIMP +nsThread::GetName(nsACString &result) { - NS_ASSERTION(result, "bad result pointer"); - if (gMainThread == 0) - return NS_ERROR_FAILURE; - *result = gMainThread; - NS_ADDREF(gMainThread); - return NS_OK; + result = mName; // no need to lock since this never changes + return NS_OK; } -NS_COM PRBool -nsIThread::IsMainThread() +NS_IMETHODIMP +nsThread::GetPRThread(PRThread **result) { - if (gMainThread == 0) - return PR_TRUE; - - PRThread *theMainThread; - gMainThread->GetPRThread(&theMainThread); - return theMainThread == PR_GetCurrentThread(); + *result = mThread; + return NS_OK; } -void +NS_IMETHODIMP nsThread::Shutdown() { - if (gMainThread) { - // XXX nspr doesn't seem to be calling the main thread's destructor - // callback, so let's help it out: - nsThread::Exit(NS_STATIC_CAST(nsThread*, gMainThread)); - nsrefcnt cnt; - NS_RELEASE2(gMainThread, cnt); - NS_WARN_IF_FALSE(cnt == 0, "Main thread being held past XPCOM shutdown."); - gMainThread = nsnull; - - kIThreadSelfIndex = 0; - } + LOG(("THRD(%p) shutdown\n", this)); + + // Maybe we are already shutdown. + if (!mThread) + return NS_OK; + + NS_ENSURE_STATE(PR_GetCurrentThread() != mThread); + + // shutdown event queue + nsCOMPtr event = new nsThreadShutdownEvent(this); + if (!event) + return NS_ERROR_OUT_OF_MEMORY; + PutEvent(event); + + // XXX we could still end up with other events being added after the shutdown task + + PR_JoinThread(mThread); + mThread = nsnull; + return NS_OK; } -//////////////////////////////////////////////////////////////////////////////// +NS_IMETHODIMP +nsThread::HasPendingEvents(PRBool *result) +{ + NS_ENSURE_STATE(PR_GetCurrentThread() == mThread); + + *result = mEvents->GetEvent(PR_FALSE, nsnull); + return NS_OK; +} + +NS_IMETHODIMP +nsThread::ProcessNextEvent() +{ + LOG(("THRD(%p) ProcessNextEvent\n", this)); + + NS_ENSURE_STATE(PR_GetCurrentThread() == mThread); + + nsresult rv; + + nsCOMPtr obs = mObserver; + if (obs) + obs->OnProcessNextEvent(this, mActive); + + // If we are shutting down, then do not wait for new events. + nsCOMPtr event; + mEvents->GetEvent(mActive, getter_AddRefs(event)); + + if (event) { + LOG(("THRD(%p) running [%p]\n", this, event.get())); + event->Run(); + rv = NS_OK; + } else { + NS_ASSERTION(!mActive, "This should only happen when shutting down"); + rv = NS_ERROR_ABORT; + } + + return rv; +} + +//----------------------------------------------------------------------------- +// nsISupportsPriority + +NS_IMETHODIMP +nsThread::GetPriority(PRInt32 *priority) +{ + *priority = mPriority; + return NS_OK; +} + +NS_IMETHODIMP +nsThread::SetPriority(PRInt32 priority) +{ + NS_ENSURE_STATE(mThread); + + // NSPR defines the following four thread priorities: + // PR_PRIORITY_LOW + // PR_PRIORITY_NORMAL + // PR_PRIORITY_HIGH + // PR_PRIORITY_URGENT + // We map the priority values defined on nsISupportsPriority to these values. + + mPriority = priority; + + PRThreadPriority pri; + if (mPriority <= PRIORITY_HIGHEST) { + pri = PR_PRIORITY_URGENT; + } else if (mPriority < PRIORITY_NORMAL) { + pri = PR_PRIORITY_HIGH; + } else if (mPriority > PRIORITY_NORMAL) { + pri = PR_PRIORITY_LOW; + } else { + pri = PR_PRIORITY_NORMAL; + } + PR_SetThreadPriority(mThread, pri); + + return NS_OK; +} + +NS_IMETHODIMP +nsThread::AdjustPriority(PRInt32 delta) +{ + return SetPriority(mPriority + delta); +} + +//----------------------------------------------------------------------------- +// nsIThreadInternal + +NS_IMETHODIMP +nsThread::GetObserver(nsIThreadObserver **obs) +{ + nsAutoLock lock(mLock); + NS_IF_ADDREF(*obs = mObserver); + return NS_OK; +} + +NS_IMETHODIMP +nsThread::SetObserver(nsIThreadObserver *obs) +{ + NS_ENSURE_STATE(PR_GetCurrentThread() == mThread); + + nsAutoLock lock(mLock); + mObserver = obs; + return NS_OK; +} + +NS_IMETHODIMP +nsThread::PushEventQueue(nsIThreadEventFilter *filter) +{ + nsChainedEventQueue *queue = new nsChainedEventQueue(filter); + if (!queue) + return NS_ERROR_OUT_OF_MEMORY; + + nsAutoLock lock(mLock); + queue->mNext = mEvents; + mEvents = queue; + return NS_OK; +} + +NS_IMETHODIMP +nsThread::PopEventQueue() +{ + nsAutoLock lock(mLock); + + // Make sure we do not pop too many! + NS_ENSURE_STATE(mEvents != &mEventsRoot); + + nsChainedEventQueue *queue = mEvents; + mEvents = mEvents->mNext; + + nsCOMPtr event; + while (queue->GetEvent(PR_FALSE, getter_AddRefs(event))) + mEvents->PutEvent(event); + + return NS_OK; +} + +PRBool +nsThread::nsChainedEventQueue::PutEvent(nsIRunnable *event) +{ + PRBool val; + if (!mFilter || mFilter->AcceptEvent(event)) { + val = mQueue.PutEvent(event); + } else { + val = mNext->PutEvent(event); + } + return val; +} diff --git a/mozilla/xpcom/threads/nsThread.h b/mozilla/xpcom/threads/nsThread.h index e75086a71d8..e4d14e9968a 100644 --- a/mozilla/xpcom/threads/nsThread.h +++ b/mozilla/xpcom/threads/nsThread.h @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -12,18 +13,18 @@ * for the specific language governing rights and limitations under the * License. * - * The Original Code is mozilla.org code. + * The Original Code is Mozilla code. * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 + * The Initial Developer of the Original Code is Google Inc. + * Portions created by the Initial Developer are Copyright (C) 2006 * the Initial Developer. All Rights Reserved. * * Contributor(s): + * Darin Fisher * * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to @@ -33,60 +34,111 @@ * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * - * ***** END LICENSE BLOCK ***** - * This Original Code has been modified by IBM Corporation. - * Modifications made by IBM described herein are - * Copyright (c) International Business Machines - * Corporation, 2000 - * - * Modifications to Mozilla code or documentation - * identified per MPL Section 3.3 - * - * Date Modified by Description of modification - * 04/20/2000 IBM Corp. Added PR_CALLBACK for Optlink use in OS2 - */ + * ***** END LICENSE BLOCK ***** */ #ifndef nsThread_h__ #define nsThread_h__ -#include "nsIRunnable.h" -#include "nsIThread.h" -#include "nsCOMPtr.h" +#include "nsIThreadInternal.h" +#include "nsISupportsPriority.h" +#include "nsEventQueue.h" +#include "nsThreadUtils.h" +#include "nsString.h" +#include "nsAutoPtr.h" -class nsThread : public nsIThread +// A native thread +class nsThread : public nsIThreadInternal, public nsISupportsPriority { public: - NS_DECL_ISUPPORTS + NS_DECL_ISUPPORTS + NS_DECL_NSIEVENTTARGET + NS_DECL_NSITHREAD + NS_DECL_NSITHREADINTERNAL + NS_DECL_NSISUPPORTSPRIORITY - // nsIThread methods: - NS_DECL_NSITHREAD - - // nsThread methods: - nsThread(); + nsThread(const nsACString &name); - nsresult RegisterThreadSelf(); - void SetPRThread(PRThread* thread) { mThread = thread; } - void WaitUntilReadyToStartMain(); + // Initialize this as a wrapper for a new PRThread. + nsresult Init(); - static void PR_CALLBACK Main(void* arg); - static void PR_CALLBACK Exit(void* arg); - static void PR_CALLBACK Shutdown(); - - static PRUintn kIThreadSelfIndex; - - static NS_METHOD - Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr); + // Initialize this as a wrapper for the current PRThread. + nsresult InitCurrentThread(); private: - ~nsThread(); + friend class nsThreadShutdownEvent; -protected: - PRThread* mThread; - nsCOMPtr mRunnable; - PRBool mDead; - PRLock* mStartLock; + ~nsThread(); + + PR_STATIC_CALLBACK(void) ThreadFunc(void *arg); + + // Helper + already_AddRefed GetObserver() { + nsIThreadObserver *obs; + nsThread::GetObserver(&obs); + return already_AddRefed(obs); + } + + // Wrappers for event queue methods: + PRBool GetEvent(PRBool mayWait, nsIRunnable **event) { + return mEvents->GetEvent(mayWait, event); + } + PRBool PutEvent(nsIRunnable *event); + + // Wrapper for nsEventQueue that supports chaining. + struct nsChainedEventQueue { + struct nsChainedEventQueue *mNext; + nsCOMPtr mFilter; + nsEventQueue mQueue; + + nsChainedEventQueue(nsIThreadEventFilter *filter = nsnull) + : mNext(nsnull), mFilter(filter) { + } + + PRBool GetEvent(PRBool mayWait, nsIRunnable **event) { + return mQueue.GetEvent(mayWait, event); + } + + PRBool PutEvent(nsIRunnable *event); + }; + + // This lock protects access to mObserver and mEvents. Both of those fields + // are only modified on the thread itself (never from another thread). This + // means that we can avoid holding the lock while using mObserver and mEvents + // on the thread itself. When calling PutEvent on mEvents, we have to hold + // the lock to synchronize with PopEventQueue. + PRLock *mLock; + + nsCOMPtr mObserver; + + nsChainedEventQueue *mEvents; // never null + nsChainedEventQueue mEventsRoot; + + nsCString mName; + PRInt32 mPriority; + PRThread *mThread; + PRIntn mActive; }; -//////////////////////////////////////////////////////////////////////////////// +//----------------------------------------------------------------------------- -#endif // nsThread_h__ +class nsThreadSyncDispatch : public nsRunnable { +public: + nsThreadSyncDispatch(nsIRunnable *task) + : mSyncTask(task) { + } + + NS_IMETHODIMP Run() { + mSyncTask->Run(); + mSyncTask = nsnull; + return NS_OK; + } + + PRBool IsPending() { + return mSyncTask != nsnull; + } + +private: + nsCOMPtr mSyncTask; +}; + +#endif // nsThread_h__ diff --git a/mozilla/xpcom/threads/nsThreadManager.cpp b/mozilla/xpcom/threads/nsThreadManager.cpp new file mode 100644 index 00000000000..7625622f4a6 --- /dev/null +++ b/mozilla/xpcom/threads/nsThreadManager.cpp @@ -0,0 +1,261 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla code. + * + * The Initial Developer of the Original Code is Google Inc. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Darin Fisher + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsThreadManager.h" +#include "nsThread.h" +#include "nsCOMArray.h" +#include "nsAutoPtr.h" + +//----------------------------------------------------------------------------- + +PR_STATIC_CALLBACK(void) +ReleaseObject(void *data) +{ + NS_STATIC_CAST(nsISupports *, data)->Release(); +} + +PR_STATIC_CALLBACK(PLDHashOperator) +AppendAndRemoveThread(const void *key, nsCOMPtr &thread, void *arg) +{ + nsCOMArray *threads = + NS_STATIC_CAST(nsCOMArray *, arg); + threads->AppendObject(thread); + return PL_DHASH_REMOVE; +} + +//----------------------------------------------------------------------------- + +nsThreadManager nsThreadManager::sInstance; + +// statically allocated instance +NS_IMETHODIMP_(nsrefcnt) nsThreadManager::AddRef() { return 2; } +NS_IMETHODIMP_(nsrefcnt) nsThreadManager::Release() { return 1; } +NS_IMPL_QUERY_INTERFACE1_CI(nsThreadManager, nsIThreadManager) +NS_IMPL_CI_INTERFACE_GETTER1(nsThreadManager, nsIThreadManager) + +//----------------------------------------------------------------------------- + +nsresult +nsThreadManager::Init() +{ + if (!mThreadsByName.Init() || !mThreadsByPRThread.Init()) + return NS_ERROR_OUT_OF_MEMORY; + + if (PR_NewThreadPrivateIndex(&mCurThreadIndex, ReleaseObject) == PR_FAILURE) + return NS_ERROR_FAILURE; + + // Setup "main" thread + nsRefPtr mainThread = new nsThread(NS_LITERAL_CSTRING("main")); + if (!mainThread) + return NS_ERROR_OUT_OF_MEMORY; + mainThread->InitCurrentThread(); + + mainThread->GetPRThread(&mMainPRThread); + return NS_OK; +} + +void +nsThreadManager::Shutdown() +{ + NS_ASSERTION(NS_IsMainThread(), "shutdown not called from main thread"); + + // We move the threads from the hashtable to a list, so that we avoid + // holding the hashtable lock while calling nsIThread::Shutdown. + + nsCOMArray threads; + mThreadsByPRThread.Enumerate(AppendAndRemoveThread, &threads); + mThreadsByName.Clear(); + + // Shutdown all background threads. + for (PRInt32 i = 0; i < threads.Count(); ++i) { + nsIThread *thread = threads.ObjectAt(i); + + PRBool isMainThread = PR_FALSE; + thread->IsOnCurrentThread(&isMainThread); + if (!isMainThread) + thread->Shutdown(); + } + + // Remove the TLS entry for the main thread. + PR_SetThreadPrivate(mCurThreadIndex, nsnull); +} + +nsresult +nsThreadManager::SetupCurrentThread(nsIThread *thread, nsIThread *previous) +{ + nsCString name; + if (thread) { + thread->GetName(name); + if (!name.IsEmpty()) { + // make sure thread name is unique + nsCOMPtr temp; + GetThread(name, getter_AddRefs(temp)); + + if (temp && temp != previous) { + NS_NOTREACHED("thread name is not unique"); + return NS_ERROR_INVALID_ARG; + } + mThreadsByName.Put(name, thread); + } + + PRThread *prthread = nsnull; + thread->GetPRThread(&prthread); + NS_ASSERTION(prthread, "no prthread"); + +#ifdef DEBUG + if (previous) { + PRThread *prthreadPrev = nsnull; + previous->GetPRThread(&prthreadPrev); + NS_ASSERTION(prthreadPrev, "no previous prthread"); + NS_ASSERTION(prthread == prthreadPrev, "prthread changed"); + } +#endif + + mThreadsByPRThread.Put(prthread, thread); + + NS_ADDREF(thread); // for TLS entry + } else if (previous) { + previous->GetName(name); + if (!name.IsEmpty()) + mThreadsByName.Remove(name); + + PRThread *prthread = nsnull; + previous->GetPRThread(&prthread); + NS_ASSERTION(prthread, "no prthread"); + mThreadsByPRThread.Remove(prthread); + } + + // write thread local storage + PR_SetThreadPrivate(mCurThreadIndex, thread); + return NS_OK; +} + +NS_IMETHODIMP +nsThreadManager::NewThread(const nsACString &name, nsIThread **result) +{ + // make sure name is unique + + nsThread *thr = new nsThread(name); + if (!thr) + return NS_ERROR_OUT_OF_MEMORY; + NS_ADDREF(thr); + + nsresult rv = thr->Init(); + if (NS_FAILED(rv)) { + NS_RELEASE(thr); + return rv; + } + + // At this point, we expect that the thread has been registered in mThread; + // however, it is possible that it could have also been replaced by now, so + // we cannot really assert that it was added. + + *result = thr; + return NS_OK; +} + +NS_IMETHODIMP +nsThreadManager::GetThread(const nsACString &name, nsIThread **result) +{ + if (name.IsEmpty()) { + *result = nsnull; + return NS_OK; + } + mThreadsByName.Get(name, result); + return NS_OK; +} + +NS_IMETHODIMP +nsThreadManager::GetThreadFromPRThread(PRThread *thread, nsIThread **result) +{ + NS_ENSURE_ARG_POINTER(thread); + mThreadsByPRThread.Get(thread, result); + return NS_OK; +} + +NS_IMETHODIMP +nsThreadManager::GetMainThread(nsIThread **result) +{ + mThreadsByPRThread.Get(mMainPRThread, result); + return NS_OK; +} + +NS_IMETHODIMP +nsThreadManager::GetCurrentThread(nsIThread **result) +{ + // read thread local storage + void *data = PR_GetThreadPrivate(mCurThreadIndex); + if (data) { + NS_ADDREF(*result = NS_STATIC_CAST(nsIThread *, data)); + } else { + // OK, that's fine. We'll dynamically create one :-) + nsRefPtr thread = new nsThread(EmptyCString()); + if (!thread) + return NS_ERROR_OUT_OF_MEMORY; + thread->InitCurrentThread(); + NS_ADDREF(*result = thread); + } + return NS_OK; +} + +#if 0 +NS_IMETHODIMP +nsThreadManager::SetCurrentThread(nsIThread *thread, nsIThread **result) +{ + nsCOMPtr prev; + GetCurrentThread(getter_AddRefs(prev)); + + nsresult rv = SetupCurrentThread(thread, prev); + if (NS_FAILED(rv)) + return rv; + + if (result) { + *result = nsnull; + prev.swap(*result); + } + + return NS_OK; +} +#endif + +NS_IMETHODIMP +nsThreadManager::GetIsMainThread(PRBool *result) +{ + *result = (PR_GetCurrentThread() == mMainPRThread); + return NS_OK; +} diff --git a/mozilla/xpcom/threads/nsThreadManager.h b/mozilla/xpcom/threads/nsThreadManager.h new file mode 100644 index 00000000000..562fa59af3f --- /dev/null +++ b/mozilla/xpcom/threads/nsThreadManager.h @@ -0,0 +1,91 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla code. + * + * The Initial Developer of the Original Code is Google Inc. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Darin Fisher + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsThreadManager_h__ +#define nsThreadManager_h__ + +#include "nsIThreadManager.h" +#include "nsIThread.h" +#include "nsInterfaceHashtable.h" + +class nsIRunnable; + +class nsThreadManager : public nsIThreadManager +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSITHREADMANAGER + + static nsThreadManager *get() { + return &sInstance; + } + + nsresult Init(); + + // Shutdown all threads. This function should only be called on the main + // thread of the application process. + void Shutdown(); + + // Establishes |current| as the nsIThread for the calling thread. The + // caller should pass a pointer to the previous nsIThread if any. If + // |current| is null, then this method has the effect of unregistering + // the nsIThread associated with the calling thread. + nsresult SetupCurrentThread(nsIThread *current, nsIThread *previous); + +private: + nsThreadManager() : mCurThreadIndex(0), mMainPRThread(nsnull) {} + ~nsThreadManager() {} + + static nsThreadManager sInstance; + + nsInterfaceHashtableMT mThreadsByName; + nsInterfaceHashtableMT mThreadsByPRThread; + PRUintn mCurThreadIndex; // thread-local-storage index + PRThread *mMainPRThread; +}; + +#define NS_THREADMANAGER_CLASSNAME "nsThreadManager" +#define NS_THREADMANAGER_CID \ +{ /* 7a4204c6-e45a-4c37-8ebb-6709a22c917c */ \ + 0x7a4204c6, \ + 0xe45a, \ + 0x4c37, \ + {0x8e, 0xbb, 0x67, 0x09, 0xa2, 0x2c, 0x91, 0x7c} \ +} + +#endif // nsThreadManager_h__ diff --git a/mozilla/xpcom/threads/nsThreadPool.cpp b/mozilla/xpcom/threads/nsThreadPool.cpp new file mode 100644 index 00000000000..ffeacd4a0d2 --- /dev/null +++ b/mozilla/xpcom/threads/nsThreadPool.cpp @@ -0,0 +1,318 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla code. + * + * The Initial Developer of the Original Code is Google Inc. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Darin Fisher + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsIProxyObjectManager.h" +#include "nsThreadPool.h" +#include "nsThreadManager.h" +#include "nsThread.h" +#include "nsMemory.h" +#include "nsAutoPtr.h" +#include "nsAutoLock.h" +#include "prinrval.h" +#include "prlog.h" + +#ifdef PR_LOGGING +static PRLogModuleInfo *sLog = PR_NewLogModule("nsThreadPool"); +#endif +#define LOG(args) PR_LOG(sLog, PR_LOG_DEBUG, args) + +// DESIGN: +// o Allocate anonymous threads. +// o Use nsThreadPool::Run as the main routine for each thread. +// o Each thread waits on the event queue's monitor, checking for +// pending events and rescheduling itself as an idle thread. + +#define DEFAULT_THREAD_LIMIT 4 +#define DEFAULT_IDLE_THREAD_LIMIT 1 +#define DEFAULT_IDLE_THREAD_TIMEOUT PR_SecondsToInterval(60) + +NS_IMPL_THREADSAFE_ADDREF(nsThreadPool) +NS_IMPL_THREADSAFE_RELEASE(nsThreadPool) +NS_IMPL_QUERY_INTERFACE3_CI(nsThreadPool, nsIThreadPool, nsIEventTarget, + nsIRunnable) +NS_IMPL_CI_INTERFACE_GETTER2(nsThreadPool, nsIThreadPool, nsIEventTarget) + +nsThreadPool::nsThreadPool() + : mThreadLimit(DEFAULT_THREAD_LIMIT) + , mIdleThreadLimit(DEFAULT_IDLE_THREAD_LIMIT) + , mIdleThreadTimeout(DEFAULT_IDLE_THREAD_TIMEOUT) + , mIdleCount(0) + , mShutdown(PR_FALSE) +{ +} + +nsThreadPool::~nsThreadPool() +{ + Shutdown(); +} + +nsresult +nsThreadPool::PutEvent(nsIRunnable *event) +{ + // Avoid spawning a new thread while holding the event queue lock... + + PRBool spawnThread = PR_FALSE; + { + nsAutoMonitor mon(mEvents.Monitor()); + + LOG(("THRD-P(%p) put [%d %d %d]\n", this, mIdleCount, mThreads.Count(), + mThreadLimit)); + NS_ASSERTION(mIdleCount <= (PRUint32) mThreads.Count(), "oops"); + + // Make sure we have a thread to service this event. + if (mIdleCount == 0 && mThreads.Count() < (PRInt32) mThreadLimit) + spawnThread = PR_TRUE; + + mEvents.PutEvent(event); + } + + LOG(("THRD-P(%p) put [spawn=%d]\n", this, spawnThread)); + if (!spawnThread) + return NS_OK; + + nsCOMPtr thread; + nsThreadManager::get()->NewThread(EmptyCString(), getter_AddRefs(thread)); + NS_ENSURE_STATE(thread); + + PRBool killThread = PR_FALSE; + { + nsAutoMonitor mon(mEvents.Monitor()); + if (mThreads.Count() < (PRInt32) mThreadLimit) { + mThreads.AppendObject(thread); + } else { + killThread = PR_TRUE; // okay, we don't need this thread anymore + } + } + LOG(("THRD-P(%p) put [%p kill=%d]\n", this, thread.get(), killThread)); + if (killThread) { + thread->Shutdown(); + } else { + thread->Dispatch(this, NS_DISPATCH_NORMAL); + } + + return NS_OK; +} + +void +nsThreadPool::ShutdownThread(nsIThread *thread) +{ + LOG(("THRD-P(%p) shutdown async [%p]\n", this, thread)); + + // This method is responsible for calling Shutdown on the thread. This must + // be done from the main thread of the application. + + NS_ASSERTION(!NS_IsMainThread(), "wrong thread"); + + nsCOMPtr doomed; + NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD, NS_GET_IID(nsIThread), thread, + NS_PROXY_ASYNC, getter_AddRefs(doomed)); + if (doomed) { + doomed->Shutdown(); + } else { + NS_WARNING("failed to construct proxy to main thread"); + } +} + +NS_IMETHODIMP +nsThreadPool::Run() +{ + LOG(("THRD-P(%p) enter\n", this)); + + nsCOMPtr current; + nsThreadManager::get()->GetCurrentThread(getter_AddRefs(current)); + + PRBool exitThread = PR_FALSE; + PRBool wasIdle = PR_FALSE; + PRIntervalTime idleSince; + + do { + nsCOMPtr event; + { + nsAutoMonitor mon(mEvents.Monitor()); + if (!mEvents.GetPendingEvent(getter_AddRefs(event))) { + PRIntervalTime now = PR_IntervalNow(); + PRIntervalTime timeout = PR_MillisecondsToInterval(mIdleThreadTimeout); + + // If we are shutting down, then don't keep any idle threads + if (mShutdown) { + exitThread = PR_TRUE; + } else { + if (wasIdle) { + // if too many idle threads or idle for too long, then bail. + if (mIdleCount > mIdleThreadLimit || (now - idleSince) > timeout) + exitThread = PR_TRUE; + } else { + // if would be too many idle threads... + if (mIdleCount == mIdleThreadLimit) { + exitThread = PR_TRUE; + } else { + ++mIdleCount; + idleSince = now; + wasIdle = PR_TRUE; + } + } + } + + if (exitThread) { + if (wasIdle) + --mIdleCount; + mThreads.RemoveObject(current); + } else { + PRIntervalTime delta = timeout - (now - idleSince); + LOG(("THRD-P(%p) waiting [%d]\n", this, delta)); + mon.Wait(delta); + } + } else if (wasIdle) { + wasIdle = PR_FALSE; + --mIdleCount; + } + } + if (event) { + LOG(("THRD-P(%p) running [%p]\n", this, event.get())); + event->Run(); + } + } while (!exitThread); + + ShutdownThread(current); + + LOG(("THRD-P(%p) leave\n", this)); + return NS_OK; +} + +NS_IMETHODIMP +nsThreadPool::Dispatch(nsIRunnable *event, PRUint32 flags) +{ + LOG(("THRD-P(%p) dispatch [%p %x]\n", this, event, flags)); + + NS_ENSURE_STATE(!mShutdown); + + if (flags & DISPATCH_SYNC) { + nsCOMPtr thread; + nsThreadManager::get()->GetCurrentThread(getter_AddRefs(thread)); + NS_ENSURE_STATE(thread); + + nsRefPtr wrapper = new nsThreadSyncDispatch(event); + PutEvent(wrapper); + + while (wrapper->IsPending()) + thread->ProcessNextEvent(); + } else { + NS_ASSERTION(flags == NS_DISPATCH_NORMAL, "unexpected dispatch flags"); + PutEvent(event); + } + return NS_OK; +} + +NS_IMETHODIMP +nsThreadPool::IsOnCurrentThread(PRBool *result) +{ + *result = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP +nsThreadPool::Shutdown() +{ + nsCOMArray threads; + { + nsAutoMonitor mon(mEvents.Monitor()); + mShutdown = PR_TRUE; + mon.NotifyAll(); + + threads.AppendObjects(mThreads); + } + + // It's important that we shutdown the threads while outside the event queue + // monitor. Otherwise, we could end up dead-locking. The threads will take + // care of removing themselves from mThreads as they exit. + + for (PRInt32 i = 0; i < threads.Count(); ++i) + threads[i]->Shutdown(); + + return NS_OK; +} + +NS_IMETHODIMP +nsThreadPool::GetThreadLimit(PRUint32 *value) +{ + *value = mThreadLimit; + return NS_OK; +} + +NS_IMETHODIMP +nsThreadPool::SetThreadLimit(PRUint32 value) +{ + nsAutoMonitor mon(mEvents.Monitor()); + mThreadLimit = value; + if (mIdleThreadLimit > mThreadLimit) + mIdleThreadLimit = mThreadLimit; + mon.NotifyAll(); // wake up threads so they observe this change + return NS_OK; +} + +NS_IMETHODIMP +nsThreadPool::GetIdleThreadLimit(PRUint32 *value) +{ + *value = mIdleThreadLimit; + return NS_OK; +} + +NS_IMETHODIMP +nsThreadPool::SetIdleThreadLimit(PRUint32 value) +{ + nsAutoMonitor mon(mEvents.Monitor()); + mIdleThreadLimit = value; + mon.NotifyAll(); // wake up threads so they observe this change + return NS_OK; +} + +NS_IMETHODIMP +nsThreadPool::GetIdleThreadTimeout(PRUint32 *value) +{ + *value = mIdleThreadTimeout; + return NS_OK; +} + +NS_IMETHODIMP +nsThreadPool::SetIdleThreadTimeout(PRUint32 value) +{ + nsAutoMonitor mon(mEvents.Monitor()); + mIdleThreadTimeout = value; + mon.NotifyAll(); // wake up threads so they observe this change + return NS_OK; +} diff --git a/mozilla/xpcom/threads/nsThreadPool.h b/mozilla/xpcom/threads/nsThreadPool.h new file mode 100644 index 00000000000..9366b56cd40 --- /dev/null +++ b/mozilla/xpcom/threads/nsThreadPool.h @@ -0,0 +1,82 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla code. + * + * The Initial Developer of the Original Code is Google Inc. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Darin Fisher + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsThreadPool_h__ +#define nsThreadPool_h__ + +#include "nsIThreadPool.h" +#include "nsIThread.h" +#include "nsIRunnable.h" +#include "nsEventQueue.h" +#include "nsCOMArray.h" + +class nsThreadPool : public nsIThreadPool, public nsIRunnable +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIEVENTTARGET + NS_DECL_NSITHREADPOOL + NS_DECL_NSIRUNNABLE + + nsThreadPool(); + +private: + ~nsThreadPool(); + + void ShutdownThread(nsIThread *thread); + nsresult PutEvent(nsIRunnable *event); + + nsCOMArray mThreads; + nsEventQueue mEvents; + PRUint32 mThreadLimit; + PRUint32 mIdleThreadLimit; + PRUint32 mIdleThreadTimeout; + PRUint32 mIdleCount; + PRBool mShutdown; +}; + +#define NS_THREADPOOL_CLASSNAME "nsThreadPool" +#define NS_THREADPOOL_CID \ +{ /* 547ec2a8-315e-4ec4-888e-6e4264fe90eb */ \ + 0x547ec2a8, \ + 0x315e, \ + 0x4ec4, \ + {0x88, 0x8e, 0x6e, 0x42, 0x64, 0xfe, 0x90, 0xeb} \ +} + +#endif // nsThreadPool_h__ diff --git a/mozilla/xpcom/threads/nsTimerImpl.cpp b/mozilla/xpcom/threads/nsTimerImpl.cpp index 4517dbb5561..d0c6c23d619 100644 --- a/mozilla/xpcom/threads/nsTimerImpl.cpp +++ b/mozilla/xpcom/threads/nsTimerImpl.cpp @@ -41,11 +41,10 @@ #include "nsTimerImpl.h" #include "TimerThread.h" #include "nsAutoLock.h" - +#include "nsAutoPtr.h" #include "nsVoidArray.h" - -#include "nsIEventQueue.h" - +#include "nsThreadManager.h" +#include "nsThreadUtils.h" #include "prmem.h" static PRInt32 gGenerator = 0; @@ -150,7 +149,7 @@ nsTimerImpl::nsTimerImpl() : mTimeout(0) { // XXXbsmedberg: shouldn't this be in Init()? - nsIThread::GetCurrent(getter_AddRefs(mCallingThread)); + nsThreadManager::get()->GetCurrentThread(getter_AddRefs(mCallingThread)); mCallback.c = nsnull; @@ -428,28 +427,45 @@ void nsTimerImpl::Fire() } -struct TimerEventType : public PLEvent { - PRInt32 mGeneration; +class nsTimerEvent : public nsRunnable { +public: + NS_IMETHOD Run(); + + nsTimerEvent(nsTimerImpl *timer, PRInt32 generation) + : mTimer(timer), mGeneration(generation) { + // timer is already addref'd for us + } + #ifdef DEBUG_TIMERS PRIntervalTime mInitTime; #endif + +private: + ~nsTimerEvent() { +#ifdef DEBUG + if (mTimer) + NS_WARNING("leaking reference to nsTimerImpl"); +#endif + } + + nsTimerImpl *mTimer; + PRInt32 mGeneration; }; - -PR_STATIC_CALLBACK(void*) handleTimerEvent(PLEvent* aEvent) +NS_IMETHODIMP nsTimerEvent::Run() { - TimerEventType *event = NS_STATIC_CAST(TimerEventType*, aEvent); + nsRefPtr timer; + timer.swap(mTimer); - nsTimerImpl* timer = NS_STATIC_CAST(nsTimerImpl*, event->owner); - if (event->mGeneration != timer->GetGeneration()) - return nsnull; + if (mGeneration != timer->GetGeneration()) + return NS_OK; #ifdef DEBUG_TIMERS if (PR_LOG_TEST(gTimerLog, PR_LOG_DEBUG)) { PRIntervalTime now = PR_IntervalNow(); PR_LOG(gTimerLog, PR_LOG_DEBUG, ("[this=%p] time between PostTimerEvent() and Fire(): %dms\n", - event->owner, PR_IntervalToMilliseconds(now - event->mInitTime))); + this, PR_IntervalToMilliseconds(now - mInitTime))); } #endif @@ -460,43 +476,27 @@ PR_STATIC_CALLBACK(void*) handleTimerEvent(PLEvent* aEvent) NS_ASSERTION(gManager, "Global Thread Manager is null!"); if (gManager) gManager->AddIdleTimer(timer); - return nsnull; + return NS_OK; } } timer->Fire(); - return nsnull; + return NS_OK; } -PR_STATIC_CALLBACK(void) destroyTimerEvent(PLEvent* aEvent) -{ - TimerEventType *event = NS_STATIC_CAST(TimerEventType*, aEvent); - - nsTimerImpl *timer = NS_STATIC_CAST(nsTimerImpl*, event->owner); - NS_RELEASE(timer); - PR_DELETE(event); -} - - void nsTimerImpl::PostTimerEvent() { - // XXX we may want to reuse the PLEvent in the case of repeating timers. - TimerEventType* event; - - // construct - event = PR_NEW(TimerEventType); - if (!event) - return; - - // initialize - PL_InitEvent((PLEvent*)event, this, handleTimerEvent, destroyTimerEvent); + // XXX we may want to reuse this nsTimerEvent in the case of repeating timers. // Since TimerThread addref'd 'this' for us, we don't need to addref here. - // We will release in destroyMyEvent. We do need to copy the generation - // number from this timer into the event, so we can avoid firing a timer - // that was re-initialized after being canceled. - event->mGeneration = mGeneration; + // We will release in destroyMyEvent. We need to copy the generation number + // from this timer into the event, so we can avoid firing a timer that was + // re-initialized after being canceled. + + nsTimerEvent* event = new nsTimerEvent(this, mGeneration); + if (!event) + return; #ifdef DEBUG_TIMERS if (PR_LOG_TEST(gTimerLog, PR_LOG_DEBUG)) { @@ -512,18 +512,7 @@ void nsTimerImpl::PostTimerEvent() gThread->AddTimer(this); } - PRThread *thread; - nsresult rv = mCallingThread->GetPRThread(&thread); - if (NS_FAILED(rv)) { - NS_WARNING("Dropping timer event because thread is dead"); - return; - } - - nsCOMPtr queue; - if (gThread) - gThread->mEventQueueService->GetThreadEventQueue(thread, getter_AddRefs(queue)); - if (queue) - queue->PostEvent(event); + mCallingThread->Dispatch(event, NS_DISPATCH_NORMAL); } void nsTimerImpl::SetDelayInternal(PRUint32 aDelay) @@ -614,7 +603,7 @@ nsresult nsTimerManager::AddIdleTimer(nsITimer* timer) NS_IMETHODIMP nsTimerManager::FireNextIdleTimer() { - if (!gFireOnIdle || !nsIThread::IsMainThread()) { + if (!gFireOnIdle || !NS_IsMainThread()) { return NS_OK; } diff --git a/mozilla/xpcom/threads/nsTimerImpl.h b/mozilla/xpcom/threads/nsTimerImpl.h index 98596f4e918..731de2c4d80 100644 --- a/mozilla/xpcom/threads/nsTimerImpl.h +++ b/mozilla/xpcom/threads/nsTimerImpl.h @@ -108,7 +108,6 @@ public: private: ~nsTimerImpl(); - nsresult InitCommon(PRUint32 aType, PRUint32 aDelay); void ReleaseCallback() diff --git a/mozilla/xpfe/appshell/src/nsAppShellService.cpp b/mozilla/xpfe/appshell/src/nsAppShellService.cpp index 66993023b64..6f4137d8cce 100644 --- a/mozilla/xpfe/appshell/src/nsAppShellService.cpp +++ b/mozilla/xpfe/appshell/src/nsAppShellService.cpp @@ -44,7 +44,6 @@ #include "nsIURL.h" #include "nsNetUtil.h" #include "nsIServiceManager.h" -#include "nsIEventQueueService.h" #include "nsIObserverService.h" #include "nsIObserver.h" #include "nsIXPConnect.h" @@ -63,7 +62,6 @@ #include "nsCRT.h" #include "nsITimelineService.h" #include "prprf.h" -#include "plevent.h" #include "nsWidgetsCID.h" #include "nsIRequestObserver.h" diff --git a/mozilla/xpfe/appshell/src/nsWebShellWindow.cpp b/mozilla/xpfe/appshell/src/nsWebShellWindow.cpp index a16b00001a5..f67ef5c71a0 100644 --- a/mozilla/xpfe/appshell/src/nsWebShellWindow.cpp +++ b/mozilla/xpfe/appshell/src/nsWebShellWindow.cpp @@ -81,8 +81,6 @@ #include "nsIMenuListener.h" #include "nsITimer.h" -#include "nsIEventQueueService.h" -#include "plevent.h" #include "prmem.h" #include "prlock.h" diff --git a/mozilla/xpfe/appshell/src/nsXULWindow.cpp b/mozilla/xpfe/appshell/src/nsXULWindow.cpp index fcb7ac76556..55229f80675 100644 --- a/mozilla/xpfe/appshell/src/nsXULWindow.cpp +++ b/mozilla/xpfe/appshell/src/nsXULWindow.cpp @@ -1,5 +1,6 @@ -/* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 ci et: */ +/* * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -47,6 +48,8 @@ #include "nsWidgetsCID.h" #include "prprf.h" #include "nsCRT.h" +#include "nsThreadUtils.h" +#include "nsNetCID.h" //Interfaces needed to be included #include "nsIAppShell.h" @@ -77,7 +80,8 @@ #include "nsIScreenManager.h" #include "nsIScreen.h" #include "nsIScrollable.h" -#include "nsIPref.h" +#include "nsIPrefService.h" +#include "nsIPrefBranch.h" #include "nsIScriptSecurityManager.h" #include "nsIWindowWatcher.h" #include "nsIURI.h" @@ -106,25 +110,30 @@ #define ZLEVEL_ATTRIBUTE NS_LITERAL_STRING("zlevel") // CIDs static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID); -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); -static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID); -static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID); static NS_DEFINE_CID(kWindowMediatorCID, NS_WINDOWMEDIATOR_CID); //***************************************************************************** //*** nsXULWindow: Object Management //***************************************************************************** -nsXULWindow::nsXULWindow() : mChromeTreeOwner(nsnull), - mContentTreeOwner(nsnull), mPrimaryContentTreeOwner(nsnull), - mModalStatus(NS_OK), mContinueModalLoop(PR_FALSE), - mDebuting(PR_FALSE), mChromeLoaded(PR_FALSE), - mShowAfterLoad(PR_FALSE), mIntrinsicallySized(PR_FALSE), - mCenterAfterLoad(PR_FALSE), mIsHiddenWindow(PR_FALSE), - mLockedUntilChromeLoad(PR_FALSE), - mContextFlags(0), mBlurSuppressionLevel(0), - mPersistentAttributesDirty(0), mPersistentAttributesMask(0), - mChromeFlags(nsIWebBrowserChrome::CHROME_ALL) +nsXULWindow::nsXULWindow() + : mChromeTreeOwner(nsnull), + mContentTreeOwner(nsnull), + mPrimaryContentTreeOwner(nsnull), + mModalStatus(NS_OK), + mContinueModalLoop(PR_FALSE), + mDebuting(PR_FALSE), + mChromeLoaded(PR_FALSE), + mShowAfterLoad(PR_FALSE), + mIntrinsicallySized(PR_FALSE), + mCenterAfterLoad(PR_FALSE), + mIsHiddenWindow(PR_FALSE), + mLockedUntilChromeLoad(PR_FALSE), + mContextFlags(0), + mBlurSuppressionLevel(0), + mPersistentAttributesDirty(0), + mPersistentAttributesMask(0), + mChromeFlags(nsIWebBrowserChrome::CHROME_ALL) { } @@ -141,14 +150,14 @@ NS_IMPL_THREADSAFE_ADDREF(nsXULWindow) NS_IMPL_THREADSAFE_RELEASE(nsXULWindow) NS_INTERFACE_MAP_BEGIN(nsXULWindow) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXULWindow) - NS_INTERFACE_MAP_ENTRY(nsIXULWindow) - NS_INTERFACE_MAP_ENTRY(nsIBaseWindow) - NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor) - NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) - if (aIID.Equals(NS_GET_IID(nsXULWindow))) - foundInterface = NS_REINTERPRET_CAST(nsISupports*, this); - else + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXULWindow) + NS_INTERFACE_MAP_ENTRY(nsIXULWindow) + NS_INTERFACE_MAP_ENTRY(nsIBaseWindow) + NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor) + NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) + if (aIID.Equals(NS_GET_IID(nsXULWindow))) + foundInterface = NS_REINTERPRET_CAST(nsISupports*, this); + else NS_INTERFACE_MAP_END //***************************************************************************** @@ -320,16 +329,16 @@ NS_IMETHODIMP nsXULWindow::SetChromeFlags(PRUint32 aChromeFlags) NS_IMETHODIMP nsXULWindow::SetIntrinsicallySized(PRBool aIntrinsicallySized) { - mIntrinsicallySized = aIntrinsicallySized; - return NS_OK; + mIntrinsicallySized = aIntrinsicallySized; + return NS_OK; } NS_IMETHODIMP nsXULWindow::GetIntrinsicallySized(PRBool* aIntrinsicallySized) { - NS_ENSURE_ARG_POINTER(aIntrinsicallySized); + NS_ENSURE_ARG_POINTER(aIntrinsicallySized); - *aIntrinsicallySized = mIntrinsicallySized; - return NS_OK; + *aIntrinsicallySized = mIntrinsicallySized; + return NS_OK; } NS_IMETHODIMP nsXULWindow::GetPrimaryContentShell(nsIDocShellTreeItem** @@ -361,8 +370,8 @@ NS_IMETHODIMP nsXULWindow::GetContentShellById(const PRUnichar* aID, NS_IMETHODIMP nsXULWindow::AddChildWindow(nsIXULWindow *aChild) { - // we're not really keeping track of this right now - return NS_OK; + // we're not really keeping track of this right now + return NS_OK; } NS_IMETHODIMP nsXULWindow::RemoveChildWindow(nsIXULWindow *aChild) @@ -373,11 +382,9 @@ NS_IMETHODIMP nsXULWindow::RemoveChildWindow(nsIXULWindow *aChild) NS_IMETHODIMP nsXULWindow::ShowModal() { - nsCOMPtr appShell(do_CreateInstance(kAppShellCID)); - NS_ENSURE_TRUE(appShell, NS_ERROR_FAILURE); + nsCOMPtr thread = do_GetCurrentThread(); + NS_ENSURE_STATE(thread); - appShell->Create(0, nsnull); - appShell->Spinup(); // Store locally so it doesn't die on us nsCOMPtr window = mWindow; nsCOMPtr tempRef = this; @@ -394,18 +401,8 @@ NS_IMETHODIMP nsXULWindow::ShowModal() nsCOMPtr stack(do_GetService("@mozilla.org/js/xpc/ContextStack;1")); nsresult rv = NS_OK; if (stack && NS_SUCCEEDED(stack->Push(nsnull))) { - while(NS_SUCCEEDED(rv) && mContinueModalLoop) { - void* data; - PRBool isRealEvent; - PRBool processEvent; - - rv = appShell->GetNativeEvent(isRealEvent, data); - if(NS_SUCCEEDED(rv)) { - window->ModalEventFilter(isRealEvent, data, &processEvent); - if(processEvent) - appShell->DispatchNativeEvent(isRealEvent, data); - } - } + while (NS_SUCCEEDED(rv) && mContinueModalLoop) + rv = thread->ProcessNextEvent(); JSContext* cx; stack->Pop(&cx); NS_ASSERTION(cx == nsnull, "JSContextStack mismatch"); @@ -428,7 +425,6 @@ NS_IMETHODIMP nsXULWindow::ShowModal() modal loop is always exited using ExitModalLoop (the other way would be to change the protected member variable directly.) */ - appShell->Spindown(); return mModalStatus; } @@ -440,49 +436,49 @@ NS_IMETHODIMP nsXULWindow::ShowModal() NS_IMETHODIMP nsXULWindow::InitWindow(nativeWindow aParentNativeWindow, nsIWidget* parentWidget, PRInt32 x, PRInt32 y, PRInt32 cx, PRInt32 cy) { - //XXX First Check In - NS_ASSERTION(PR_FALSE, "Not Yet Implemented"); - return NS_OK; + //XXX First Check In + NS_ASSERTION(PR_FALSE, "Not Yet Implemented"); + return NS_OK; } NS_IMETHODIMP nsXULWindow::Create() { - //XXX First Check In - NS_ASSERTION(PR_FALSE, "Not Yet Implemented"); - return NS_OK; + //XXX First Check In + NS_ASSERTION(PR_FALSE, "Not Yet Implemented"); + return NS_OK; } NS_IMETHODIMP nsXULWindow::Destroy() { - if(!mWindow) - return NS_OK; + if(!mWindow) + return NS_OK; - nsCOMPtr appShell(do_GetService(NS_APPSHELLSERVICE_CONTRACTID)); - NS_ASSERTION(appShell, "Couldn't get appShell... xpcom shutdown?"); - if(appShell) - appShell->UnregisterTopLevelWindow(NS_STATIC_CAST(nsIXULWindow*, this)); + nsCOMPtr appShell(do_GetService(NS_APPSHELLSERVICE_CONTRACTID)); + NS_ASSERTION(appShell, "Couldn't get appShell... xpcom shutdown?"); + if (appShell) + appShell->UnregisterTopLevelWindow(NS_STATIC_CAST(nsIXULWindow*, this)); - nsCOMPtr parentWindow(do_QueryReferent(mParentWindow)); - if (parentWindow) - parentWindow->RemoveChildWindow(this); + nsCOMPtr parentWindow(do_QueryReferent(mParentWindow)); + if (parentWindow) + parentWindow->RemoveChildWindow(this); - // let's make sure the window doesn't get deleted out from under us - // while we are trying to close....this can happen if the docshell - // we close ends up being the last owning reference to this xulwindow + // let's make sure the window doesn't get deleted out from under us + // while we are trying to close....this can happen if the docshell + // we close ends up being the last owning reference to this xulwindow - // XXXTAB This shouldn't be an issue anymore because the ownership model - // only goes in one direction. When webshell container is fully removed - // try removing this... + // XXXTAB This shouldn't be an issue anymore because the ownership model + // only goes in one direction. When webshell container is fully removed + // try removing this... - nsCOMPtr placeHolder = this; + nsCOMPtr placeHolder = this; - // Remove modality (if any) and hide while destroying. More than - // a convenience, the hide prevents user interaction with the partially - // destroyed window. This is especially necessary when the eldest window - // in a stack of modal windows is destroyed first. It happens. - ExitModalLoop(NS_OK); - if (mWindow) - mWindow->Show(PR_FALSE); + // Remove modality (if any) and hide while destroying. More than + // a convenience, the hide prevents user interaction with the partially + // destroyed window. This is especially necessary when the eldest window + // in a stack of modal windows is destroyed first. It happens. + ExitModalLoop(NS_OK); + if (mWindow) + mWindow->Show(PR_FALSE); #if defined(XP_WIN) || defined(XP_OS2) // We need to explicitly set the focus on Windows @@ -506,55 +502,56 @@ NS_IMETHODIMP nsXULWindow::Destroy() } #endif - mDOMWindow = nsnull; - if(mDocShell) { - nsCOMPtr shellAsWin(do_QueryInterface(mDocShell)); - shellAsWin->Destroy(); - mDocShell = nsnull; // this can cause reentrancy of this function - } + mDOMWindow = nsnull; + if (mDocShell) { + nsCOMPtr shellAsWin(do_QueryInterface(mDocShell)); + shellAsWin->Destroy(); + mDocShell = nsnull; // this can cause reentrancy of this function + } - // Remove our ref on the content shells - PRInt32 count; - count = mContentShells.Count(); - for(PRInt32 i = 0; i < count; i++) { - nsContentShellInfo* shellInfo = (nsContentShellInfo*)(mContentShells.ElementAt(i)); - delete shellInfo; - } - mContentShells.Clear(); - mPrimaryContentShell = nsnull; + // Remove our ref on the content shells + PRInt32 count; + count = mContentShells.Count(); + for (PRInt32 i = 0; i < count; i++) { + nsContentShellInfo* shellInfo = + NS_STATIC_CAST(nsContentShellInfo *, mContentShells.ElementAt(i)); + delete shellInfo; + } + mContentShells.Clear(); + mPrimaryContentShell = nsnull; - if(mContentTreeOwner) { - mContentTreeOwner->XULWindow(nsnull); - NS_RELEASE(mContentTreeOwner); - } - if(mPrimaryContentTreeOwner) { - mPrimaryContentTreeOwner->XULWindow(nsnull); - NS_RELEASE(mPrimaryContentTreeOwner); - } - if(mChromeTreeOwner) { - mChromeTreeOwner->XULWindow(nsnull); - NS_RELEASE(mChromeTreeOwner); - } - if(mWindow) { - mWindow->SetClientData(0); // nsWebShellWindow hackery - mWindow = nsnull; - } + if(mContentTreeOwner) { + mContentTreeOwner->XULWindow(nsnull); + NS_RELEASE(mContentTreeOwner); + } + if(mPrimaryContentTreeOwner) { + mPrimaryContentTreeOwner->XULWindow(nsnull); + NS_RELEASE(mPrimaryContentTreeOwner); + } + if(mChromeTreeOwner) { + mChromeTreeOwner->XULWindow(nsnull); + NS_RELEASE(mChromeTreeOwner); + } + if(mWindow) { + mWindow->SetClientData(0); // nsWebShellWindow hackery + mWindow = nsnull; + } - if (!mIsHiddenWindow) { - /* Inform appstartup we've destroyed this window and it could - quit now if it wanted. This must happen at least after mDocShell - is destroyed, because onunload handlers fire then, and those being - script, anything could happen. A new window could open, even. - See bug 130719. */ - nsCOMPtr obssvc = - do_GetService("@mozilla.org/observer-service;1"); - NS_ASSERTION(obssvc, "Couldn't get observer service?"); + if (!mIsHiddenWindow) { + /* Inform appstartup we've destroyed this window and it could + quit now if it wanted. This must happen at least after mDocShell + is destroyed, because onunload handlers fire then, and those being + script, anything could happen. A new window could open, even. + See bug 130719. */ + nsCOMPtr obssvc = + do_GetService("@mozilla.org/observer-service;1"); + NS_ASSERTION(obssvc, "Couldn't get observer service?"); - if (obssvc) - obssvc->NotifyObservers(nsnull, "xul-window-destroyed", nsnull); - } + if (obssvc) + obssvc->NotifyObservers(nsnull, "xul-window-destroyed", nsnull); + } - return NS_OK; + return NS_OK; } NS_IMETHODIMP nsXULWindow::SetPosition(PRInt32 aX, PRInt32 aY) @@ -572,7 +569,7 @@ NS_IMETHODIMP nsXULWindow::SetPosition(PRInt32 aX, PRInt32 aY) NS_IMETHODIMP nsXULWindow::GetPosition(PRInt32* aX, PRInt32* aY) { - return GetPositionAndSize(aX, aY, nsnull, nsnull); + return GetPositionAndSize(aX, aY, nsnull, nsnull); } NS_IMETHODIMP nsXULWindow::SetSize(PRInt32 aCX, PRInt32 aCY, PRBool aRepaint) @@ -697,44 +694,44 @@ NS_IMETHODIMP nsXULWindow::Center(nsIXULWindow *aRelative, PRBool aScreen, PRBoo NS_IMETHODIMP nsXULWindow::Repaint(PRBool aForce) { - //XXX First Check In - NS_ASSERTION(PR_FALSE, "Not Yet Implemented"); - return NS_OK; + //XXX First Check In + NS_ASSERTION(PR_FALSE, "Not Yet Implemented"); + return NS_OK; } NS_IMETHODIMP nsXULWindow::GetParentWidget(nsIWidget** aParentWidget) { - NS_ENSURE_ARG_POINTER(aParentWidget); - NS_ENSURE_STATE(mWindow); + NS_ENSURE_ARG_POINTER(aParentWidget); + NS_ENSURE_STATE(mWindow); - *aParentWidget = mWindow->GetParent(); - return NS_OK; + *aParentWidget = mWindow->GetParent(); + return NS_OK; } NS_IMETHODIMP nsXULWindow::SetParentWidget(nsIWidget* aParentWidget) { - //XXX First Check In - NS_ASSERTION(PR_FALSE, "Not Yet Implemented"); - return NS_OK; + //XXX First Check In + NS_ASSERTION(PR_FALSE, "Not Yet Implemented"); + return NS_OK; } NS_IMETHODIMP nsXULWindow::GetParentNativeWindow(nativeWindow* aParentNativeWindow) { - NS_ENSURE_ARG_POINTER(aParentNativeWindow); + NS_ENSURE_ARG_POINTER(aParentNativeWindow); - nsCOMPtr parentWidget; - NS_ENSURE_SUCCESS(GetParentWidget(getter_AddRefs(parentWidget)), NS_ERROR_FAILURE); + nsCOMPtr parentWidget; + NS_ENSURE_SUCCESS(GetParentWidget(getter_AddRefs(parentWidget)), NS_ERROR_FAILURE); - *aParentNativeWindow = parentWidget->GetNativeData(NS_NATIVE_WIDGET); + *aParentNativeWindow = parentWidget->GetNativeData(NS_NATIVE_WIDGET); - return NS_OK; + return NS_OK; } NS_IMETHODIMP nsXULWindow::SetParentNativeWindow(nativeWindow aParentNativeWindow) { - //XXX First Check In - NS_ASSERTION(PR_FALSE, "Not Yet Implemented"); - return NS_OK; + //XXX First Check In + NS_ASSERTION(PR_FALSE, "Not Yet Implemented"); + return NS_OK; } NS_IMETHODIMP nsXULWindow::GetVisibility(PRBool* aVisibility) @@ -751,41 +748,39 @@ NS_IMETHODIMP nsXULWindow::GetVisibility(PRBool* aVisibility) NS_IMETHODIMP nsXULWindow::SetVisibility(PRBool aVisibility) { - NS_TIMELINE_ENTER("nsXULWindow::SetVisibility."); - if(!mChromeLoaded) - { - mShowAfterLoad = aVisibility; - NS_TIMELINE_LEAVE("nsXULWindow::SetVisibility"); - return NS_OK; - } + NS_TIMELINE_ENTER("nsXULWindow::SetVisibility."); + if (!mChromeLoaded) { + mShowAfterLoad = aVisibility; + NS_TIMELINE_LEAVE("nsXULWindow::SetVisibility"); + return NS_OK; + } - if(mDebuting) { - NS_TIMELINE_LEAVE("nsXULWindow::SetVisibility"); - return NS_OK; - } - mDebuting = PR_TRUE; // (Show / Focus is recursive) + if(mDebuting) { + NS_TIMELINE_LEAVE("nsXULWindow::SetVisibility"); + return NS_OK; + } + mDebuting = PR_TRUE; // (Show / Focus is recursive) - //XXXTAB Do we really need to show docshell and the window? Isn't - // the window good enough? - nsCOMPtr shellAsWin(do_QueryInterface(mDocShell)); - shellAsWin->SetVisibility(aVisibility); - mWindow->Show(aVisibility); + //XXXTAB Do we really need to show docshell and the window? Isn't + // the window good enough? + nsCOMPtr shellAsWin(do_QueryInterface(mDocShell)); + shellAsWin->SetVisibility(aVisibility); + mWindow->Show(aVisibility); - nsCOMPtr windowMediator(do_GetService(kWindowMediatorCID)); - if(windowMediator) - windowMediator->UpdateWindowTimeStamp(NS_STATIC_CAST(nsIXULWindow*, this)); + nsCOMPtr windowMediator(do_GetService(kWindowMediatorCID)); + if (windowMediator) + windowMediator->UpdateWindowTimeStamp(NS_STATIC_CAST(nsIXULWindow*, this)); - // notify observers so that we can hide the splash screen if possible - nsCOMPtr obssvc - (do_GetService("@mozilla.org/observer-service;1")); - NS_WARN_IF_FALSE(obssvc, "Couldn't get observer service."); - if (obssvc) { - obssvc->NotifyObservers(nsnull, "xul-window-visible", nsnull); - } + // notify observers so that we can hide the splash screen if possible + nsCOMPtr obssvc = + do_GetService("@mozilla.org/observer-service;1"); + NS_WARN_IF_FALSE(obssvc, "Couldn't get observer service."); + if (obssvc) + obssvc->NotifyObservers(nsnull, "xul-window-visible", nsnull); - mDebuting = PR_FALSE; - NS_TIMELINE_LEAVE("nsXULWindow::SetVisibility"); - return NS_OK; + mDebuting = PR_FALSE; + NS_TIMELINE_LEAVE("nsXULWindow::SetVisibility"); + return NS_OK; } NS_IMETHODIMP nsXULWindow::GetEnabled(PRBool *aEnabled) @@ -833,45 +828,45 @@ NS_IMETHODIMP nsXULWindow::SetBlurSuppression(PRBool aBlurSuppression) NS_IMETHODIMP nsXULWindow::GetMainWidget(nsIWidget** aMainWidget) { - NS_ENSURE_ARG_POINTER(aMainWidget); + NS_ENSURE_ARG_POINTER(aMainWidget); - *aMainWidget = mWindow; - NS_IF_ADDREF(*aMainWidget); - return NS_OK; + *aMainWidget = mWindow; + NS_IF_ADDREF(*aMainWidget); + return NS_OK; } NS_IMETHODIMP nsXULWindow::SetFocus() { - //XXX First Check In - NS_ASSERTION(PR_FALSE, "Not Yet Implemented"); - return NS_OK; + //XXX First Check In + NS_ASSERTION(PR_FALSE, "Not Yet Implemented"); + return NS_OK; } NS_IMETHODIMP nsXULWindow::GetTitle(PRUnichar** aTitle) { - NS_ENSURE_ARG_POINTER(aTitle); + NS_ENSURE_ARG_POINTER(aTitle); - *aTitle = ToNewUnicode(mTitle); - if (!*aTitle) - return NS_ERROR_OUT_OF_MEMORY; - return NS_OK; + *aTitle = ToNewUnicode(mTitle); + if (!*aTitle) + return NS_ERROR_OUT_OF_MEMORY; + return NS_OK; } NS_IMETHODIMP nsXULWindow::SetTitle(const PRUnichar* aTitle) { - NS_ENSURE_STATE(mWindow); - mTitle.Assign(aTitle); - mTitle.StripChars("\n\r"); - NS_ENSURE_SUCCESS(mWindow->SetTitle(mTitle), NS_ERROR_FAILURE); + NS_ENSURE_STATE(mWindow); + mTitle.Assign(aTitle); + mTitle.StripChars("\n\r"); + NS_ENSURE_SUCCESS(mWindow->SetTitle(mTitle), NS_ERROR_FAILURE); - // Tell the window mediator that a title has changed - nsCOMPtr windowMediator(do_GetService(kWindowMediatorCID)); - if(!windowMediator) - return NS_OK; + // Tell the window mediator that a title has changed + nsCOMPtr windowMediator(do_GetService(kWindowMediatorCID)); + if(!windowMediator) + return NS_OK; - windowMediator->UpdateWindowTitle(NS_STATIC_CAST(nsIXULWindow*, this), aTitle); + windowMediator->UpdateWindowTitle(NS_STATIC_CAST(nsIXULWindow*, this), aTitle); - return NS_OK; + return NS_OK; } @@ -881,74 +876,75 @@ NS_IMETHODIMP nsXULWindow::SetTitle(const PRUnichar* aTitle) NS_IMETHODIMP nsXULWindow::EnsureChromeTreeOwner() { - if(mChromeTreeOwner) - return NS_OK; + if (mChromeTreeOwner) + return NS_OK; - mChromeTreeOwner = new nsChromeTreeOwner(); - NS_ENSURE_TRUE(mChromeTreeOwner, NS_ERROR_OUT_OF_MEMORY); + mChromeTreeOwner = new nsChromeTreeOwner(); + NS_ENSURE_TRUE(mChromeTreeOwner, NS_ERROR_OUT_OF_MEMORY); - NS_ADDREF(mChromeTreeOwner); - mChromeTreeOwner->XULWindow(this); + NS_ADDREF(mChromeTreeOwner); + mChromeTreeOwner->XULWindow(this); - return NS_OK; + return NS_OK; } NS_IMETHODIMP nsXULWindow::EnsureContentTreeOwner() { - if(mContentTreeOwner) - return NS_OK; + if (mContentTreeOwner) + return NS_OK; - mContentTreeOwner = new nsContentTreeOwner(PR_FALSE); - NS_ENSURE_TRUE(mContentTreeOwner, NS_ERROR_FAILURE); + mContentTreeOwner = new nsContentTreeOwner(PR_FALSE); + NS_ENSURE_TRUE(mContentTreeOwner, NS_ERROR_FAILURE); - NS_ADDREF(mContentTreeOwner); - mContentTreeOwner->XULWindow(this); + NS_ADDREF(mContentTreeOwner); + mContentTreeOwner->XULWindow(this); - return NS_OK; + return NS_OK; } NS_IMETHODIMP nsXULWindow::EnsurePrimaryContentTreeOwner() { - if(mPrimaryContentTreeOwner) - return NS_OK; + if (mPrimaryContentTreeOwner) + return NS_OK; - mPrimaryContentTreeOwner = new nsContentTreeOwner(PR_TRUE); - NS_ENSURE_TRUE(mPrimaryContentTreeOwner, NS_ERROR_FAILURE); + mPrimaryContentTreeOwner = new nsContentTreeOwner(PR_TRUE); + NS_ENSURE_TRUE(mPrimaryContentTreeOwner, NS_ERROR_FAILURE); - NS_ADDREF(mPrimaryContentTreeOwner); - mPrimaryContentTreeOwner->XULWindow(this); + NS_ADDREF(mPrimaryContentTreeOwner); + mPrimaryContentTreeOwner->XULWindow(this); - return NS_OK; + return NS_OK; } NS_IMETHODIMP nsXULWindow::EnsurePrompter() { - if (mPrompter) - return NS_OK; + if (mPrompter) + return NS_OK; - nsCOMPtr ourWindow; - nsresult rv = GetWindowDOMWindow(getter_AddRefs(ourWindow)); - if (NS_SUCCEEDED(rv)) { - nsCOMPtr wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID)); - if (wwatch) - wwatch->GetNewPrompter(ourWindow, getter_AddRefs(mPrompter)); - } - return mPrompter ? NS_OK : NS_ERROR_FAILURE; + nsCOMPtr ourWindow; + nsresult rv = GetWindowDOMWindow(getter_AddRefs(ourWindow)); + if (NS_SUCCEEDED(rv)) { + nsCOMPtr wwatch = + do_GetService(NS_WINDOWWATCHER_CONTRACTID); + if (wwatch) + wwatch->GetNewPrompter(ourWindow, getter_AddRefs(mPrompter)); + } + return mPrompter ? NS_OK : NS_ERROR_FAILURE; } NS_IMETHODIMP nsXULWindow::EnsureAuthPrompter() { - if (mAuthPrompter) - return NS_OK; + if (mAuthPrompter) + return NS_OK; - nsCOMPtr ourWindow; - nsresult rv = GetWindowDOMWindow(getter_AddRefs(ourWindow)); - if (NS_SUCCEEDED(rv)) { - nsCOMPtr wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID)); - if (wwatch) - wwatch->GetNewAuthPrompter(ourWindow, getter_AddRefs(mAuthPrompter)); - } - return mAuthPrompter ? NS_OK : NS_ERROR_FAILURE; + nsCOMPtr ourWindow; + nsresult rv = GetWindowDOMWindow(getter_AddRefs(ourWindow)); + if (NS_SUCCEEDED(rv)) { + nsCOMPtr wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID)); + if (wwatch) + wwatch->GetNewAuthPrompter(ourWindow, getter_AddRefs(mAuthPrompter)); + } + return mAuthPrompter ? NS_OK : NS_ERROR_FAILURE; } void nsXULWindow::OnChromeLoaded() @@ -1366,62 +1362,62 @@ NS_IMETHODIMP nsXULWindow::LoadWindowClassFromXUL() NS_IMETHODIMP nsXULWindow::LoadIconFromXUL() { - NS_ENSURE_STATE(mWindow); + NS_ENSURE_STATE(mWindow); - // Get element. - nsCOMPtr windowElement; - GetWindowDOMElement(getter_AddRefs(windowElement)); - NS_ENSURE_TRUE(windowElement, NS_ERROR_FAILURE); + // Get element. + nsCOMPtr windowElement; + GetWindowDOMElement(getter_AddRefs(windowElement)); + NS_ENSURE_TRUE(windowElement, NS_ERROR_FAILURE); - // XXX The following code is being #if 0'd out since it - // basically does nothing until bug 70974 is fixed. - // After bug 70974 is fixed, we will also need to implement - // computed style for that property before this will - // be of any use. And even then, it will *still* - // do nothing on platforms which don't implement - // nsWindow::SetIcon(). See bug 76211 for that. - // Also see bug 57576 and its dependency tree. + // XXX The following code is being #if 0'd out since it + // basically does nothing until bug 70974 is fixed. + // After bug 70974 is fixed, we will also need to implement + // computed style for that property before this will + // be of any use. And even then, it will *still* + // do nothing on platforms which don't implement + // nsWindow::SetIcon(). See bug 76211 for that. + // Also see bug 57576 and its dependency tree. #if 0 - // Get document in which this is contained. - nsCOMPtr document; - windowElement->GetOwnerDocument(getter_AddRefs(document)); - NS_ENSURE_TRUE(document, NS_ERROR_FAILURE); + // Get document in which this is contained. + nsCOMPtr document; + windowElement->GetOwnerDocument(getter_AddRefs(document)); + NS_ENSURE_TRUE(document, NS_ERROR_FAILURE); - // Get document view. - nsCOMPtr docView(do_QueryInterface(document)); - NS_ENSURE_TRUE(docView, NS_ERROR_FAILURE); + // Get document view. + nsCOMPtr docView(do_QueryInterface(document)); + NS_ENSURE_TRUE(docView, NS_ERROR_FAILURE); - // Get default/abstract view. - nsCOMPtr abstractView; - docView->GetDefaultView(getter_AddRefs(abstractView)); - NS_ENSURE_TRUE(abstractView, NS_ERROR_FAILURE); + // Get default/abstract view. + nsCOMPtr abstractView; + docView->GetDefaultView(getter_AddRefs(abstractView)); + NS_ENSURE_TRUE(abstractView, NS_ERROR_FAILURE); - // Get "view CSS." - nsCOMPtr viewCSS(do_QueryInterface(abstractView)); - NS_ENSURE_TRUE(viewCSS, NS_ERROR_FAILURE); + // Get "view CSS." + nsCOMPtr viewCSS(do_QueryInterface(abstractView)); + NS_ENSURE_TRUE(viewCSS, NS_ERROR_FAILURE); - // Next, get CSS style declaration. - nsCOMPtr cssDecl; - viewCSS->GetComputedStyle(windowElement, EmptyString(), - getter_AddRefs(cssDecl)); - NS_ENSURE_TRUE(cssDecl, NS_ERROR_FAILURE); + // Next, get CSS style declaration. + nsCOMPtr cssDecl; + viewCSS->GetComputedStyle(windowElement, EmptyString(), + getter_AddRefs(cssDecl)); + NS_ENSURE_TRUE(cssDecl, NS_ERROR_FAILURE); - // Whew. Now get "list-style-image" property value. - nsAutoString windowIcon; - windowIcon.AssignLiteral("-moz-window-icon"); - nsAutoString icon; - cssDecl->GetPropertyValue(windowIcon, icon); + // Whew. Now get "list-style-image" property value. + nsAutoString windowIcon; + windowIcon.AssignLiteral("-moz-window-icon"); + nsAutoString icon; + cssDecl->GetPropertyValue(windowIcon, icon); #endif - nsAutoString id; - windowElement->GetAttribute(NS_LITERAL_STRING("id"), id); + nsAutoString id; + windowElement->GetAttribute(NS_LITERAL_STRING("id"), id); - if (id.IsEmpty()) { - id.AssignLiteral("default"); - } + if (id.IsEmpty()) { + id.AssignLiteral("default"); + } - mWindow->SetIcon(id); - return NS_OK; + mWindow->SetIcon(id); + return NS_OK; } NS_IMETHODIMP nsXULWindow::SavePersistentAttributes() @@ -1541,69 +1537,69 @@ NS_IMETHODIMP nsXULWindow::SavePersistentAttributes() NS_IMETHODIMP nsXULWindow::GetWindowDOMWindow(nsIDOMWindowInternal** aDOMWindow) { - NS_ENSURE_STATE(mDocShell); + NS_ENSURE_STATE(mDocShell); - if(!mDOMWindow) - mDOMWindow = do_GetInterface(mDocShell); - NS_ENSURE_TRUE(mDOMWindow, NS_ERROR_FAILURE); + if (!mDOMWindow) + mDOMWindow = do_GetInterface(mDocShell); + NS_ENSURE_TRUE(mDOMWindow, NS_ERROR_FAILURE); - *aDOMWindow = mDOMWindow; - NS_ADDREF(*aDOMWindow); - return NS_OK; + *aDOMWindow = mDOMWindow; + NS_ADDREF(*aDOMWindow); + return NS_OK; } NS_IMETHODIMP nsXULWindow::GetWindowDOMElement(nsIDOMElement** aDOMElement) { - NS_ENSURE_STATE(mDocShell); - NS_ENSURE_ARG_POINTER(aDOMElement); + NS_ENSURE_STATE(mDocShell); + NS_ENSURE_ARG_POINTER(aDOMElement); - *aDOMElement = nsnull; + *aDOMElement = nsnull; - nsCOMPtr cv; - - mDocShell->GetContentViewer(getter_AddRefs(cv)); - NS_ENSURE_TRUE(cv, NS_ERROR_FAILURE); + nsCOMPtr cv; - nsCOMPtr docv(do_QueryInterface(cv)); - NS_ENSURE_TRUE(docv, NS_ERROR_FAILURE); + mDocShell->GetContentViewer(getter_AddRefs(cv)); + NS_ENSURE_TRUE(cv, NS_ERROR_FAILURE); - nsCOMPtr doc; - docv->GetDocument(getter_AddRefs(doc)); - nsCOMPtr domdoc(do_QueryInterface(doc)); - NS_ENSURE_TRUE(domdoc, NS_ERROR_FAILURE); + nsCOMPtr docv(do_QueryInterface(cv)); + NS_ENSURE_TRUE(docv, NS_ERROR_FAILURE); - domdoc->GetDocumentElement(aDOMElement); - NS_ENSURE_TRUE(*aDOMElement, NS_ERROR_FAILURE); + nsCOMPtr doc; + docv->GetDocument(getter_AddRefs(doc)); + nsCOMPtr domdoc(do_QueryInterface(doc)); + NS_ENSURE_TRUE(domdoc, NS_ERROR_FAILURE); - return NS_OK; + domdoc->GetDocumentElement(aDOMElement); + NS_ENSURE_TRUE(*aDOMElement, NS_ERROR_FAILURE); + + return NS_OK; } NS_IMETHODIMP nsXULWindow::GetDOMElementById(char* aID, nsIDOMElement** aDOMElement) { - NS_ENSURE_STATE(mDocShell); - NS_ENSURE_ARG_POINTER(aDOMElement); + NS_ENSURE_STATE(mDocShell); + NS_ENSURE_ARG_POINTER(aDOMElement); - *aDOMElement = nsnull; + *aDOMElement = nsnull; - nsCOMPtr cv; - - mDocShell->GetContentViewer(getter_AddRefs(cv)); - if(!cv) - return NS_ERROR_FAILURE; + nsCOMPtr cv; - nsCOMPtr docv(do_QueryInterface(cv)); - if(!docv) - return NS_ERROR_FAILURE; + mDocShell->GetContentViewer(getter_AddRefs(cv)); + if(!cv) + return NS_ERROR_FAILURE; - nsCOMPtr doc; - docv->GetDocument(getter_AddRefs(doc)); - nsCOMPtr domdoc(do_QueryInterface(doc)); - if(!domdoc) - return NS_ERROR_FAILURE; - - NS_ENSURE_SUCCESS(domdoc->GetElementById(NS_ConvertASCIItoUTF16(aID), aDOMElement), NS_ERROR_FAILURE); + nsCOMPtr docv(do_QueryInterface(cv)); + if(!docv) + return NS_ERROR_FAILURE; - return NS_OK; + nsCOMPtr doc; + docv->GetDocument(getter_AddRefs(doc)); + nsCOMPtr domdoc(do_QueryInterface(doc)); + if(!domdoc) + return NS_ERROR_FAILURE; + + NS_ENSURE_SUCCESS(domdoc->GetElementById(NS_ConvertASCIItoUTF16(aID), aDOMElement), NS_ERROR_FAILURE); + + return NS_OK; } nsresult nsXULWindow::ContentShellAdded(nsIDocShellTreeItem* aContentShell, @@ -1693,31 +1689,30 @@ nsresult nsXULWindow::ContentShellRemoved(nsIDocShellTreeItem* aContentShell) NS_IMETHODIMP nsXULWindow::SizeShellTo(nsIDocShellTreeItem* aShellItem, PRInt32 aCX, PRInt32 aCY) { - // XXXTAB This is wrong, we should actually reflow based on the passed in' - // shell. For now we are hacking and doing delta sizing. This is bad - // because it assumes all size we add will go to the shell which probably - // won't happen. + // XXXTAB This is wrong, we should actually reflow based on the passed in + // shell. For now we are hacking and doing delta sizing. This is bad + // because it assumes all size we add will go to the shell which probably + // won't happen. - nsCOMPtr shellAsWin(do_QueryInterface(aShellItem)); - NS_ENSURE_TRUE(shellAsWin, NS_ERROR_FAILURE); + nsCOMPtr shellAsWin(do_QueryInterface(aShellItem)); + NS_ENSURE_TRUE(shellAsWin, NS_ERROR_FAILURE); - PRInt32 width = 0; - PRInt32 height = 0; - shellAsWin->GetSize(&width, &height); + PRInt32 width = 0; + PRInt32 height = 0; + shellAsWin->GetSize(&width, &height); - PRInt32 widthDelta = aCX - width; - PRInt32 heightDelta = aCY - height; + PRInt32 widthDelta = aCX - width; + PRInt32 heightDelta = aCY - height; - if(widthDelta || heightDelta) - { - PRInt32 winCX = 0; - PRInt32 winCY = 0; + if (widthDelta || heightDelta) { + PRInt32 winCX = 0; + PRInt32 winCY = 0; - GetSize(&winCX, &winCY); - SetSize(winCX + widthDelta, winCY + heightDelta, PR_TRUE); - } + GetSize(&winCX, &winCY); + SetSize(winCX + widthDelta, winCY + heightDelta, PR_TRUE); + } - return NS_OK; + return NS_OK; } NS_IMETHODIMP nsXULWindow::ExitModalLoop(nsresult aStatus) @@ -1743,127 +1738,103 @@ NS_IMETHODIMP nsXULWindow::CreateNewWindow(PRInt32 aChromeFlags, NS_IMETHODIMP nsXULWindow::CreateNewChromeWindow(PRInt32 aChromeFlags, nsIAppShell* aAppShell, nsIXULWindow **_retval) { - NS_TIMELINE_ENTER("nsXULWindow::CreateNewChromeWindow"); - nsCOMPtr appShell(do_GetService(NS_APPSHELLSERVICE_CONTRACTID)); - NS_ENSURE_TRUE(appShell, NS_ERROR_FAILURE); - - // Just do a normal create of a window and return. - //XXXTAB remove this when appshell talks in terms of nsIXULWindow - nsCOMPtr parent; - if(aChromeFlags & nsIWebBrowserChrome::CHROME_DEPENDENT) - parent = this; + NS_TIMELINE_ENTER("nsXULWindow::CreateNewChromeWindow"); + nsCOMPtr appShell(do_GetService(NS_APPSHELLSERVICE_CONTRACTID)); + NS_ENSURE_TRUE(appShell, NS_ERROR_FAILURE); - nsCOMPtr newWindow; - appShell->CreateTopLevelWindow(parent, nsnull, aChromeFlags, - nsIAppShellService::SIZE_TO_CONTENT, - nsIAppShellService::SIZE_TO_CONTENT, - aAppShell, getter_AddRefs(newWindow)); + // Just do a normal create of a window and return. + //XXXTAB remove this when appshell talks in terms of nsIXULWindow + nsCOMPtr parent; + if(aChromeFlags & nsIWebBrowserChrome::CHROME_DEPENDENT) + parent = this; - NS_ENSURE_TRUE(newWindow, NS_ERROR_FAILURE); + nsCOMPtr newWindow; + appShell->CreateTopLevelWindow(parent, nsnull, aChromeFlags, + nsIAppShellService::SIZE_TO_CONTENT, + nsIAppShellService::SIZE_TO_CONTENT, + aAppShell, getter_AddRefs(newWindow)); - newWindow->SetChromeFlags(aChromeFlags); + NS_ENSURE_TRUE(newWindow, NS_ERROR_FAILURE); - *_retval = newWindow; - NS_ADDREF(*_retval); - - NS_TIMELINE_LEAVE("nsXULWindow::CreateNewChromeWindow done"); - return NS_OK; + newWindow->SetChromeFlags(aChromeFlags); + + *_retval = newWindow; + NS_ADDREF(*_retval); + + NS_TIMELINE_LEAVE("nsXULWindow::CreateNewChromeWindow done"); + return NS_OK; } NS_IMETHODIMP nsXULWindow::CreateNewContentWindow(PRInt32 aChromeFlags, nsIAppShell* aAppShell, nsIXULWindow **_retval) { - NS_TIMELINE_ENTER("nsXULWindow::CreateNewContentWindow"); - nsCOMPtr appShell(do_GetService(NS_APPSHELLSERVICE_CONTRACTID)); - NS_ENSURE_TRUE(appShell, NS_ERROR_FAILURE); + NS_TIMELINE_ENTER("nsXULWindow::CreateNewContentWindow"); - nsCOMPtr parent; - if(aChromeFlags & nsIWebBrowserChrome::CHROME_DEPENDENT) - parent = this; + nsCOMPtr thread = do_GetCurrentThread(); + NS_ENSURE_STATE(thread); - // We need to create a new top level window and then enter a nested - // loop. Eventually the new window will be told that it has loaded, - // at which time we know it is safe to spin out of the nested loop - // and allow the opening code to proceed. + nsCOMPtr appShell(do_GetService(NS_APPSHELLSERVICE_CONTRACTID)); + NS_ENSURE_TRUE(appShell, NS_ERROR_FAILURE); - // First push a nested event queue for event processing from netlib - // onto our UI thread queue stack. - nsEventQueueStack queuePusher; - NS_ENSURE_SUCCESS(queuePusher.Success(), NS_ERROR_FAILURE); + nsCOMPtr parent; + if (aChromeFlags & nsIWebBrowserChrome::CHROME_DEPENDENT) + parent = this; - nsCOMPtr uri; + // We need to create a new top level window and then enter a nested + // loop. Eventually the new window will be told that it has loaded, + // at which time we know it is safe to spin out of the nested loop + // and allow the opening code to proceed. - nsCOMPtr prefs(do_GetService(kPrefServiceCID)); - if (prefs) { - char *urlStr; - PRBool strAllocated = PR_TRUE; - nsresult prefres; - prefres = prefs->CopyCharPref("browser.chromeURL", &urlStr); - if (NS_SUCCEEDED(prefres) && urlStr[0] == '\0') { - PL_strfree(urlStr); - prefres = NS_ERROR_FAILURE; - } - if (NS_FAILED(prefres)) { - urlStr = "chrome://navigator/content/navigator.xul"; - strAllocated = PR_FALSE; - } + nsCOMPtr uri; - nsCOMPtr service(do_GetService(kIOServiceCID)); - if (service) - service->NewURI(nsDependentCString(urlStr), nsnull, nsnull, getter_AddRefs(uri)); - if (strAllocated) - PL_strfree(urlStr); - } - NS_ENSURE_TRUE(uri, NS_ERROR_FAILURE); + nsCOMPtr prefs(do_GetService(NS_PREFSERVICE_CONTRACTID)); + if (prefs) { + nsXPIDLCString urlStr; + nsresult prefres; + prefres = prefs->GetCharPref("browser.chromeURL", getter_Copies(urlStr)); + if (NS_SUCCEEDED(prefres) && urlStr.IsEmpty()) + prefres = NS_ERROR_FAILURE; + if (NS_FAILED(prefres)) + urlStr.AssignLiteral("chrome://navigator/content/navigator.xul"); - nsCOMPtr newWindow; - appShell->CreateTopLevelWindow(parent, uri, - aChromeFlags, 615, 480, aAppShell, - getter_AddRefs(newWindow)); + nsCOMPtr service(do_GetService(NS_IOSERVICE_CONTRACTID)); + if (service) + service->NewURI(urlStr, nsnull, nsnull, getter_AddRefs(uri)); + } + NS_ENSURE_TRUE(uri, NS_ERROR_FAILURE); - NS_ENSURE_TRUE(newWindow, NS_ERROR_FAILURE); + nsCOMPtr newWindow; + appShell->CreateTopLevelWindow(parent, uri, + aChromeFlags, 615, 480, aAppShell, + getter_AddRefs(newWindow)); - newWindow->SetChromeFlags(aChromeFlags); + NS_ENSURE_TRUE(newWindow, NS_ERROR_FAILURE); - nsCOMPtr subShell(do_CreateInstance(kAppShellCID)); - NS_ENSURE_TRUE(subShell, NS_ERROR_FAILURE); + newWindow->SetChromeFlags(aChromeFlags); - subShell->Create(0, nsnull); - subShell->Spinup(); + // Specify that we want the window to remain locked until the chrome has loaded. + nsXULWindow *xulWin = NS_STATIC_CAST(nsXULWindow*, + NS_STATIC_CAST(nsIXULWindow*, + newWindow)); - // Specify that we want the window to remain locked until the chrome has loaded. - nsXULWindow *xulWin = NS_STATIC_CAST(nsXULWindow*, - NS_STATIC_CAST(nsIXULWindow*, - newWindow)); + xulWin->LockUntilChromeLoad(); - xulWin->LockUntilChromeLoad(); + // Push nsnull onto the JSContext stack before we dispatch a native event. + nsCOMPtr stack(do_GetService("@mozilla.org/js/xpc/ContextStack;1")); + if (stack && NS_SUCCEEDED(stack->Push(nsnull))) { + nsresult looprv = NS_OK; + while (NS_SUCCEEDED(looprv) && xulWin->IsLocked()) + looprv = thread->ProcessNextEvent(); + JSContext *cx; + stack->Pop(&cx); + NS_ASSERTION(cx == nsnull, "JSContextStack mismatch"); + } - // Push nsnull onto the JSContext stack before we dispatch a native event. - nsCOMPtr stack(do_GetService("@mozilla.org/js/xpc/ContextStack;1")); - if(stack && NS_SUCCEEDED(stack->Push(nsnull))) - { - nsresult looprv = NS_OK; - while(NS_SUCCEEDED(looprv) && xulWin->IsLocked()) - { - void *data; - PRBool isRealEvent; - - looprv = subShell->GetNativeEvent(isRealEvent, data); - subShell->DispatchNativeEvent(isRealEvent, data); - } + *_retval = newWindow; + NS_ADDREF(*_retval); - JSContext *cx; - stack->Pop(&cx); - NS_ASSERTION(cx == nsnull, "JSContextStack mismatch"); - } - - subShell->Spindown(); - - *_retval = newWindow; - NS_ADDREF(*_retval); - - NS_TIMELINE_LEAVE("nsXULWindow::CreateNewContentWindow"); - return NS_OK; + NS_TIMELINE_LEAVE("nsXULWindow::CreateNewContentWindow"); + return NS_OK; } void nsXULWindow::EnableParent(PRBool aEnable) @@ -2027,8 +1998,8 @@ void nsXULWindow::PlaceWindowLayersBehind(PRUint32 aLowLevel, } } -void nsXULWindow::SetContentScrollbarVisibility(PRBool aVisible) { - +void nsXULWindow::SetContentScrollbarVisibility(PRBool aVisible) +{ nsCOMPtr contentWin(do_GetInterface(mPrimaryContentShell)); if (contentWin) { nsCOMPtr scrollbars; @@ -2038,8 +2009,8 @@ void nsXULWindow::SetContentScrollbarVisibility(PRBool aVisible) { } } -PRBool nsXULWindow::GetContentScrollbarVisibility() { - +PRBool nsXULWindow::GetContentScrollbarVisibility() +{ PRBool visible = PR_TRUE; nsCOMPtr contentWin(do_GetInterface(mPrimaryContentShell)); @@ -2053,8 +2024,8 @@ PRBool nsXULWindow::GetContentScrollbarVisibility() { } // during spinup, attributes that haven't been loaded yet can't be dirty -void nsXULWindow::PersistentAttributesDirty(PRUint32 aDirtyFlags) { - +void nsXULWindow::PersistentAttributesDirty(PRUint32 aDirtyFlags) +{ mPersistentAttributesDirty |= aDirtyFlags & mPersistentAttributesMask; } @@ -2139,29 +2110,3 @@ nsContentShellInfo::~nsContentShellInfo() { //XXX Set Tree Owner to null if the tree owner is nsXULWindow->mContentTreeOwner } - -//***************************************************************************** -//*** nsEventQueueStack: Object Implementation -//***************************************************************************** - -nsEventQueueStack::nsEventQueueStack() : mQueue(nsnull) -{ - mService = do_GetService(kEventQueueServiceCID); - - if(mService) - mService->PushThreadEventQueue(getter_AddRefs(mQueue)); -} -nsEventQueueStack::~nsEventQueueStack() -{ - if(mQueue) - mService->PopThreadEventQueue(mQueue); - mService = nsnull; -} - -nsresult nsEventQueueStack::Success() -{ - return mQueue ? NS_OK : NS_ERROR_FAILURE; -} - - - diff --git a/mozilla/xpfe/appshell/src/nsXULWindow.h b/mozilla/xpfe/appshell/src/nsXULWindow.h index fc929fcbc51..fc9fa2e259a 100644 --- a/mozilla/xpfe/appshell/src/nsXULWindow.h +++ b/mozilla/xpfe/appshell/src/nsXULWindow.h @@ -56,7 +56,6 @@ #include "nsIDocShell.h" #include "nsIDocShellTreeItem.h" #include "nsIDOMWindowInternal.h" -#include "nsIEventQueueService.h" #include "nsIInterfaceRequestor.h" #include "nsIInterfaceRequestorUtils.h" #include "nsIWidget.h" @@ -199,20 +198,4 @@ public: nsWeakPtr child; // content shell (weak reference to nsIDocShellTreeItem) }; -// nsEventQueueStack -// a little utility object to push an event queue and pop it when it -// goes out of scope. should probably be in a file of utility functions. -class nsEventQueueStack -{ -public: - nsEventQueueStack(); - ~nsEventQueueStack(); - - nsresult Success(); - -protected: - nsCOMPtr mService; - nsCOMPtr mQueue; -}; - #endif /* nsXULWindow_h__ */ diff --git a/mozilla/xpfe/browser/src/nsBrowserInstance.cpp b/mozilla/xpfe/browser/src/nsBrowserInstance.cpp index cd99ce7dee2..d30c4292868 100644 --- a/mozilla/xpfe/browser/src/nsBrowserInstance.cpp +++ b/mozilla/xpfe/browser/src/nsBrowserInstance.cpp @@ -69,15 +69,16 @@ #include "nsIWebBrowserChrome.h" #include "nsIWindowWatcher.h" #include "nsCOMPtr.h" +#include "nsAutoPtr.h" #include "nsXPIDLString.h" #include "nsReadableUtils.h" +#include "nsThreadUtils.h" #include "nsIPref.h" #include "nsIServiceManager.h" #include "nsIURL.h" #include "nsIIOService.h" #include "nsIWidget.h" -#include "plevent.h" #include "plstr.h" #include "nsIAppStartup.h" @@ -108,7 +109,6 @@ /* Define Class IDs */ static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID); -static NS_DEFINE_CID(kProxyObjectManagerCID, NS_PROXYEVENT_MANAGER_CID); #ifdef DEBUG static int APP_DEBUG = 0; // Set to 1 in debugger to turn on debugging. @@ -129,7 +129,6 @@ const char *kIgnoreOverrideMilestone = "ignore"; //***************************************************************************** #ifdef ENABLE_PAGE_CYCLER -#include "nsIProxyObjectManager.h" #include "nsITimer.h" static void TimesUp(nsITimer *aTimer, void *aClosure); @@ -139,7 +138,14 @@ class PageCycler : public nsIObserver { public: NS_DECL_ISUPPORTS - PLEvent mEvent; + struct PageCyclerEvent : public nsRunnable { + PageCyclerEvent(PageCycler *pc) : mPageCycler(pc) {} + NS_IMETHOD Run() { + mPageCycler->DoCycle(); + return NS_OK; + } + nsRefPtr mPageCycler; + }; PageCycler(nsBrowserInstance* appCore, const char *aTimeoutValue = nsnull, const char *aWaitValue = nsnull) : mAppCore(appCore), mBuffer(nsnull), mCursor(nsnull), mTimeoutValue(0), mWaitValue(1 /*sec*/) { @@ -223,13 +229,11 @@ public: nsCOMPtr appStartup = do_GetService(NS_APPSTARTUP_CONTRACTID, &rv); if(NS_FAILED(rv)) return rv; - nsCOMPtr pIProxyObjectManager = - do_GetService(kProxyObjectManagerCID, &rv); - if(NS_FAILED(rv)) return rv; nsCOMPtr appStartupProxy; - rv = pIProxyObjectManager->GetProxyForObject(NS_UI_THREAD_EVENTQ, NS_GET_IID(nsIAppStartup), - appStartup, PROXY_ASYNC | PROXY_ALWAYS, - getter_AddRefs(appStartupProxy)); + rv = NS_GetProxyForObject(NS_PROXY_TO_CURRENT_THREAD, + NS_GET_IID(nsIAppStartup), appStartup, + NS_PROXY_ASYNC | NS_PROXY_ALWAYS, + getter_AddRefs(appStartupProxy)); (void)appStartupProxy->Quit(nsIAppStartup::eAttemptQuit); return NS_ERROR_FAILURE; @@ -268,23 +272,9 @@ public: // otherwise we'll run the risk of confusing the docshell // (which notifies observers before propagating the // DocumentEndLoad up to parent docshells). - nsCOMPtr eqs - = do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID); - - rv = NS_ERROR_FAILURE; - - if (eqs) { - nsCOMPtr eq; - eqs->ResolveEventQueue(NS_UI_THREAD_EVENTQ, getter_AddRefs(eq)); - if (eq) { - rv = eq->InitEvent(&mEvent, this, HandleAsyncLoadEvent, - DestroyAsyncLoadEvent); - - if (NS_SUCCEEDED(rv)) { - rv = eq->PostEvent(&mEvent); - } - } - } + nsCOMPtr ev = new PageCyclerEvent(this); + if (ev) + rv = NS_DispatchToCurrentThread(ev); if (NS_FAILED(rv)) { printf("######### PageCycler couldn't asynchronously load: %s\n", NS_ConvertUTF16toUTF8(mLastRequest).get()); @@ -299,27 +289,19 @@ public: return rv; } - static void* PR_CALLBACK - HandleAsyncLoadEvent(PLEvent* aEvent) + void DoCycle() { - // This is the callback that actually loads the page - PageCycler* self = NS_STATIC_CAST(PageCycler*, PL_GetEventOwner(aEvent)); - // load the URL - const PRUnichar* url = self->mLastRequest.get(); + const PRUnichar* url = mLastRequest.get(); printf("########## PageCycler starting: %s\n", NS_ConvertUTF16toUTF8(url).get()); - self->mIntervalTime = PR_IntervalNow(); - self->mAppCore->LoadUrl(url); + mIntervalTime = PR_IntervalNow(); + mAppCore->LoadUrl(url); // start new timer - self->StartTimer(); - return nsnull; + StartTimer(); } - static void PR_CALLBACK - DestroyAsyncLoadEvent(PLEvent* aEvent) { /*no-op*/ } - const nsAutoString &GetLastRequest( void ) { return mLastRequest; diff --git a/mozilla/xpinstall/src/nsInstall.cpp b/mozilla/xpinstall/src/nsInstall.cpp index 9cb8a9ff9a3..9754fbb7f28 100644 --- a/mozilla/xpinstall/src/nsInstall.cpp +++ b/mozilla/xpinstall/src/nsInstall.cpp @@ -55,6 +55,7 @@ #include "nsDirectoryServiceDefs.h" #include "nsAppDirectoryServiceDefs.h" #include "nsDirectoryServiceUtils.h" +#include "nsThreadUtils.h" #include "nsNetUtil.h" @@ -110,7 +111,6 @@ #include #endif -static NS_DEFINE_IID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); static NS_DEFINE_IID(kProxyObjectManagerCID, NS_PROXYEVENT_MANAGER_CID); static NS_DEFINE_CID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID); @@ -189,9 +189,11 @@ nsInstallInfo::nsInstallInfo(PRUint32 aInstallType, // Failure is an option, and will occur in the stub installer. + nsCOMPtr thread = do_GetMainThread(); + NS_WITH_ALWAYS_PROXIED_SERVICE(CHROMEREG_IFACE, cr, NS_CHROMEREGISTRY_CONTRACTID, - NS_UI_THREAD_EVENTQ, &rv); + thread, &rv); if (NS_SUCCEEDED(rv)) { mChromeRegistry = cr; @@ -211,7 +213,7 @@ nsInstallInfo::nsInstallInfo(PRUint32 aInstallType, #ifdef MOZ_XUL_APP NS_WITH_ALWAYS_PROXIED_SERVICE(nsIExtensionManager, em, "@mozilla.org/extensions/manager;1", - NS_UI_THREAD_EVENTQ, &rv); + thread, &rv); if (NS_SUCCEEDED(rv)) mExtensionManager = em; @@ -264,12 +266,14 @@ nsInstall::nsInstall(nsIZipReader * theJARFile) su->Release(); + nsCOMPtr thread = do_GetMainThread(); + // get the resourced xpinstall string bundle mStringBundle = nsnull; NS_WITH_PROXIED_SERVICE( nsIStringBundleService, service, kStringBundleServiceCID, - NS_UI_THREAD_EVENTQ, + thread, &rv ); if (NS_SUCCEEDED(rv) && service) @@ -1220,7 +1224,6 @@ nsInstall::LoadResources(JSContext* cx, const nsString& aBaseName, jsval* aRetur nsCOMPtr resFile; nsIURI *url = nsnull; nsIStringBundleService* service = nsnull; - nsIEventQueueService* pEventQueueService = nsnull; nsIStringBundle* bundle = nsnull; nsCOMPtr propEnum; jsval v = JSVAL_NULL; @@ -1245,13 +1248,6 @@ nsInstall::LoadResources(JSContext* cx, const nsString& aBaseName, jsval* aRetur // initialize string bundle and related services ret = CallGetService(kStringBundleServiceCID, &service); - if (NS_FAILED(ret)) - goto cleanup; - ret = CallGetService(kEventQueueServiceCID, &pEventQueueService); - if (NS_FAILED(ret)) - goto cleanup; - ret = pEventQueueService->CreateThreadEventQueue(); - NS_RELEASE(pEventQueueService); if (NS_FAILED(ret)) goto cleanup; @@ -1411,8 +1407,10 @@ nsPIXPIProxy* nsInstall::GetUIThreadProxy() if (NS_SUCCEEDED(rv)) { nsCOMPtr tmp(do_QueryInterface(new nsXPIProxy())); - rv = pmgr->GetProxyForObject( NS_UI_THREAD_EVENTQ, NS_GET_IID(nsPIXPIProxy), - tmp, PROXY_SYNC | PROXY_ALWAYS, getter_AddRefs(mUIThreadProxy) ); + rv = pmgr->GetProxyForObject( NS_PROXY_TO_MAIN_THREAD, + NS_GET_IID(nsPIXPIProxy), tmp, + NS_PROXY_SYNC | NS_PROXY_ALWAYS, + getter_AddRefs(mUIThreadProxy) ); } } diff --git a/mozilla/xpinstall/src/nsInstall.h b/mozilla/xpinstall/src/nsInstall.h index 65b91d427da..f02dc804583 100644 --- a/mozilla/xpinstall/src/nsInstall.h +++ b/mozilla/xpinstall/src/nsInstall.h @@ -46,8 +46,6 @@ #include "jsapi.h" -#include "plevent.h" - #include "nsString.h" #include "nsVoidArray.h" #include "nsHashtable.h" @@ -66,7 +64,6 @@ #include "nsIStringBundle.h" #include "nsILocale.h" -#include "nsIEventQueueService.h" #include "nsIServiceManager.h" #include "nsIComponentManager.h" #include "nsIEnumerator.h" diff --git a/mozilla/xpinstall/src/nsInstallFolder.cpp b/mozilla/xpinstall/src/nsInstallFolder.cpp index 8baf0499e9c..192cc8f8953 100644 --- a/mozilla/xpinstall/src/nsInstallFolder.cpp +++ b/mozilla/xpinstall/src/nsInstallFolder.cpp @@ -59,8 +59,7 @@ #ifdef XP_WIN #include -#include -#include +#include #endif struct DirectoryTable diff --git a/mozilla/xpinstall/src/nsSoftwareUpdate.cpp b/mozilla/xpinstall/src/nsSoftwareUpdate.cpp index e8caa8f872b..cb6a9b0c9d6 100644 --- a/mozilla/xpinstall/src/nsSoftwareUpdate.cpp +++ b/mozilla/xpinstall/src/nsSoftwareUpdate.cpp @@ -78,9 +78,6 @@ #include "nsIScriptNameSpaceManager.h" #include "nsIScriptExternalNameSet.h" -#include "nsIEventQueueService.h" -#include "nsIProxyObjectManager.h" -#include "nsProxiedService.h" #include "nsIChromeRegistry.h" #include "nsCURILoader.h" diff --git a/mozilla/xpinstall/src/nsSoftwareUpdateRun.cpp b/mozilla/xpinstall/src/nsSoftwareUpdateRun.cpp index 2431b577fae..062feea44e3 100644 --- a/mozilla/xpinstall/src/nsSoftwareUpdateRun.cpp +++ b/mozilla/xpinstall/src/nsSoftwareUpdateRun.cpp @@ -56,7 +56,6 @@ #include "nspr.h" #include "jsapi.h" -#include "nsIEventQueueService.h" #include "nsIEnumerator.h" #include "nsIZipReader.h" #include "nsIJSRuntimeService.h" @@ -75,7 +74,6 @@ #include "nsIExtensionManager.h" static NS_DEFINE_CID(kSoftwareUpdateCID, NS_SoftwareUpdate_CID); -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); extern JSObject *InitXPInstallObjects(JSContext *jscontext, JSObject *global, nsIFile* jarfile, const PRUnichar* url, @@ -466,16 +464,6 @@ extern "C" void RunInstallOnThread(void *data) nsCOMPtr listener; - // lets set up an eventQ so that our xpcom/proxies will not have to: - nsCOMPtr eventQ; - nsCOMPtr eventQService = - do_GetService(kEventQueueServiceCID, &rv); - if (NS_SUCCEEDED(rv)) - { - eventQService->CreateMonitoredThreadEventQueue(); - eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(eventQ)); - } - nsCOMPtr softwareUpdate = do_GetService(kSoftwareUpdateCID, &rv); diff --git a/mozilla/xpinstall/src/nsWinReg.h b/mozilla/xpinstall/src/nsWinReg.h index 7b33761425c..87bbd591f5d 100644 --- a/mozilla/xpinstall/src/nsWinReg.h +++ b/mozilla/xpinstall/src/nsWinReg.h @@ -46,8 +46,6 @@ #include "jsapi.h" -#include "plevent.h" - #include "nsString.h" #include "nsHashtable.h" diff --git a/mozilla/xpinstall/src/nsXPITriggerInfo.cpp b/mozilla/xpinstall/src/nsXPITriggerInfo.cpp index 719de7f6678..bcb82a20cb8 100644 --- a/mozilla/xpinstall/src/nsXPITriggerInfo.cpp +++ b/mozilla/xpinstall/src/nsXPITriggerInfo.cpp @@ -41,14 +41,13 @@ #include "nsXPITriggerInfo.h" #include "nsNetUtil.h" #include "nsDebug.h" +#include "nsAutoPtr.h" +#include "nsThreadUtils.h" #include "nsIServiceManager.h" -#include "nsIEventQueueService.h" #include "nsIJSContextStack.h" #include "nsIScriptSecurityManager.h" #include "nsICryptoHash.h" -static NS_DEFINE_IID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); - // // nsXPITriggerItem // @@ -227,7 +226,7 @@ void nsXPITriggerInfo::SaveCallback( JSContext *aCx, jsval aVal ) } mCbval = aVal; - mThread = PR_GetCurrentThread(); + mThread = do_GetCurrentThread(); if ( !JSVAL_IS_NULL(mCbval) ) { JS_BeginRequest(mCx); @@ -236,26 +235,24 @@ void nsXPITriggerInfo::SaveCallback( JSContext *aCx, jsval aVal ) } } -PR_STATIC_CALLBACK(void) destroyTriggerEvent(PLEvent* aEvent) +XPITriggerEvent::~XPITriggerEvent() { - XPITriggerEvent *event = NS_STATIC_CAST(XPITriggerEvent*, aEvent); - JS_BeginRequest(event->cx); - JS_RemoveRoot( event->cx, &event->cbval ); - JS_EndRequest(event->cx); - delete event; + JS_BeginRequest(cx); + JS_RemoveRoot(cx, &cbval); + JS_EndRequest(cx); } -PR_STATIC_CALLBACK(void*) handleTriggerEvent(PLEvent* aEvent) +NS_IMETHODIMP +XPITriggerEvent::Run() { - XPITriggerEvent *event = NS_STATIC_CAST(XPITriggerEvent*, aEvent); jsval ret; void* mark; jsval* args; - JS_BeginRequest(event->cx); - args = JS_PushArguments( event->cx, &mark, "Wi", - event->URL.get(), - event->status ); + JS_BeginRequest(cx); + args = JS_PushArguments(cx, &mark, "Wi", + URL.get(), + status); if ( args ) { // This code is all in a JS request, and here we're about to @@ -268,7 +265,7 @@ PR_STATIC_CALLBACK(void*) handleTriggerEvent(PLEvent* aEvent) nsCOMPtr stack = do_GetService("@mozilla.org/js/xpc/ContextStack;1"); if (stack) - stack->Push(event->cx); + stack->Push(cx); nsCOMPtr secman = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID); @@ -291,7 +288,7 @@ PR_STATIC_CALLBACK(void*) handleTriggerEvent(PLEvent* aEvent) if (!errorStr) { PRBool equals = PR_FALSE; - principal->Equals(event->princ, &equals); + principal->Equals(princ, &equals); if (!equals) { @@ -301,13 +298,13 @@ PR_STATIC_CALLBACK(void*) handleTriggerEvent(PLEvent* aEvent) if (errorStr) { - JS_ReportError(event->cx, errorStr); + JS_ReportError(cx, errorStr); } else { - JS_CallFunctionValue(event->cx, - JSVAL_TO_OBJECT(event->global), - event->cbval, + JS_CallFunctionValue(cx, + JSVAL_TO_OBJECT(global), + cbval, 2, args, &ret); @@ -316,9 +313,9 @@ PR_STATIC_CALLBACK(void*) handleTriggerEvent(PLEvent* aEvent) if (stack) stack->Pop(nsnull); - JS_PopArguments( event->cx, mark ); + JS_PopArguments(cx, mark); } - JS_EndRequest(event->cx); + JS_EndRequest(cx); return 0; } @@ -326,59 +323,45 @@ PR_STATIC_CALLBACK(void*) handleTriggerEvent(PLEvent* aEvent) void nsXPITriggerInfo::SendStatus(const PRUnichar* URL, PRInt32 status) { - nsCOMPtr eq; nsresult rv; if ( mCx && mGlobalWrapper && mCbval ) { - nsCOMPtr EQService = - do_GetService(kEventQueueServiceCID, &rv); - if ( NS_SUCCEEDED( rv ) ) + // create event and post it + nsRefPtr event = new XPITriggerEvent(); + if (event) { - rv = EQService->GetThreadEventQueue(mThread, getter_AddRefs(eq)); - if ( NS_SUCCEEDED(rv) ) - { - // create event and post it - XPITriggerEvent* event = new XPITriggerEvent(); - if (event) - { - PL_InitEvent(event, 0, - handleTriggerEvent, - destroyTriggerEvent); + event->URL = URL; + event->status = status; + event->cx = mCx; + event->princ = mPrincipal; - event->URL = URL; - event->status = status; - event->cx = mCx; - event->princ = mPrincipal; + JSObject *obj = nsnull; - JSObject *obj = nsnull; + mGlobalWrapper->GetJSObject(&obj); - mGlobalWrapper->GetJSObject(&obj); + event->global = OBJECT_TO_JSVAL(obj); - event->global = OBJECT_TO_JSVAL(obj); + event->cbval = mCbval; + JS_BeginRequest(event->cx); + JS_AddNamedRoot(event->cx, &event->cbval, + "XPITriggerEvent::cbval" ); + JS_EndRequest(event->cx); - event->cbval = mCbval; - JS_BeginRequest(event->cx); - JS_AddNamedRoot( event->cx, &event->cbval, - "XPITriggerEvent::cbval" ); - JS_EndRequest(event->cx); + // Hold a strong reference to keep the underlying + // JSContext from dying before we handle this event. + event->ref = mGlobalWrapper; - // Hold a strong reference to keep the underlying - // JSContext from dying before we handle this event. - event->ref = mGlobalWrapper; - - eq->PostEvent(event); - } - else - rv = NS_ERROR_OUT_OF_MEMORY; - } + rv = mThread->Dispatch(event, NS_DISPATCH_NORMAL); } + else + rv = NS_ERROR_OUT_OF_MEMORY; if ( NS_FAILED( rv ) ) { // couldn't get event queue -- maybe window is gone or // some similarly catastrophic occurrance + NS_WARNING("failed to dispatch XPITriggerEvent"); } } } - diff --git a/mozilla/xpinstall/src/nsXPITriggerInfo.h b/mozilla/xpinstall/src/nsXPITriggerInfo.h index 0ae0c070620..a43695d3b7c 100644 --- a/mozilla/xpinstall/src/nsXPITriggerInfo.h +++ b/mozilla/xpinstall/src/nsXPITriggerInfo.h @@ -49,12 +49,12 @@ #include "nsIOutputStream.h" #include "jsapi.h" #include "prthread.h" -#include "plevent.h" #include "nsIXPConnect.h" #include "nsICryptoHash.h" #include "nsIPrincipal.h" +#include "nsThreadUtils.h" -struct XPITriggerEvent : public PLEvent { +struct XPITriggerEvent : public nsRunnable { nsString URL; PRInt32 status; JSContext* cx; @@ -62,10 +62,11 @@ struct XPITriggerEvent : public PLEvent { jsval cbval; nsCOMPtr ref; nsCOMPtr princ; + + virtual ~XPITriggerEvent(); + NS_IMETHOD Run(); }; - - class nsXPITriggerItem { public: @@ -134,7 +135,7 @@ class nsXPITriggerInfo JSContext *mCx; nsCOMPtr mGlobalWrapper; jsval mCbval; - PRThread* mThread; + nsCOMPtr mThread; nsCOMPtr mPrincipal; diff --git a/mozilla/xpinstall/src/nsXPInstallManager.cpp b/mozilla/xpinstall/src/nsXPInstallManager.cpp index c4181a61d4d..072e5279a70 100644 --- a/mozilla/xpinstall/src/nsXPInstallManager.cpp +++ b/mozilla/xpinstall/src/nsXPInstallManager.cpp @@ -89,8 +89,6 @@ static NS_DEFINE_IID(kProxyObjectManagerCID, NS_PROXYEVENT_MANAGER_CID); static NS_DEFINE_IID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID); -#include "nsIEventQueueService.h" - #define PREF_XPINSTALL_ENABLED "xpinstall.enabled" #define PREF_XPINSTALL_CONFIRM_DLG "xpinstall.dialog.confirm" #define PREF_XPINSTALL_STATUS_DLG_SKIN "xpinstall.dialog.progress.skin" @@ -551,10 +549,10 @@ NS_IMETHODIMP nsXPInstallManager::Observe( nsISupports *aSubject, do_GetService(kProxyObjectManagerCID, &rv); if (pmgr) { - rv = pmgr->GetProxyForObject( NS_UI_THREAD_EVENTQ, + rv = pmgr->GetProxyForObject( NS_PROXY_TO_MAIN_THREAD, NS_GET_IID(nsIXPIProgressDialog), dlg, - PROXY_SYNC | PROXY_ALWAYS, + NS_PROXY_SYNC | NS_PROXY_ALWAYS, getter_AddRefs(mDlg) ); } }