diff --git a/xpcom/proxy/src/nsProxyEvent.cpp b/xpcom/proxy/src/nsProxyEvent.cpp index c5719cb3b8e..7c062c7fd3c 100644 --- a/xpcom/proxy/src/nsProxyEvent.cpp +++ b/xpcom/proxy/src/nsProxyEvent.cpp @@ -72,6 +72,7 @@ nsProxyObjectCallInfo::SetCompleted() PR_AtomicSet(&mCompleted, 1); } +#define debug_DOUGT #ifdef debug_DOUGT static PRUint32 totalProxyObjects = 0; @@ -160,6 +161,11 @@ nsProxyObject::NestedEventLoop(nsProxyObjectCallInfo *proxyInfo) rv = eventQService->GetThreadEventQueue(PR_CurrentThread(), &eventQ); } + else + { + NS_RELEASE(eventQ); + rv = eventQService->PushThreadEventQueue(&eventQ); + } if (NS_FAILED(rv)) return rv; @@ -169,12 +175,21 @@ nsProxyObject::NestedEventLoop(nsProxyObjectCallInfo *proxyInfo) rv = eventQ->GetEvent(&event); if (NS_FAILED(rv)) break; eventQ->HandleEvent(event); + + PR_Sleep( PR_MillisecondsToInterval(5) ); } - NS_RELEASE(eventQ); + if (eventLoopCreated) - eventQService->DestroyThreadEventQueue(); + { + NS_RELEASE(eventQ); + eventQService->DestroyThreadEventQueue(); + } + else + { + eventQService->PopThreadEventQueue(eventQ); + } return rv; } @@ -259,9 +274,8 @@ nsProxyObject::Post( PRUint32 methodIndex, nsXPTMethodInfo *methodInfo, nsXPTCMi else { mDestQueue->PostEvent(event); - rv = NestedEventLoop(proxyInfo); - + //mDestQueue->PostSynchronousEvent(event, nsnull); if (NS_FAILED(rv)) return rv; } diff --git a/xpcom/proxy/src/nsProxyEventClass.cpp b/xpcom/proxy/src/nsProxyEventClass.cpp index fdfddee20ab..ab10f5524f7 100644 --- a/xpcom/proxy/src/nsProxyEventClass.cpp +++ b/xpcom/proxy/src/nsProxyEventClass.cpp @@ -175,6 +175,7 @@ nsProxyEventClass::~nsProxyEventClass() nsresult nsProxyEventClass::CallQueryInterfaceOnProxy(nsProxyEventObject* self, REFNSIID aIID, nsProxyEventObject** aInstancePtr) { + nsresult rv; *aInstancePtr = (nsProxyEventObject*)0xDEADBEEF; // in case of error. @@ -197,7 +198,15 @@ nsProxyEventClass::CallQueryInterfaceOnProxy(nsProxyEventObject* self, REFNSIID iim->GetInfoForName("nsISupports", &nsISupportsInfo); nsISupportsInfo->GetMethodInfo(0, &mi); // 0 is QueryInterface - return self->CallMethod(0, mi, var); + rv = self->CallMethod(0, mi, var); + + // if we are going to return another interface, + // lets make sure that we increment the wrapper. + + if (NS_SUCCEEDED(rv)) + NS_ADDREF(self); + + return rv; } @@ -230,14 +239,12 @@ nsProxyEventClass::DelegatedQueryInterface(nsProxyEventObject* self, REFNSIID aIID, void** aInstancePtr) { - if(aIID.Equals(nsCOMTypeInfo::GetIID())) + if(NULL == aInstancePtr) { - nsProxyEventObject* root = self->GetRootProxyObject(); - *aInstancePtr = (void*) root; - NS_ADDREF(root); - return NS_OK; + NS_PRECONDITION(0, "null pointer"); + return NS_ERROR_NULL_POINTER; } - + if(aIID.Equals(self->GetIID())) { *aInstancePtr = (void*) self; @@ -251,15 +258,5 @@ nsProxyEventClass::DelegatedQueryInterface(nsProxyEventObject* self, return NS_OK; } - return CallQueryInterfaceOnProxy(self, aIID, (nsProxyEventObject**)aInstancePtr); } - - - -nsresult -nsProxyEventClass::GetRootProxyObject(nsProxyEventObject* anObject, nsProxyEventObject** result) -{ - return CallQueryInterfaceOnProxy(anObject, nsCOMTypeInfo::GetIID(), result); -} - diff --git a/xpcom/proxy/src/nsProxyEventObject.cpp b/xpcom/proxy/src/nsProxyEventObject.cpp index d32dc771695..65356ace859 100644 --- a/xpcom/proxy/src/nsProxyEventObject.cpp +++ b/xpcom/proxy/src/nsProxyEventObject.cpp @@ -147,7 +147,6 @@ return_wrapper: // if (rootObject) NS_RELEASE(rootObject); - return proxy; } @@ -163,85 +162,64 @@ nsProxyEventObject::nsProxyEventObject(nsIEventQueue *destQueue, : mClass(aClass), mNext(NULL) { - mRoot = (root ? root : this); - mProxyObject = new nsProxyObject(destQueue, proxyType, aObj); - NS_INIT_REFCNT(); NS_ADDREF_THIS(); + + mProxyObject = new nsProxyObject(destQueue, proxyType, aObj); + + mRoot = (root ? root : this); + + // if we have a root, lets addref it. + if (root) + NS_ADDREF(mRoot); + NS_ADDREF(aClass); } nsProxyEventObject::~nsProxyEventObject() { - NS_PRECONDITION(0 == mRefCnt, "refcounting error"); - if(mRoot == this && GetClass()) - { - nsProxyObjectManager *manager = nsProxyObjectManager::GetInstance(); - nsHashtable *realToProxyMap = manager->GetRealObjectToProxyObjectMap(); - - if (realToProxyMap != nsnull) - { - nsVoidKey key(this); - realToProxyMap->Remove(&key); - } - } - - if (mProxyObject != nsnull) - mProxyObject->Release(); - - NS_RELEASE(mClass); + NS_IF_RELEASE(mProxyObject); + NS_IF_RELEASE(mClass); - if(mNext) - NS_DELETEXPCOM(mNext); // cascaded delete + if (mRoot) + { + if (mRoot != this) + { + mRoot->RootRemoval(); + } + else + { + nsProxyObjectManager *manager = nsProxyObjectManager::GetInstance(); + nsHashtable *realToProxyMap = manager->GetRealObjectToProxyObjectMap(); + + if (realToProxyMap != nsnull) + { + nsVoidKey key(this); + realToProxyMap->Remove(&key); + } + } + } } +nsresult +nsProxyEventObject::RootRemoval() +{ + if (--mRefCnt <= 1) + NS_DELETEXPCOM(this); + return NS_OK; +} + +NS_IMPL_ADDREF(nsProxyEventObject); +NS_IMPL_RELEASE(nsProxyEventObject); NS_IMETHODIMP nsProxyEventObject::QueryInterface(REFNSIID aIID, void** aInstancePtr) { - if(NULL == aInstancePtr) - { - NS_PRECONDITION(0, "null pointer"); - return NS_ERROR_NULL_POINTER; - } + // TODO: we need to wrap the object if it is not a proxy. return mClass->DelegatedQueryInterface(this, aIID, aInstancePtr); } - -nsrefcnt -nsProxyEventObject::AddRef(void) -{ - NS_PRECONDITION(mRoot, "bad root"); - - ++mRefCnt; - NS_LOG_ADDREF(this, mRefCnt, "nsProxyEventObject", sizeof(*this)); - if(1 == mRefCnt && mRoot && mRoot != this) - NS_ADDREF(mRoot); - - return mRefCnt; -} - -nsrefcnt -nsProxyEventObject::Release(void) -{ - NS_PRECONDITION(mRoot, "bad root"); - --mRefCnt; - NS_LOG_RELEASE(this, mRefCnt, "nsProxyEventObject"); - - if(0 == mRefCnt) - { - NS_DELETEXPCOM(this); - return 0; - } -#if 0 // removed on dougt's suggestion - else if(1 == mRefCnt) - mRoot->Release(); // do NOT zero out the ptr (weak ref) -#endif - return mRefCnt; -} - - nsProxyEventObject* nsProxyEventObject::Find(REFNSIID aIID) { diff --git a/xpcom/proxy/src/nsProxyEventPrivate.h b/xpcom/proxy/src/nsProxyEventPrivate.h index cd268ba6dfd..445bb644738 100644 --- a/xpcom/proxy/src/nsProxyEventPrivate.h +++ b/xpcom/proxy/src/nsProxyEventPrivate.h @@ -55,7 +55,6 @@ public: REFNSIID GetIID() const {return mIID;} nsIInterfaceInfo* GetInterfaceInfo() const {return mInfo;} - nsresult GetRootProxyObject(nsProxyEventObject* anObject, nsProxyEventObject** result); nsresult CallQueryInterfaceOnProxy(nsProxyEventObject* self, REFNSIID aIID, nsProxyEventObject** aInstancePtr); protected: @@ -90,14 +89,9 @@ public: REFNSIID GetIID() const { return GetClass()->GetIID();} - - nsIEventQueue* GetQueue() const { return mProxyObject->GetQueue(); } - nsIEventQueue* GetPLQueue() const { return mProxyObject->GetQueue(); } nsProxyEventClass* GetClass() const { return mClass; } + nsIEventQueue* GetQueue() const { return mProxyObject->GetQueue(); } nsISupports* GetRealObject() const { return mProxyObject->GetRealObject(); } - nsProxyEventObject* GetRootProxyObject() const { return mRoot; } - - nsProxyEventObject* Find(REFNSIID aIID); protected: @@ -108,8 +102,11 @@ protected: nsISupports* aObj, nsProxyEventClass* aClass, nsProxyEventObject* root); + + nsProxyEventObject* Find(REFNSIID aIID); private: + nsresult RootRemoval(); nsProxyObject* mProxyObject; nsProxyEventClass* mClass;