From 6037b8f2c542cb911465127d74267e864e4ea328 Mon Sep 17 00:00:00 2001 From: "rpotts%netscape.com" Date: Tue, 5 Jan 1999 09:51:28 +0000 Subject: [PATCH] use the new EventQueueService to obtain the event queue used for marshalling data over to the UI thread... --- network/module/nsNetService.cpp | 55 +++++++++++++++++++++++++++++-- network/module/nsNetService.h | 3 +- network/module/nsNetThread.cpp | 57 ++++++++++++++++++++------------- 3 files changed, 89 insertions(+), 26 deletions(-) diff --git a/network/module/nsNetService.cpp b/network/module/nsNetService.cpp index be1186f1b134..3e455775d407 100644 --- a/network/module/nsNetService.cpp +++ b/network/module/nsNetService.cpp @@ -43,6 +43,8 @@ extern "C" { #include "nsIProtocolURLFactory.h" #include "nsIProtocol.h" #include "nsIServiceManager.h" +#include "nsIEventQueueService.h" +#include "nsXPComCIID.h" #include "nsCRT.h" #ifdef XP_PC @@ -99,7 +101,7 @@ nsresult PerformNastyWindowsAsyncDNSHack(URL_Struct* URL_s, nsIURL* aURL); #endif /* XP_WIN && !NETLIB_THREAD */ char *mangleResourceIntoFileURL(const char* aResourceFileName) ; -extern nsIStreamListener* ns_NewStreamListenerProxy(nsIStreamListener* aListener); +extern nsIStreamListener* ns_NewStreamListenerProxy(nsIStreamListener* aListener, PLEventQueue* aEventQ); extern "C" { #if defined(XP_WIN) || defined(XP_OS2) @@ -119,12 +121,24 @@ extern const char *XP_AppPlatform; } /* end of extern "C" */ static NS_DEFINE_IID(kINetlibURLIID, NS_INETLIBURL_IID); +static NS_DEFINE_IID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); +static NS_DEFINE_IID(kIEventQueueServiceIID, NS_IEVENTQUEUESERVICE_IID); nsNetlibService::nsNetlibService() { + nsresult rv; + NS_INIT_REFCNT(); + /* + * Cache the EventQueueService... + */ + // XXX: What if this fails? + rv = nsServiceManager::GetService(kEventQueueServiceCID, + kIEventQueueServiceIID, + (nsISupports **)&mEventQService); + /* m_stubContext = new_stub_context(); */ @@ -217,6 +231,11 @@ nsNetlibService::~nsNetlibService() delete mNetlibThread; } + if (nsnull != mEventQService) { + nsServiceManager::ReleaseService(kEventQueueServiceCID, mEventQService); + mEventQService = nsnull; + } + delete mProtocols; } @@ -295,13 +314,19 @@ nsresult nsNetlibService::OpenStream(nsIURL *aUrl, nsINetlibURL *netlibURL; nsresult result; nsIStreamListener* consumer; + PLEventQueue* evQueue = nsnull; if ((NULL == aConsumer) || (NULL == aUrl)) { return NS_FALSE; } #if defined(NETLIB_THREAD) - consumer = ns_NewStreamListenerProxy(aConsumer); + mEventQService->GetThreadEventQueue(PR_GetCurrentThread(), &evQueue); + if (nsnull == evQueue) { + return NS_FALSE; + } + + consumer = ns_NewStreamListenerProxy(aConsumer, evQueue); if (nsnull == consumer) { return NS_FALSE; } @@ -354,6 +379,15 @@ nsresult nsNetlibService::OpenStream(nsIURL *aUrl, * The Reference count on pConn is already 1 so no AddRef() is necessary. */ URL_s->fe_data = pConn; + + /* + * Attach the Event Queue to use when proxying data back to the thread + * which initiated the URL load... + * + * Currently, this information is needed to marshall the call to the URL + * exit_routine(...) on the correct thread... + */ + URL_s->owner_data = evQueue; /* * Give the protocol a chance to initialize any URL_Struct fields... @@ -402,6 +436,7 @@ nsresult nsNetlibService::OpenBlockingStream(nsIURL *aUrl, nsNetlibStream *pBlockingStream; nsINetlibURL *netlibURL; nsIStreamListener* consumer = nsnull; + PLEventQueue* evQueue = nsnull; nsresult result; if (NULL == aNewStream) { @@ -410,8 +445,13 @@ nsresult nsNetlibService::OpenBlockingStream(nsIURL *aUrl, if (NULL != aUrl) { #if defined(NETLIB_THREAD) + mEventQService->GetThreadEventQueue(PR_GetCurrentThread(), &evQueue); + if (nsnull == evQueue) { + goto loser; + } + if (nsnull != aConsumer) { - consumer = ns_NewStreamListenerProxy(aConsumer); + consumer = ns_NewStreamListenerProxy(aConsumer, evQueue); if (nsnull == consumer) { goto loser; } @@ -495,6 +535,15 @@ nsresult nsNetlibService::OpenBlockingStream(nsIURL *aUrl, */ URL_s->fe_data = pConn; + /* + * Attach the Event Queue to use when proxying data back to the thread + * which initiated the URL load... + * + * Currently, this information is needed to marshall the call to the URL + * exit_routine(...) on the correct thread... + */ + URL_s->owner_data = evQueue; + /* * Give the protocol a chance to initialize any URL_Struct fields... * diff --git a/network/module/nsNetService.h b/network/module/nsNetService.h index 22404cf27e91..2ba5f57709da 100644 --- a/network/module/nsNetService.h +++ b/network/module/nsNetService.h @@ -21,8 +21,8 @@ #define nsNetService_h___ #include "nspr.h" -#include "plevent.h" #include "nsIPref.h" +#include "nsIEventQueueService.h" #include "nsINetService.h" #include "nsNetThread.h" #include "nsHashtable.h" @@ -119,6 +119,7 @@ private: nsITimer* mPollingTimer; nsNetlibThread* mNetlibThread; + nsIEventQueueService* mEventQService; nsHashtable* mProtocols; }; diff --git a/network/module/nsNetThread.cpp b/network/module/nsNetThread.cpp index 2e9cb2a7d9ac..c5cb51d8e639 100644 --- a/network/module/nsNetThread.cpp +++ b/network/module/nsNetThread.cpp @@ -312,7 +312,7 @@ void nsNetlibThread::NetlibMainLoop() class nsStreamListenerProxy : public nsIStreamListener { public: - nsStreamListenerProxy(nsIStreamListener* aListener); + nsStreamListenerProxy(nsIStreamListener* aListener, PLEventQueue* aEventQ); NS_DECL_ISUPPORTS @@ -334,6 +334,7 @@ protected: private: nsresult mStatus; + PLEventQueue* mEventQ; }; @@ -344,7 +345,7 @@ struct ProxyEvent : public PLEvent virtual ~ProxyEvent(); virtual void InitEvent(); NS_IMETHOD HandleEvent() = 0; - void Fire(void); + void Fire(PLEventQueue* aEventQ); static void PR_CALLBACK HandlePLEvent(PLEvent* aEvent); static void PR_CALLBACK DestroyPLEvent(PLEvent* aEvent); @@ -387,13 +388,14 @@ void PR_CALLBACK ProxyEvent::DestroyPLEvent(PLEvent* aEvent) extern PLEventQueue* gWebShell_UnixEventQueue; #endif -void ProxyEvent::Fire() +void ProxyEvent::Fire(PLEventQueue* aEventQ) { PLEventQueue* eventQueue; InitEvent(); #if defined(XP_PC) - eventQueue = PL_GetMainEventQueue(); + NS_PRECONDITION(nsnull != aEventQ, "PLEventQueue for thread is null"); + eventQueue = aEventQ; #elif defined(XP_UNIX) eventQueue = gWebShell_UnixEventQueue; #endif @@ -615,13 +617,15 @@ OnDataAvailableProxyEvent::HandleEvent() /*--------------------------------------------------------------------------*/ -nsStreamListenerProxy::nsStreamListenerProxy(nsIStreamListener* aListener) +nsStreamListenerProxy::nsStreamListenerProxy(nsIStreamListener* aListener, + PLEventQueue* aEventQ) { NS_INIT_REFCNT(); mRealListener = aListener; NS_ADDREF(mRealListener); + mEventQ = aEventQ; mStatus = NS_OK; } @@ -665,7 +669,7 @@ nsStreamListenerProxy::OnStartBinding(nsIURL* aURL, const char *aContentType) if (nsnull == ev) { rv = NS_ERROR_OUT_OF_MEMORY; } else { - ev->Fire(); + ev->Fire(mEventQ); } } } else { @@ -689,7 +693,7 @@ nsStreamListenerProxy::OnProgress(nsIURL* aURL, PRUint32 aProgress, if (nsnull == ev) { rv = NS_ERROR_OUT_OF_MEMORY; } else { - ev->Fire(); + ev->Fire(mEventQ); } } } else { @@ -712,7 +716,7 @@ nsStreamListenerProxy::OnStatus(nsIURL* aURL, const PRUnichar* aMsg) if (nsnull == ev) { rv = NS_ERROR_OUT_OF_MEMORY; } else { - ev->Fire(); + ev->Fire(mEventQ); } } } else { @@ -736,7 +740,7 @@ nsStreamListenerProxy::OnStopBinding(nsIURL* aURL, nsresult aStatus, if (nsnull == ev) { rv = NS_ERROR_OUT_OF_MEMORY; } else { - ev->Fire(); + ev->Fire(mEventQ); } } } else { @@ -776,7 +780,7 @@ nsStreamListenerProxy::OnDataAvailable(nsIURL* aURL, nsIInputStream *aIStream, if (nsnull == ev) { rv = NS_ERROR_OUT_OF_MEMORY; } else { - ev->Fire(); + ev->Fire(mEventQ); } } } else { @@ -793,9 +797,10 @@ nsStreamListenerProxy::~nsStreamListenerProxy() NS_RELEASE(mRealListener); } -nsIStreamListener* ns_NewStreamListenerProxy(nsIStreamListener* aListener) +nsIStreamListener* ns_NewStreamListenerProxy(nsIStreamListener* aListener, + PLEventQueue* aEventQ) { - return new nsStreamListenerProxy(aListener); + return new nsStreamListenerProxy(aListener, aEventQ); } @@ -867,16 +872,24 @@ net_CallExitRoutineProxy(Net_GetUrlExitFunc* exit_routine, CallExitRoutineProxyEvent* ev; /* - * Always use a PLEvent to call the exit_routine(...). This is necessary - * because when a connection is interrupted, the exit_routine(...) is called - * inside of the LIBNET_LOCK(). - * - * By always using an event, we are sure that the exit_routine(...) is not - * called while the thread is holding the LIBNET_LOCK(). + * Make sure that the URL_Struct was opened by the nsINetService... + * Otherwise, we cannot look at the URL_s->owner_data */ - ev = new CallExitRoutineProxyEvent(exit_routine, URL_s, status, - format_out, window_id); - if (nsnull != ev) { - ev->Fire(); + if (NULL != window_id->modular_data) { + /* + * Always use a PLEvent to call the exit_routine(...). This is necessary + * because when a connection is interrupted, the exit_routine(...) is called + * inside of the LIBNET_LOCK(). + * + * By always using an event, we are sure that the exit_routine(...) is not + * called while the thread is holding the LIBNET_LOCK(). + */ + ev = new CallExitRoutineProxyEvent(exit_routine, URL_s, status, + format_out, window_id); + if (nsnull != ev) { + ev->Fire((PLEventQueue*)URL_s->owner_data); + } + } else { + net_CallExitRoutine(exit_routine, URL_s, status, format_out, window_id); } }