From c031e1c389a0a13b26c970a1039c36af1e937eb1 Mon Sep 17 00:00:00 2001 From: "dougt%netscape.com" Date: Tue, 30 Nov 1999 00:14:55 +0000 Subject: [PATCH] Fix for 18078. R=mstoltz,warren --- dom/src/jsurl/nsJSProtocolHandler.cpp | 2 +- xpcom/proxy/public/nsProxyObjectManager.h | 1 + xpcom/proxy/src/nsProxyEvent.cpp | 6 +-- xpcom/proxy/src/nsProxyObjectManager.cpp | 39 +++++----------- xpcom/proxy/tests/proxytests.cpp | 8 ++-- xpcom/threads/nsEventQueueService.cpp | 56 ++++++++++++++++++----- xpcom/threads/nsEventQueueService.h | 1 + xpcom/threads/nsIEventQueueService.h | 10 +++- 8 files changed, 76 insertions(+), 47 deletions(-) diff --git a/dom/src/jsurl/nsJSProtocolHandler.cpp b/dom/src/jsurl/nsJSProtocolHandler.cpp index 02fe88faa470..2318c7ccfcc0 100644 --- a/dom/src/jsurl/nsJSProtocolHandler.cpp +++ b/dom/src/jsurl/nsJSProtocolHandler.cpp @@ -278,7 +278,7 @@ nsJSProtocolHandler::NewChannel(const char* verb, if (eval == nsnull) return NS_ERROR_OUT_OF_MEMORY; - rv = proxyObjectManager->GetProxyObject(nsnull, + rv = proxyObjectManager->GetProxyObject(NS_UI_THREAD_EVENTQ, nsCOMTypeInfo::GetIID(), NS_STATIC_CAST(nsISupports*, eval), PROXY_SYNC | PROXY_ALWAYS, diff --git a/xpcom/proxy/public/nsProxyObjectManager.h b/xpcom/proxy/public/nsProxyObjectManager.h index 88c05845ff02..3f3e0a2389e3 100644 --- a/xpcom/proxy/public/nsProxyObjectManager.h +++ b/xpcom/proxy/public/nsProxyObjectManager.h @@ -27,6 +27,7 @@ #include "nsISupports.h" #include "nsIFactory.h" #include "nsIEventQueue.h" +#include "nsIEventQueueService.h" #include "nsHashtable.h" diff --git a/xpcom/proxy/src/nsProxyEvent.cpp b/xpcom/proxy/src/nsProxyEvent.cpp index 82c6c2a0f5bc..defc0068c350 100644 --- a/xpcom/proxy/src/nsProxyEvent.cpp +++ b/xpcom/proxy/src/nsProxyEvent.cpp @@ -218,7 +218,7 @@ nsProxyObject::PostAndWait(nsProxyObjectCallInfo *proxyInfo) return rv; nsCOMPtr eventQ; - rv = eventQService->GetThreadEventQueue(PR_CurrentThread(), getter_AddRefs(eventQ)); + rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(eventQ)); if (NS_FAILED(rv)) { rv = eventQService->CreateThreadEventQueue(); @@ -226,7 +226,7 @@ nsProxyObject::PostAndWait(nsProxyObjectCallInfo *proxyInfo) if (NS_FAILED(rv)) return rv; - rv = eventQService->GetThreadEventQueue(PR_CurrentThread(), getter_AddRefs(eventQ)); + rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(eventQ)); } else { @@ -564,7 +564,7 @@ AutoProxyParameterList(PRUint32 methodIndex, nsXPTMethodInfo *methodInfo, nsXPTC if ( NS_FAILED( rv ) ) return rv; - rv = eventQService->GetThreadEventQueue(PR_CurrentThread(), &eventQ); + rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &eventQ); if ( NS_FAILED( rv ) ) { // the caller does not have an eventQ of their own. bad. diff --git a/xpcom/proxy/src/nsProxyObjectManager.cpp b/xpcom/proxy/src/nsProxyObjectManager.cpp index 50bd592f11c5..10b070d7a8c6 100644 --- a/xpcom/proxy/src/nsProxyObjectManager.cpp +++ b/xpcom/proxy/src/nsProxyObjectManager.cpp @@ -132,36 +132,21 @@ NS_IMETHODIMP nsProxyObjectManager::GetProxyObject(nsIEventQueue *destQueue, REFNSIID aIID, nsISupports* aObj, PRInt32 proxyType, void** aProxyObject) { nsresult rv; - - nsCOMPtr postQ(do_QueryInterface(destQueue)); + nsCOMPtr postQ; + *aProxyObject = nsnull; - // post to primordial thread event queue if no queue specified - if (postQ == nsnull) - { - nsCOMPtr mainIThread; - PRThread *mainThread; - - // Get the primordial thread - rv = nsIThread::GetMainThread(getter_AddRefs(mainIThread)); - if ( NS_FAILED( rv ) ) - return NS_ERROR_UNEXPECTED; - - rv = mainIThread->GetPRThread(&mainThread); - if ( NS_FAILED( rv ) ) - return NS_ERROR_UNEXPECTED; - - NS_WITH_SERVICE(nsIEventQueueService, eventQService, kEventQueueServiceCID, &rv); - if ( NS_FAILED( rv ) ) - return NS_ERROR_UNEXPECTED; - - rv = eventQService->GetThreadEventQueue(mainThread, getter_AddRefs(postQ)); - - if ( NS_FAILED( rv ) ) - return NS_ERROR_UNEXPECTED; - } - + // check to see if the destination Q is a special case. + + NS_WITH_SERVICE(nsIEventQueueService, eventQService, 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 != nsnull && !(proxyType & PROXY_ASYNC) && !(proxyType & PROXY_ALWAYS)) diff --git a/xpcom/proxy/tests/proxytests.cpp b/xpcom/proxy/tests/proxytests.cpp index 69a740938ee1..138a45398afd 100644 --- a/xpcom/proxy/tests/proxytests.cpp +++ b/xpcom/proxy/tests/proxytests.cpp @@ -298,13 +298,13 @@ void TestCase_NestedLoop(void *arg) NS_WITH_SERVICE(nsIEventQueueService, eventQService, kEventQueueServiceCID, &rv); if (NS_SUCCEEDED(rv)) { - rv = eventQService->GetThreadEventQueue(PR_CurrentThread(), &eventQ); + rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &eventQ); if (NS_FAILED(rv)) rv = eventQService->CreateThreadEventQueue(); if (NS_FAILED(rv)) return; else - rv = eventQService->GetThreadEventQueue(PR_CurrentThread(), &eventQ); + rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &eventQ); printf("Thread (%d) Prior to calling proxyObject->Test.\n", threadNumber); rv = proxyObject->Test((PRInt32)eventQ, 0, &retval); @@ -416,13 +416,13 @@ static void PR_CALLBACK EventLoop( void *arg ) nsIEventQueue* eventQ; NS_WITH_SERVICE(nsIEventQueueService, eventQService, kEventQueueServiceCID, &rv); if (NS_SUCCEEDED(rv)) { - rv = eventQService->GetThreadEventQueue(PR_CurrentThread(), &eventQ); + rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &eventQ); if (NS_FAILED(rv)) rv = eventQService->CreateThreadEventQueue(); if (NS_FAILED(rv)) return; else - rv = eventQService->GetThreadEventQueue(PR_CurrentThread(), &eventQ); + rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &eventQ); } if (NS_FAILED(rv)) return; diff --git a/xpcom/threads/nsEventQueueService.cpp b/xpcom/threads/nsEventQueueService.cpp index 34af92d9a063..a3e83f8814a9 100644 --- a/xpcom/threads/nsEventQueueService.cpp +++ b/xpcom/threads/nsEventQueueService.cpp @@ -476,33 +476,67 @@ nsEventQueueServiceImpl::GetThreadEventQueue(PRThread* aThread, nsIEventQueue** { nsresult rv = NS_OK; EventQueueEntry* evQueueEntry; - ThreadKey key(aThread); + + /* Parameter validation... */ + if (NULL == aResult) return NS_ERROR_NULL_POINTER; + + PRThread* keyThread = aThread; + + if (keyThread == NS_CURRENT_THREAD) + { + keyThread = PR_GetCurrentThread(); + } + else if (keyThread == NS_UI_THREAD) + { + nsCOMPtr mainIThread; + + // Get the primordial thread + rv = nsIThread::GetMainThread(getter_AddRefs(mainIThread)); + if (NS_FAILED(rv)) return rv; + + rv = mainIThread->GetPRThread(&keyThread); + if (NS_FAILED(rv)) return rv; + } + + ThreadKey key(keyThread); /* Enter the lock which protects the EventQ hashtable... */ PR_EnterMonitor(mEventQMonitor); - /* Parameter validation... */ - if ((NULL == aThread) || (NULL == aResult)) { - rv = NS_ERROR_NULL_POINTER; - goto done; - } - evQueueEntry = (EventQueueEntry*)mEventQTable->Get(&key); + + PR_ExitMonitor(mEventQMonitor); + if (NULL != evQueueEntry) { *aResult = evQueueEntry->GetEventQueue(); // Queue addrefing is done by this call. } else { // XXX: Need error code for requesting an event queue when none exists... *aResult = NULL; rv = NS_ERROR_FAILURE; - goto done; } -done: - // Release the EventQ lock... - PR_ExitMonitor(mEventQMonitor); return rv; } + +NS_IMETHODIMP +nsEventQueueServiceImpl::ResolveEventQueue(nsIEventQueue* queueOrConstant, nsIEventQueue* *resultQueue) +{ + if (queueOrConstant == NS_CURRENT_EVENTQ) + { + return GetThreadEventQueue(NS_CURRENT_THREAD, resultQueue); + } + else if (queueOrConstant == NS_UI_THREAD_EVENTQ) + { + return GetThreadEventQueue(NS_UI_THREAD, resultQueue); + } + + *resultQueue = queueOrConstant; + NS_ADDREF(*resultQueue); + return NS_OK; +} + + #ifdef XP_MAC // MAC specific. Will go away someday // Bwah ha ha h ha ah aha ha ha diff --git a/xpcom/threads/nsEventQueueService.h b/xpcom/threads/nsEventQueueService.h index 541c2364e283..321cf7c6f3af 100644 --- a/xpcom/threads/nsEventQueueService.h +++ b/xpcom/threads/nsEventQueueService.h @@ -60,6 +60,7 @@ public: NS_IMETHOD CreateThreadEventQueue(void); NS_IMETHOD DestroyThreadEventQueue(void); NS_IMETHOD GetThreadEventQueue(PRThread* aThread, nsIEventQueue** aResult); + NS_IMETHOD ResolveEventQueue(nsIEventQueue* queueOrConstant, nsIEventQueue* *resultQueue); NS_IMETHOD CreateFromIThread(nsIThread *aThread, nsIEventQueue **aResult); NS_IMETHOD CreateFromPLEventQueue(PLEventQueue* aPLEventQueue, nsIEventQueue** aResult); diff --git a/xpcom/threads/nsIEventQueueService.h b/xpcom/threads/nsIEventQueueService.h index 50352792e9ab..632edf6aaa24 100644 --- a/xpcom/threads/nsIEventQueueService.h +++ b/xpcom/threads/nsIEventQueueService.h @@ -41,6 +41,13 @@ #define NS_EVENTQUEUESERVICE_PROGID "component://netscape/event-queue-service" #define NS_EVENTQUEUESERVICE_CLASSNAME "Event Queue Service" +#define NS_CURRENT_THREAD ((PRThread*)0) +#define NS_CURRENT_EVENTQ ((nsIEventQueue*)0) + +#define NS_UI_THREAD ((PRThread*)1) +#define NS_UI_THREAD_EVENTQ ((nsIEventQueue*)1) + + class nsIThread; class nsIEventQueueService : public nsISupports @@ -62,7 +69,8 @@ public: NS_IMETHOD PopThreadEventQueue(nsIEventQueue *aQueue) = 0; NS_IMETHOD GetThreadEventQueue(PRThread* aThread, nsIEventQueue** aResult) = 0; - + NS_IMETHOD ResolveEventQueue(nsIEventQueue* queueOrConstant, nsIEventQueue* *resultQueue) = 0; + #ifdef XP_MAC // This is ment to be temporary until something better is worked out NS_IMETHOD ProcessEvents() = 0;