Index: public/nsProxiedService.h =================================================================== RCS file: /cvsroot/mozilla/xpcom/proxy/public/nsProxiedService.h,v retrieving revision 1.16 diff -u -p -r1.16 nsProxiedService.h --- public/nsProxiedService.h 7 Nov 2004 23:59:33 -0000 1.16 +++ public/nsProxiedService.h 18 Apr 2006 02:56:47 -0000 @@ -119,7 +119,7 @@ public: private: void InitProxy(nsISupports *aObj, const nsIID &aIID, - nsIEventQueue* aEventQ, PRBool always, nsresult*rv) + nsIEventQueue* aEventQ, PRBool always, nsresult* rv) { PRInt32 proxyType = PROXY_SYNC; if (always) Index: public/nsProxyEvent.h =================================================================== RCS file: /cvsroot/mozilla/xpcom/proxy/public/nsProxyEvent.h,v retrieving revision 1.35 diff -u -p -r1.35 nsProxyEvent.h --- public/nsProxyEvent.h 28 Jan 2006 16:25:25 -0000 1.35 +++ public/nsProxyEvent.h 18 Apr 2006 02:56:47 -0000 @@ -145,6 +145,7 @@ public: ~nsProxyObjectCallInfo(); PRUint32 GetMethodIndex() const { return mMethodIndex; } + nsXPTMethodInfo* GetMethodInfo() const { return mMethodInfo; } nsXPTCVariant* GetParameterList() const { return mParameterList; } PRUint32 GetParameterCount() const { return mParameterCount; } PLEvent* GetPLEvent() const { return mEvent; } Index: src/nsProxyEvent.cpp =================================================================== RCS file: /cvsroot/mozilla/xpcom/proxy/src/nsProxyEvent.cpp,v retrieving revision 1.80 diff -u -p -r1.80 nsProxyEvent.cpp --- src/nsProxyEvent.cpp 28 Jan 2006 15:46:11 -0000 1.80 +++ src/nsProxyEvent.cpp 18 Apr 2006 02:56:47 -0000 @@ -549,9 +549,9 @@ 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... @@ -559,6 +559,29 @@ static void* EventHandler(PLEvent *self) info->GetMethodIndex(), info->GetParameterCount(), info->GetParameterList()); + if (NS_SUCCEEDED(rv) && + info->GetMethodIndex() == 0 && + info->GetParameterCount() == 2 && + 1) + { + const nsXPTParamInfo paramInfo = info->GetMethodInfo()->GetParam(0); + const nsXPTType& type = paramInfo.GetType(); + const nsXPTCVariant *parameterList = info->GetParameterList(); + uint8 type_tag = type.TagPart(); + if(paramInfo.IsIn() && type_tag == nsXPTType::T_IID) + { + const nsIID iid = *(nsIID*)parameterList[0].val.p; + void *proxy = nsnull; + nsresult rv = + NS_GetProxyForObject(proxyObject->GetQueue(), + iid, + (nsISupports*)parameterList[1].val.p, + proxyObject->GetProxyType(), + (void**)&proxy); + ((nsISupports*)parameterList[1].val.p)->Release(); + (void*)parameterList[1].val.p = proxy; + } + } info->SetResult(rv); } else Index: src/nsProxyEventClass.cpp =================================================================== RCS file: /cvsroot/mozilla/xpcom/proxy/src/nsProxyEventClass.cpp,v retrieving revision 1.46 diff -u -p -r1.46 nsProxyEventClass.cpp --- src/nsProxyEventClass.cpp 25 Nov 2005 19:48:02 -0000 1.46 +++ src/nsProxyEventClass.cpp 18 Apr 2006 02:56:47 -0000 @@ -219,15 +219,15 @@ nsProxyEventClass::~nsProxyEventClass() nsCOMPtr manager = getter_AddRefs(nsProxyObjectManager::GetInstance()); if (manager == nsnull) return; - nsHashtable *iidToClassMap = manager->GetIIDToProxyClassMap(); + nsHashtable *iidToClassMap = manager->GetIIDToProxyClassMap(); if (iidToClassMap != nsnull) { iidToClassMap->Remove(&key); #ifdef PROXYEVENTCLASS_DEBUG - char* iidStr = mIID.ToString(); - printf("GetNewOrUsedClass %s remove\n", iidStr); - nsCRT::free(iidStr); + char* iidStr = mIID.ToString(); + printf("GetNewOrUsedClass %s remove\n", iidStr); + nsCRT::free(iidStr); #endif } #endif @@ -286,7 +286,7 @@ nsProxyEventClass::CallQueryInterfaceOnP } NS_IF_RELEASE((*aInstancePtr)); - (*aInstancePtr) = NS_STATIC_CAST(nsProxyEventObject*, aIdentificationObject); + (*aInstancePtr) = NS_STATIC_CAST(nsProxyEventObject*, NS_STATIC_CAST(nsIClassInfo*, aIdentificationObject)); } return rv; } @@ -333,41 +333,41 @@ nsProxyEventClass::DelegatedQueryInterfa 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; + // 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; + } - while(NS_SUCCEEDED(current->GetParent(getter_AddRefs(parent))) && parent) - { - current = parent; + // check if asking for an interface that we inherit from + nsCOMPtr current = GetInterfaceInfo(); + nsCOMPtr parent; - nsIID* iid; - if(NS_SUCCEEDED(current->GetInterfaceIID(&iid)) && iid) + while(NS_SUCCEEDED(current->GetParent(getter_AddRefs(parent))) && parent) { - PRBool found = aIID.Equals(*iid); - nsMemory::Free(iid); - if(found) + 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); } Index: src/nsProxyEventObject.cpp =================================================================== RCS file: /cvsroot/mozilla/xpcom/proxy/src/nsProxyEventObject.cpp,v retrieving revision 1.50 diff -u -p -r1.50 nsProxyEventObject.cpp --- src/nsProxyEventObject.cpp 28 Jan 2006 15:46:11 -0000 1.50 +++ src/nsProxyEventObject.cpp 18 Apr 2006 02:56:47 -0000 @@ -111,12 +111,12 @@ nsProxyEventObject::DebugDump(const char printf("\n-=-=-=-=-=-=-=-=-=-=-=-=-\n"); printf("%s\n", message); - if(strcmp(message, "Create") == 0) + if (strcmp(message, "Create") == 0) { totalProxyObjects++; outstandingProxyObjects++; } - else if(strcmp(message, "Delete") == 0) + else if (strcmp(message, "Delete") == 0) { outstandingProxyObjects--; } @@ -130,20 +130,20 @@ nsProxyEventObject::DebugDump(const char nsCOMPtr rootQueue = do_QueryInterface(mProxyObject->mDestQueue); nsProxyEventKey key(rootObject, rootQueue, mProxyObject->mProxyType); printf("Hashkey: %d\n", key.HashCode()); - + char* name; GetClass()->GetInterfaceInfo()->GetName(&name); printf("interface name is %s\n", name); - if(name) + if (name) nsMemory::Free(name); char * iid = GetClass()->GetProxiedIID().ToString(); printf("IID number is %s\n", iid); delete iid; printf("nsProxyEventClass @ %x\n", mClass); - - if(mNext) + + if (mNext) { - if(isRoot) + if (isRoot) { printf("Additional wrappers for this object...\n"); } @@ -166,9 +166,9 @@ nsProxyEventObject::DebugDump(const char // nsProxyEventObject // ////////////////////////////////////////////////////////////////////////////////////////////////// -nsProxyEventObject* +nsProxyEventObject* nsProxyEventObject::GetNewOrUsedProxy(nsIEventQueue *destQueue, - PRInt32 proxyType, + PRInt32 proxyType, nsISupports *aObj, REFNSIID aIID) { @@ -177,18 +177,47 @@ nsProxyEventObject::GetNewOrUsedProxy(ns if (!aObj) return nsnull; - nsISupports* rawObject = aObj; - // - // make sure that the object pass in is not a proxy... - // if the object *is* a proxy, then be nice and build the proxy - // for the real object... + // Enter the proxy object creation lock. // - nsCOMPtr identificationObject; + // This lock protects thev linked list which chains proxies together + // (ie. mRoot and mNext) and ensures that there is no hashtable contention + // between the time that a proxy is looked up (and not found) in the + // hashtable and then added... + // + nsProxyObjectManager *manager = nsProxyObjectManager::GetInstance(); + if (!manager) { + return nsnull; + } + + nsCOMPtr eventQService(do_GetService(kEventQueueServiceCID, &rv)); + if (NS_FAILED(rv)) + return nsnull; + + nsISupports* rawObject; + nsHashtable *realToProxyMap, *proxyToRealMap; + { + nsAutoMonitor mon(manager->GetMonitor()); + + // Get the hash table containing root proxy objects... + realToProxyMap = manager->GetRealObjectToProxyObjectMap(); + if (!realToProxyMap) { + return nsnull; + } + proxyToRealMap = manager->GetProxyObjectToRealObjectMap(); + if (!proxyToRealMap) { + return nsnull; + } - rv = rawObject->QueryInterface(kProxyObject_Identity_Class_IID, - getter_AddRefs(identificationObject)); - if (NS_SUCCEEDED(rv)) { + // + // make sure that the object pass in is not a proxy... + // if the object *is* a proxy, then be nice and build the proxy + // for the real object... + // + nsProxyEventKey peokey(aObj, nsnull, 0); + rawObject = (nsISupports*)proxyToRealMap->Get(&peokey); + } + if (rawObject) { // // ATTENTION!!!! // @@ -199,8 +228,12 @@ nsProxyEventObject::GetNewOrUsedProxy(ns // 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_ERROR("Someone is building a proxy from a proxy"); + + nsRefPtr identificationObject; + + rv = rawObject->QueryInterface(kProxyObject_Identity_Class_IID, + getter_AddRefs(identificationObject)); NS_ASSERTION(identificationObject, "where did my identification object go!"); if (!identificationObject) { return nsnull; @@ -214,6 +247,9 @@ nsProxyEventObject::GetNewOrUsedProxy(ns if (!rawObject) { return nsnull; } + } else { + // XXX need to wrap this in a proxy + rawObject = aObj; } // @@ -234,31 +270,9 @@ nsProxyEventObject::GetNewOrUsedProxy(ns return nsnull; } - // - // Enter the proxy object creation lock. - // - // This lock protects thev linked list which chains proxies together - // (ie. mRoot and mNext) and ensures that there is no hashtable contention - // between the time that a proxy is looked up (and not found) in the - // hashtable and then added... - // - nsProxyObjectManager *manager = nsProxyObjectManager::GetInstance(); - if (!manager) { - 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... - nsHashtable *realToProxyMap = manager->GetRealObjectToProxyObjectMap(); - if (!realToProxyMap) { - return nsnull; - } - // Now, lookup the root nsISupports of the raw object in the hashtable // The key consists of 3 pieces of information: // - root nsISupports of the raw object @@ -267,14 +281,13 @@ nsProxyEventObject::GetNewOrUsedProxy(ns // nsProxyEventKey rootkey(rootObject.get(), destQRoot.get(), proxyType); - nsCOMPtr rootProxy; - nsCOMPtr proxy; - nsProxyEventObject* peo; + nsRefPtr rootProxy; + nsRefPtr peo; - // find in our hash table + // find in our hash table rootProxy = (nsProxyEventObject*) realToProxyMap->Get(&rootkey); - if(rootProxy) { + if (rootProxy) { // // At least one proxy has already been created for this raw object... // @@ -285,13 +298,13 @@ nsProxyEventObject::GetNewOrUsedProxy(ns if(peo) { // An existing proxy is available... So use it. - NS_ADDREF(peo); + NS_ADDREF((nsXPTCStubBase*)peo); return peo; } } else { // build the root proxy - nsCOMPtr rootClazz; + nsRefPtr rootClazz; rootClazz = dont_AddRef(nsProxyEventClass::GetNewOrUsedClass( NS_GET_IID(nsISupports))); @@ -299,34 +312,59 @@ nsProxyEventObject::GetNewOrUsedProxy(ns return nsnull; } - peo = new nsProxyEventObject(destQueue, - proxyType, - rootObject, - rootClazz, + peo = CreateProxyEventObject(destQueue, + proxyType, + rootObject, + rootClazz, nsnull, eventQService); - if(!peo) { + if (!peo) { // Ouch... Out of memory! return nsnull; } - // Add this root proxy into the hash table... realToProxyMap->Put(&rootkey, peo); + nsProxyEventKey peokey(peo, nsnull, 0); + proxyToRealMap->Put(&peokey, rootObject); - if(aIID.Equals(NS_GET_IID(nsISupports))) { + if (!aIID.Equals(NS_GET_IID(nsIClassInfo))) { + nsIClassInfo* poCI = nsnull; + rv = NS_GetProxyForObject( + destQueue, + NS_GET_IID(nsIClassInfo), + rootObject, + nsIProxyObjectManager::INVOKE_SYNC | nsIProxyObjectManager::FORCE_PROXY_CREATION, + (void**)&poCI); + if (NS_SUCCEEDED(rv) && poCI) { + peo->mProxyObjectCI = poCI; + PRUint32 flags = 0; + rv = poCI->GetFlags(&flags); + if (NS_SUCCEEDED(rv)) { + if (flags & nsIClassInfo::THREADSAFE) { + peo->mProxyObjectCI = do_QueryInterface(aObj); + } + + peo->mFlags |= (flags & ~(nsIClassInfo::SINGLETON | nsIClassInfo::RESERVED)); + } + NS_RELEASE(poCI); + } + } + + if (aIID.Equals(NS_GET_IID(nsISupports))) { // // Since the requested proxy is for the nsISupports interface of // the raw object, use the new root proxy as the specific proxy // too... // - NS_ADDREF(peo); - return peo; + nsProxyEventObject *proxy = peo; + NS_ADDREF(proxy); + return proxy; } // This assignment is an owning reference to the new ProxyEventObject. // So, it will automatically get deleted if any subsequent early // returns are taken... - rootProxy = do_QueryInterface(peo); + rootProxy = peo; } // @@ -336,26 +374,27 @@ nsProxyEventObject::GetNewOrUsedProxy(ns NS_ASSERTION(rootProxy, "What happened to the root proxy!"); // Get a class for this IID. - nsCOMPtr proxyClazz; - + nsRefPtr proxyClazz; + proxyClazz = dont_AddRef(nsProxyEventClass::GetNewOrUsedClass(aIID)); - if(!proxyClazz) { + if (!proxyClazz) { return nsnull; } // Get the raw interface for this IID - nsCOMPtr rawInterface; + nsRefPtr rawInterface; + // XXX this is not thread friendly; ask a caching CI first rv = rawObject->QueryInterface(aIID, getter_AddRefs(rawInterface)); if (NS_FAILED(rv) || !rawInterface) { NS_ASSERTION(NS_FAILED(rv), "where did my rawInterface object go!"); return nsnull; } - peo = new nsProxyEventObject(destQueue, - proxyType, - rawInterface, - proxyClazz, + peo = CreateProxyEventObject(destQueue, + proxyType, + rawInterface, + proxyClazz, rootProxy, eventQService); if (!peo) { @@ -370,9 +409,11 @@ nsProxyEventObject::GetNewOrUsedProxy(ns peo->mNext = rootProxy->mNext; rootProxy->mNext = peo; - NS_ADDREF(peo); - return peo; - + nsProxyEventKey peokey(peo, nsnull, 0); + proxyToRealMap->Put(&peokey, rootObject); + nsProxyEventObject *proxy = peo; + NS_ADDREF(proxy); + return proxy; } nsProxyEventObject* nsProxyEventObject::LockedFind(REFNSIID aIID) @@ -396,26 +437,38 @@ nsProxyEventObject* nsProxyEventObject:: return nsnull; } -nsProxyEventObject::nsProxyEventObject() -: mNext(nsnull) +nsProxyEventObject* +nsProxyEventObject::CreateProxyEventObject(nsIEventQueue *destQueue, + PRInt32 proxyType, + nsISupports* aObj, + nsProxyEventClass* aClass, + nsProxyEventObject* root, + nsIEventQueueService* eventQService) { - NS_WARNING("This constructor should never be called"); + nsProxyEventObject* peo = new nsProxyEventObject(aClass, root); + if (!peo) + return nsnull; + + nsProxyObject* po = new nsProxyObject(destQueue, proxyType, aObj, eventQService); + if (!po) { + delete peo; + return nsnull; + } + + peo->mProxyObject = po; + return peo; } -nsProxyEventObject::nsProxyEventObject(nsIEventQueue *destQueue, - PRInt32 proxyType, - nsISupports* aObj, - nsProxyEventClass* aClass, - nsProxyEventObject* root, - nsIEventQueueService* eventQService) - : mClass(aClass), - mRoot(root), - mNext(nsnull) +nsProxyEventObject::nsProxyEventObject( + nsProxyEventClass* aClass, + nsProxyEventObject* root) + : mClass(aClass), + mRoot(root), + mNext(nsnull), + mFlags(nsIClassInfo::THREADSAFE) { NS_IF_ADDREF(mRoot); - mProxyObject = new nsProxyObject(destQueue, proxyType, aObj, eventQService); - #ifdef DEBUG_xpcom_proxy DebugDump("Create", 0); #endif @@ -426,6 +479,13 @@ nsProxyEventObject::~nsProxyEventObject( #ifdef DEBUG_xpcom_proxy DebugDump("Delete", 0); #endif + nsHashtable *realToProxyMap = nsnull, *proxyToRealMap = nsnull; + nsProxyObjectManager* manager = nsnull; + if (!nsProxyObjectManager::IsManagerShutdown()) { + manager = nsProxyObjectManager::GetInstance(); + realToProxyMap = manager->GetRealObjectToProxyObjectMap(); + proxyToRealMap = manager->GetProxyObjectToRealObjectMap(); + } if (mRoot) { // // This proxy is not the root interface so it must be removed @@ -469,6 +529,11 @@ nsProxyEventObject::~nsProxyEventObject( } } + if (proxyToRealMap) { + nsProxyEventKey peokey(this, nsnull, 0); + proxyToRealMap->Remove(&peokey); + } + // I am worried about ordering. // do not remove assignments. mProxyObject = nsnull; @@ -515,13 +580,18 @@ nsProxyEventObject::Release(void) NS_IMETHODIMP nsProxyEventObject::QueryInterface(REFNSIID aIID, void** aInstancePtr) { - if( aIID.Equals(GetIID()) ) + if (aIID.Equals(GetIID())) { - *aInstancePtr = NS_STATIC_CAST(nsISupports*, this); + *aInstancePtr = this; + NS_ADDREF_THIS(); + return NS_OK; + } + if (aIID.Equals(NS_GET_IID(nsIClassInfo))) + { + *aInstancePtr = NS_STATIC_CAST(nsIClassInfo*, this); NS_ADDREF_THIS(); return NS_OK; } - return mClass->DelegatedQueryInterface(this, aIID, aInstancePtr); } @@ -563,3 +633,68 @@ nsProxyEventObject::CallMethod(PRUint16 return rv; } + +/* void getInterfaces (out PRUint32 count, [array, size_is (count), retval] out nsIIDPtr array); */ +NS_IMETHODIMP nsProxyEventObject::GetInterfaces(PRUint32 *count, nsIID * **array) +{ + if (!mProxyObjectCI) + return NS_ERROR_NOT_IMPLEMENTED; + return mProxyObjectCI->GetInterfaces(count, array); +} + +/* nsISupports getHelperForLanguage (in PRUint32 language); */ +NS_IMETHODIMP nsProxyEventObject::GetHelperForLanguage(PRUint32 language, nsISupports **_retval) +{ + if (!mProxyObjectCI) + return NS_ERROR_NOT_IMPLEMENTED; + return mProxyObjectCI->GetHelperForLanguage(language, _retval); +} + +/* readonly attribute string contractID; */ +NS_IMETHODIMP nsProxyEventObject::GetContractID(char * *aContractID) +{ + if (!mProxyObjectCI) + return NS_ERROR_NOT_IMPLEMENTED; + return mProxyObjectCI->GetContractID(aContractID); +} + +/* readonly attribute string classDescription; */ +NS_IMETHODIMP nsProxyEventObject::GetClassDescription(char * *aClassDescription) +{ + if (!mProxyObjectCI) + return NS_ERROR_NOT_IMPLEMENTED; + return mProxyObjectCI->GetClassDescription(aClassDescription); +} + +/* readonly attribute nsCIDPtr classID; */ +NS_IMETHODIMP nsProxyEventObject::GetClassID(nsCID * *aClassID) +{ + const nsCID iid = mClass->GetProxiedIID(); + *aClassID = (nsCID*)nsMemory::Clone((void*)&iid, sizeof iid); + if (!*aClassID) + return NS_ERROR_OUT_OF_MEMORY; + + return NS_OK; +} + +/* readonly attribute PRUint32 implementationLanguage; */ +NS_IMETHODIMP nsProxyEventObject::GetImplementationLanguage(PRUint32 *aImplementationLanguage) +{ + if (!mProxyObjectCI) + return NS_ERROR_NOT_IMPLEMENTED; + return mProxyObjectCI->GetImplementationLanguage(aImplementationLanguage); +} + +/* readonly attribute PRUint32 flags; */ +NS_IMETHODIMP nsProxyEventObject::GetFlags(PRUint32 *aFlags) +{ + *aFlags = mFlags; + return NS_OK; +} + +/* [notxpcom] readonly attribute nsCID classIDNoAlloc; */ +NS_IMETHODIMP nsProxyEventObject::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) +{ + *aClassIDNoAlloc = mClass->GetProxiedIID(); + return NS_ERROR_NOT_IMPLEMENTED; +} Index: src/nsProxyEventPrivate.h =================================================================== RCS file: /cvsroot/mozilla/xpcom/proxy/src/nsProxyEventPrivate.h,v retrieving revision 1.40 diff -u -p -r1.40 nsProxyEventPrivate.h --- src/nsProxyEventPrivate.h 28 Jan 2006 15:46:11 -0000 1.40 +++ src/nsProxyEventPrivate.h 18 Apr 2006 02:56:47 -0000 @@ -105,11 +105,12 @@ private: NS_DEFINE_STATIC_IID_ACCESSOR(nsProxyEventClass, NS_PROXYEVENT_CLASS_IID) -class nsProxyEventObject : public nsXPTCStubBase +class nsProxyEventObject : public nsXPTCStubBase, public nsIClassInfo { public: NS_DECL_ISUPPORTS + NS_DECL_NSICLASSINFO NS_DECLARE_STATIC_IID_ACCESSOR(NS_PROXYEVENT_OBJECT_IID) @@ -130,13 +131,12 @@ public: nsISupports* GetRealObject() const { return (mProxyObject ? mProxyObject->GetRealObject(): nsnull);} PRInt32 GetProxyType() const { return (mProxyObject ? mProxyObject->GetProxyType() : nsnull);} - nsProxyEventObject(); - nsProxyEventObject(nsIEventQueue *destQueue, - PRInt32 proxyType, - nsISupports* aObj, - nsProxyEventClass* aClass, - nsProxyEventObject* root, - nsIEventQueueService* eventQService); + static nsProxyEventObject* CreateProxyEventObject(nsIEventQueue *destQueue, + PRInt32 proxyType, + nsISupports* aObj, + nsProxyEventClass* aClass, + nsProxyEventObject* root, + nsIEventQueueService* eventQService); nsProxyEventObject* LockedFind(REFNSIID aIID); @@ -149,10 +149,14 @@ private: protected: void LockedRemoveProxy(); + nsProxyEventObject(nsProxyEventClass* aClass, + nsProxyEventObject* root); protected: nsCOMPtr mClass; nsRefPtr mProxyObject; + nsCOMPtr mProxyObjectCI; + PRUint32 mFlags; // Owning reference... nsProxyEventObject *mRoot; @@ -184,7 +188,8 @@ public: static void Shutdown(); - nsHashtable* GetRealObjectToProxyObjectMap() { return &mProxyObjectMap;} + nsHashtable* GetRealObjectToProxyObjectMap() { return &mProxyObjectMap; } + nsHashtable* GetProxyObjectToRealObjectMap() { return &mRealObjectMap; } nsHashtable* GetIIDToProxyClassMap() { return &mProxyClassMap; } PRMonitor* GetMonitor() const { return mProxyCreationMonitor; } @@ -192,9 +197,10 @@ public: private: ~nsProxyObjectManager(); - static nsProxyObjectManager* mInstance; + static nsProxyObjectManager* sInstance; nsHashtable mProxyObjectMap; nsHashtable mProxyClassMap; + nsHashtable mRealObjectMap; PRMonitor *mProxyCreationMonitor; }; Index: src/nsProxyObjectManager.cpp =================================================================== RCS file: /cvsroot/mozilla/xpcom/proxy/src/nsProxyObjectManager.cpp,v retrieving revision 1.59 diff -u -p -r1.59 nsProxyObjectManager.cpp --- src/nsProxyObjectManager.cpp 22 Mar 2005 20:37:18 -0000 1.59 +++ src/nsProxyObjectManager.cpp 18 Apr 2006 02:56:48 -0000 @@ -107,13 +107,14 @@ NS_IMETHODIMP nsProxyCreateInstance::Cre // nsProxyObjectManager ///////////////////////////////////////////////////////////////////////// -nsProxyObjectManager* nsProxyObjectManager::mInstance = nsnull; +nsProxyObjectManager* nsProxyObjectManager::sInstance = nsnull; NS_IMPL_THREADSAFE_ISUPPORTS1(nsProxyObjectManager, nsIProxyObjectManager) nsProxyObjectManager::nsProxyObjectManager() : mProxyObjectMap(256, PR_TRUE), - mProxyClassMap(256, PR_TRUE) + mProxyClassMap(256, PR_TRUE), + mRealObjectMap(256, PR_TRUE) { mProxyCreationMonitor = PR_NewMonitor(); } @@ -133,13 +134,13 @@ nsProxyObjectManager::~nsProxyObjectMana PR_DestroyMonitor(mProxyCreationMonitor); } - nsProxyObjectManager::mInstance = nsnull; + nsProxyObjectManager::sInstance = nsnull; } PRBool nsProxyObjectManager::IsManagerShutdown() { - if (mInstance) + if (sInstance) return PR_FALSE; return PR_TRUE; } @@ -147,18 +148,23 @@ nsProxyObjectManager::IsManagerShutdown( nsProxyObjectManager * nsProxyObjectManager::GetInstance() { - if (! mInstance) + if (! sInstance) { - mInstance = new nsProxyObjectManager(); + sInstance = new nsProxyObjectManager(); + if (sInstance && !sInstance->mProxyCreationMonitor) + { + delete sInstance; + sInstance = nsnull; + } } - return mInstance; + return sInstance; } void nsProxyObjectManager::Shutdown() { - mInstance = nsnull; + sInstance = nsnull; } @@ -216,10 +222,20 @@ nsProxyObjectManager::GetProxyForObject( } // check to see if proxy is there or not. - *aProxyObject = nsProxyEventObject::GetNewOrUsedProxy(postQ, proxyType, aObj, aIID); + nsProxyEventObject *peo = nsProxyEventObject::GetNewOrUsedProxy(postQ, proxyType, aObj, aIID); - if (*aProxyObject == nsnull) + if (!peo) return NS_ERROR_NO_INTERFACE; //fix error code? + if (aIID.Equals(NS_GET_IID(nsIClassInfo))) { + // + // Since the requested proxy is for the nsIClassInfo interface + // and we specially implement nsIClassInfo, we have to cast + // to that interface... + // + *aProxyObject = (nsIClassInfo*)peo; + return NS_OK; + } + *aProxyObject = peo; return NS_OK; }