From 981c6e2d15eaedf2d908d28c211a8d5dafa2e010 Mon Sep 17 00:00:00 2001 From: "dougt%netscape.com" Date: Sat, 29 May 1999 22:50:25 +0000 Subject: [PATCH] Adding a few more functions to nsIEventQueue. Moving proxy to use nsIEventQueue instead of PLEvents direct. --- xpcom/proxy/public/nsProxyEvent.h | 22 +++++++- xpcom/proxy/src/nsProxyEvent.cpp | 77 +++++++++++++++++++-------- xpcom/proxy/src/nsProxyEventClass.cpp | 18 ++++--- xpcom/proxy/src/nsProxyEventPrivate.h | 6 ++- xpcom/proxy/tests/proxytests.cpp | 8 +-- xpcom/threads/nsEventQueue.cpp | 35 ++++++++++++ xpcom/threads/nsEventQueue.h | 22 +++++--- xpcom/threads/nsIEventQueue.h | 16 ++++-- 8 files changed, 154 insertions(+), 50 deletions(-) diff --git a/xpcom/proxy/public/nsProxyEvent.h b/xpcom/proxy/public/nsProxyEvent.h index cad46d19863..460adb0f84a 100644 --- a/xpcom/proxy/public/nsProxyEvent.h +++ b/xpcom/proxy/public/nsProxyEvent.h @@ -23,6 +23,7 @@ #include "nsISupports.h" #include "nsIFactory.h" +#include "nsIEventQueue.h" #include "plevent.h" #include "xptcall.h" @@ -34,6 +35,23 @@ typedef enum } ProxyType; +// 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. +// + + // Using the ISupports interface just for addrefing. @@ -65,12 +83,12 @@ class nsProxyObject : public nsISupports nsISupports* GetRealObject() const { return mRealObject; } - PLEventQueue* GetQueue() const { return mDestQueue; } + nsIEventQueue* GetQueue() const { return mDestQueue; } ProxyType GetProxyType() const { return mProxyType; } private: - PLEventQueue *mDestQueue; /* destination queue */ + nsIEventQueue *mDestQueue; /* destination queue */ nsISupports *mRealObject; /* the non-proxy object that this event is referring to */ PRBool mRealObjectOwned; diff --git a/xpcom/proxy/src/nsProxyEvent.cpp b/xpcom/proxy/src/nsProxyEvent.cpp index d72495ff71d..aabb46d39da 100644 --- a/xpcom/proxy/src/nsProxyEvent.cpp +++ b/xpcom/proxy/src/nsProxyEvent.cpp @@ -50,9 +50,9 @@ nsProxyObjectCallInfo::~nsProxyObjectCallInfo() } -static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); NS_IMPL_ISUPPORTS(nsProxyObject, kISupportsIID) +static NS_DEFINE_IID(kIEventQIID, NS_IEVENTQUEUE_IID); nsProxyObject::nsProxyObject() { @@ -73,10 +73,20 @@ nsProxyObject::nsProxyObject(PLEventQueue *destQueue, ProxyType proxyType, nsISu mRealObjectOwned = PR_FALSE; mRealObject = realObject; - mDestQueue = destQueue; mProxyType = proxyType; mRealObject->AddRef(); + + nsresult rv = nsComponentManager::CreateInstance(NS_EVENTQUEUE_PROGID, + nsnull, + kIEventQIID, + (void **)&mDestQueue); + + if (NS_SUCCEEDED(rv)) + { + mDestQueue->InitFromPLQueue(destQueue); + } + } @@ -86,7 +96,6 @@ nsProxyObject::nsProxyObject(PLEventQueue *destQueue, ProxyType proxyType, const NS_ADDREF_THIS(); mRealObjectOwned = PR_TRUE; - mDestQueue = destQueue; mProxyType = proxyType; nsresult rv = nsComponentManager::CreateInstance(aClass, @@ -99,13 +108,25 @@ nsProxyObject::nsProxyObject(PLEventQueue *destQueue, ProxyType proxyType, const mRealObjectOwned = PR_FALSE; mRealObject = nsnull; } + + rv = nsComponentManager::CreateInstance(NS_EVENTQUEUE_PROGID, + nsnull, + kIEventQIID, + (void **)&mDestQueue); + + if (NS_SUCCEEDED(rv)) + { + mDestQueue->InitFromPLQueue(destQueue); + } + } nsProxyObject::~nsProxyObject() { - PL_ENTER_EVENT_QUEUE_MONITOR(mDestQueue); - PL_RevokeEvents(mDestQueue, this); - + if (mDestQueue) + mDestQueue->EnterMonitor(); + // Shit! mDestQueue->RevokeEvents(this); + if(mRealObject != nsnull) { if (!mRealObjectOwned) @@ -114,7 +135,11 @@ nsProxyObject::~nsProxyObject() NS_RELEASE(mRealObject); } - PL_EXIT_EVENT_QUEUE_MONITOR(mDestQueue); + if (mDestQueue) + mDestQueue->ExitMonitor(); + + if (mDestQueue != nsnull) + NS_RELEASE(mDestQueue); } nsresult @@ -123,7 +148,13 @@ nsProxyObject::Post( PRUint32 methodIndex, /* which method to nsXPTCVariant *params) { - PL_ENTER_EVENT_QUEUE_MONITOR(mDestQueue); + if (mDestQueue == nsnull) + return NS_ERROR_OUT_OF_MEMORY; + + if (mRealObject == nsnull) + return NS_ERROR_OUT_OF_MEMORY; + + mDestQueue->EnterMonitor(); NS_ASSERTION(mRealObject, "no native object"); @@ -133,7 +164,7 @@ nsProxyObject::Post( PRUint32 methodIndex, /* which method to if (event == nsnull) { - PL_EXIT_EVENT_QUEUE_MONITOR(mDestQueue); + mDestQueue->ExitMonitor(); return NS_ERROR_OUT_OF_MEMORY; } @@ -147,27 +178,22 @@ nsProxyObject::Post( PRUint32 methodIndex, /* which method to if (mProxyType == PROXY_SYNC) { - PL_PostSynchronousEvent(mDestQueue, event); + mDestQueue->PostSynchronousEvent(event, nsnull); nsresult rv = info->GetResult(); - delete info; - PL_EXIT_EVENT_QUEUE_MONITOR(mDestQueue); - + mDestQueue->ExitMonitor(); return rv; - } else if (mProxyType == PROXY_ASYNC) { - PL_PostEvent(mDestQueue, event); - - PL_EXIT_EVENT_QUEUE_MONITOR(mDestQueue); - + mDestQueue->PostEvent(event); + mDestQueue->ExitMonitor(); return NS_OK; } - PL_EXIT_EVENT_QUEUE_MONITOR(mDestQueue); + mDestQueue->ExitMonitor(); return NS_ERROR_UNEXPECTED; } @@ -191,12 +217,17 @@ void* EventHandler(PLEvent *self) { nsProxyObjectCallInfo *info = (nsProxyObjectCallInfo*)PL_GetEventOwner(self); nsProxyObject *proxyObject = info->GetProxyObject(); - PLEventQueue *eventQ = proxyObject->GetQueue(); + nsIEventQueue *eventQ = proxyObject->GetQueue(); if (info != nsnull) { - - PL_ENTER_EVENT_QUEUE_MONITOR(eventQ); + if (eventQ == nsnull || proxyObject == nsnull) + { + info->SetResult(NS_ERROR_OUT_OF_MEMORY) ; + return NULL; + } + + eventQ->EnterMonitor(); // invoke the magic of xptc... nsresult rv = XPTC_InvokeByIndex( proxyObject->GetRealObject(), @@ -206,7 +237,7 @@ void* EventHandler(PLEvent *self) info->SetResult(rv); - PL_EXIT_EVENT_QUEUE_MONITOR(eventQ); + eventQ->ExitMonitor(); } return NULL; } diff --git a/xpcom/proxy/src/nsProxyEventClass.cpp b/xpcom/proxy/src/nsProxyEventClass.cpp index 473db5b6365..4de52ebbaaf 100644 --- a/xpcom/proxy/src/nsProxyEventClass.cpp +++ b/xpcom/proxy/src/nsProxyEventClass.cpp @@ -201,13 +201,19 @@ nsProxyEventClass::CallQueryInterfaceOnProxy(nsProxyEventObject* self, REFNSIID if (rv == NS_OK) { - nsProxyEventObject* proxyObj = nsProxyEventObject::GetNewOrUsedProxy(self->GetQueue(), PROXY_SYNC, aInstancePtr, aIID); - if(proxyObj) + PLEventQueue* aEventQueue; + + self->GetQueue()->GetPLEventQueue(&aEventQueue); + + if (aEventQueue != nsnull) { - return proxyObj; - } - } - + nsProxyEventObject* proxyObj = nsProxyEventObject::GetNewOrUsedProxy(aEventQueue, PROXY_SYNC, aInstancePtr, aIID); + if(proxyObj) + { + return proxyObj; + } + } + } return nsnull; } diff --git a/xpcom/proxy/src/nsProxyEventPrivate.h b/xpcom/proxy/src/nsProxyEventPrivate.h index 2f282f564ba..a5b8b4f99ef 100644 --- a/xpcom/proxy/src/nsProxyEventPrivate.h +++ b/xpcom/proxy/src/nsProxyEventPrivate.h @@ -25,6 +25,7 @@ #include "plevent.h" #include "xptcall.h" // defines nsXPTCVariant +#include "nsIEventQueue.h" #include "nsProxyEvent.h" #include "nsProxyObjectManager.h" @@ -88,8 +89,9 @@ public: REFNSIID aIID); - PLEventQueue* GetQueue() const { return mProxyObject->GetQueue(); } - + nsIEventQueue* GetQueue() const { return mProxyObject->GetQueue(); } + nsIEventQueue* GetPLQueue() const { return mProxyObject->GetQueue(); } + REFNSIID GetIID() const {return GetClass()->GetIID();} nsProxyEventClass* GetClass() const { return mClass; } diff --git a/xpcom/proxy/tests/proxytests.cpp b/xpcom/proxy/tests/proxytests.cpp index 70964164495..d8684b78878 100644 --- a/xpcom/proxy/tests/proxytests.cpp +++ b/xpcom/proxy/tests/proxytests.cpp @@ -262,9 +262,9 @@ void TestCase_TwoClassesOneInterface(void *arg) PR_ASSERT(foo); PR_ASSERT(foo2); - proxyObjectFactory->GetProxyObject(argsStruct->queue, nsITestXPCFoo::GetIID(), foo, PROXY_ASYNC, (void**)&proxyObject); + proxyObjectFactory->GetProxyObject(argsStruct->queue, nsITestXPCFoo::GetIID(), foo, PROXY_SYNC, (void**)&proxyObject); - proxyObjectFactory->GetProxyObject(argsStruct->queue, nsITestXPCFoo::GetIID(), foo2, PROXY_ASYNC, (void**)&proxyObject2); + proxyObjectFactory->GetProxyObject(argsStruct->queue, nsITestXPCFoo::GetIID(), foo2, PROXY_SYNC, (void**)&proxyObject2); if (proxyObject && proxyObject2) { @@ -305,7 +305,7 @@ void TestCase_TwoClassesOneInterface(void *arg) NS_RELEASE(proxyObject2); } - PR_Sleep( PR_MillisecondsToInterval(10000) ); + // PR_Sleep( PR_MillisecondsToInterval(10000) ); // If your thread goes away, your stack goes away. Only use ASYNC on calls that do not have out parameters } @@ -410,7 +410,7 @@ main(int argc, char **argv) 0 ); - PR_Sleep(PR_MillisecondsToInterval(5000)); + PR_Sleep(PR_MillisecondsToInterval(1000)); PR_ASSERT(gEventQueue); // BAD BAD BAD. EVENT THREAD DID NOT CREATE QUEUE. This may be a timing issue, set the // sleep about longer, and try again. diff --git a/xpcom/threads/nsEventQueue.cpp b/xpcom/threads/nsEventQueue.cpp index aa765b716f9..b819ff376eb 100644 --- a/xpcom/threads/nsEventQueue.cpp +++ b/xpcom/threads/nsEventQueue.cpp @@ -70,6 +70,41 @@ nsEventQueueImpl::PostSynchronousEvent(PLEvent* aEvent, void** aResult) 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) +{ + PL_RevokeEvents(mEventQueue, owner); + return NS_OK; +} + + +NS_IMETHODIMP +nsEventQueueImpl::GetPLEventQueue(PLEventQueue** aEventQueue) +{ + *aEventQueue = mEventQueue; + + if (mEventQueue == NULL) + return NS_ERROR_NULL_POINTER; + + return NS_OK; +} + + NS_IMETHODIMP nsEventQueueImpl::ProcessPendingEvents() { diff --git a/xpcom/threads/nsEventQueue.h b/xpcom/threads/nsEventQueue.h index 03ae7a4e41f..a9a142e1aa5 100644 --- a/xpcom/threads/nsEventQueue.h +++ b/xpcom/threads/nsEventQueue.h @@ -25,30 +25,36 @@ static NS_DEFINE_IID(kIEventQueueIID, NS_IEVENTQUEUE_IID); class nsEventQueueImpl : public nsIEventQueue { public: - nsEventQueueImpl(); - virtual ~nsEventQueueImpl(); + nsEventQueueImpl(); + virtual ~nsEventQueueImpl(); // nsISupports interface... - NS_DECL_ISUPPORTS + NS_DECL_ISUPPORTS // nsIEventQueue interface... NS_IMETHOD_(PRStatus) PostEvent(PLEvent* aEvent); NS_IMETHOD PostSynchronousEvent(PLEvent* aEvent, void** aResult); - NS_IMETHOD ProcessPendingEvents(); + NS_IMETHOD ProcessPendingEvents(); NS_IMETHOD EventLoop(); - NS_IMETHOD EventAvailable(PRBool& aResult); + NS_IMETHOD EventAvailable(PRBool& aResult); NS_IMETHOD GetEvent(PLEvent** aResult); - NS_IMETHOD_(PRInt32) GetEventQueueSelectFD(); + NS_IMETHOD_(PRInt32) GetEventQueueSelectFD(); NS_IMETHOD Init(); NS_IMETHOD InitFromPLQueue(PLEventQueue* aQueue); + NS_IMETHOD EnterMonitor(); + NS_IMETHOD ExitMonitor(); + + NS_IMETHOD RevokeEvents(void* owner); + + NS_IMETHOD GetPLEventQueue(PLEventQueue** aEventQueue); + // Helpers - static NS_METHOD - Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr); + static NS_METHOD Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr); static const nsCID& CID() { static nsCID cid = NS_EVENTQUEUE_CID; return cid; } diff --git a/xpcom/threads/nsIEventQueue.h b/xpcom/threads/nsIEventQueue.h index 22cbc6f06c1..0775671d666 100644 --- a/xpcom/threads/nsIEventQueue.h +++ b/xpcom/threads/nsIEventQueue.h @@ -40,19 +40,25 @@ class nsIEventQueue : public nsISupports public: static const nsIID& GetIID() { static nsIID iid = NS_IEVENTQUEUE_IID; return iid;} - NS_IMETHOD_(PRStatus) PostEvent(PLEvent* aEvent) = 0; - NS_IMETHOD PostSynchronousEvent(PLEvent* aEvent, void** aResult) = 0; + NS_IMETHOD_(PRStatus) PostEvent(PLEvent* aEvent) = 0; + NS_IMETHOD PostSynchronousEvent(PLEvent* aEvent, void** aResult) = 0; - NS_IMETHOD ProcessPendingEvents() = 0; - NS_IMETHOD EventLoop() = 0; + NS_IMETHOD ProcessPendingEvents() = 0; + NS_IMETHOD EventLoop() = 0; NS_IMETHOD EventAvailable(PRBool& aResult) = 0; NS_IMETHOD GetEvent(PLEvent** aResult) = 0; - NS_IMETHOD_(PRInt32) GetEventQueueSelectFD() = 0; + NS_IMETHOD_(PRInt32) GetEventQueueSelectFD() = 0; NS_IMETHOD Init() = 0; NS_IMETHOD InitFromPLQueue(PLEventQueue* aQueue) = 0; + + NS_IMETHOD EnterMonitor() = 0; + NS_IMETHOD ExitMonitor() = 0; + + NS_IMETHOD RevokeEvents(void* owner) = 0; + NS_IMETHOD GetPLEventQueue(PLEventQueue** aEventQueue) = 0; }; #endif /* nsIEventQueue_h___ */