From 566b14285831e46d4bb4fc6bf8d046156ae611d6 Mon Sep 17 00:00:00 2001 From: "idk%eng.sun.com" Date: Tue, 26 Jun 2001 10:54:44 +0000 Subject: [PATCH] *not part of the build* fix for 86789 --- java/xpcom/connect/public/bcICall.h | 22 +++++++ java/xpcom/connect/public/bcIORB.h | 1 + java/xpcom/connect/public/bcIStub.h | 3 +- java/xpcom/connect/src/ORB.cpp | 17 +++-- java/xpcom/connect/src/ORB.h | 1 + .../org/mozilla/xpcom/ProxyFactory.java | 66 +++++++++---------- .../org/mozilla/xpcom/ProxyHandler.java | 10 ++- .../classes/org/mozilla/xpcom/Utilities.java | 9 ++- java/xpcom/java/src/bcJavaStub.cpp | 29 +++++++- java/xpcom/java/src/bcJavaStub.h | 5 ++ .../java/src/org_mozilla_xpcom_Utilities.cpp | 9 ++- java/xpcom/xpcom/bcXPCOMMarshalToolkit.cpp | 2 +- java/xpcom/xpcom/bcXPCOMProxy.cpp | 4 +- java/xpcom/xpcom/bcXPCOMStub.cpp | 59 +++++++++++++---- java/xpcom/xpcom/bcXPCOMStub.h | 8 ++- java/xpcom/xpcom/bcXPCOMStubsAndProxies.cpp | 1 + 16 files changed, 185 insertions(+), 61 deletions(-) diff --git a/java/xpcom/connect/public/bcICall.h b/java/xpcom/connect/public/bcICall.h index ffef74d0bd1a..5989e2a4e6c3 100644 --- a/java/xpcom/connect/public/bcICall.h +++ b/java/xpcom/connect/public/bcICall.h @@ -34,6 +34,28 @@ class bcICall { virtual bcIUnMarshaler * GetUnMarshaler() = 0; virtual bcIORB * GetORB() = 0; }; + +#define INVOKE_ADDREF(oid,iid,orb) \ + do { \ + bcICall * call; \ + call = GET_ADDREF_CALL((oid),(iid),(orb)); \ + (orb)->SendReceive(call); \ + delete call; \ + } while(0) + +#define INVOKE_RELEASE(oid,iid,orb) \ + do { \ + bcICall * call; \ + call = GET_RELEASE_CALL((oid),(iid),(orb)); \ + (orb)->SendReceive(call); \ + delete call; \ + } while(0) + +#define GET_ADDREF_CALL(oid,iid,orb) \ + (orb)->CreateCall((iid),(oid),1) + +#define GET_RELEASE_CALL(oid,iid,orb) \ + (orb)->CreateCall((iid),(oid),2) #endif diff --git a/java/xpcom/connect/public/bcIORB.h b/java/xpcom/connect/public/bcIORB.h index 29fc2b3132f2..a426a06d071c 100644 --- a/java/xpcom/connect/public/bcIORB.h +++ b/java/xpcom/connect/public/bcIORB.h @@ -31,6 +31,7 @@ class bcIORB { public: virtual bcOID RegisterStub(bcIStub *stub) = 0; virtual void RegisterStubWithOID(bcIStub *stub, bcOID *oid) = 0; + virtual void UnregisterStub(bcOID oid) = 0; virtual bcICall * CreateCall(bcIID *, bcOID *, bcMID) = 0; virtual int SendReceive(bcICall *) = 0; //virtual IThread * GetThread(TID) = 0; diff --git a/java/xpcom/connect/public/bcIStub.h b/java/xpcom/connect/public/bcIStub.h index 8550df7a4d38..f6865c516cae 100644 --- a/java/xpcom/connect/public/bcIStub.h +++ b/java/xpcom/connect/public/bcIStub.h @@ -26,6 +26,7 @@ class bcIStub { public: virtual void Dispatch(bcICall *call) = 0; - //nb shortcut + virtual void SetORB(bcIORB *orb) = 0; + virtual void SetOID(bcOID oid) = 0; }; #endif diff --git a/java/xpcom/connect/src/ORB.cpp b/java/xpcom/connect/src/ORB.cpp index f3b7c662cbd8..01d9a3d9e969 100644 --- a/java/xpcom/connect/src/ORB.cpp +++ b/java/xpcom/connect/src/ORB.cpp @@ -57,12 +57,21 @@ ORB::~ORB() { bcOID ORB::RegisterStub(bcIStub *stub) { bcOID oid = GenerateOID(); - stubs->Put(new bcOIDKey(oid),stub); + RegisterStubWithOID(stub,&oid); return oid; } -void ORB:: RegisterStubWithOID(bcIStub *stub, bcOID *oid) { +void ORB::RegisterStubWithOID(bcIStub *stub, bcOID *oid) { stubs->Put(new bcOIDKey(*oid),stub); + stub->SetORB(this); + stub->SetOID(*oid); + return; +} + +void ORB::UnregisterStub(bcOID oid) { + bcOIDKey *oidKey = new bcOIDKey(oid); + stubs->Remove(oidKey); + delete oidKey; return; } @@ -91,12 +100,11 @@ bcIStub * ORB::GetStub(bcOID *oid) { return (bcIStub*)tmp; } - - struct bcOIDstruct { PRUint16 high; PRUint16 low; }; + bcOID ORB::GenerateOID() { bcOID oid; bcOIDstruct oidStruct; @@ -104,7 +112,6 @@ bcOID ORB::GenerateOID() { oidStruct.high = ((PRUint32)this); oid = *(bcOID*)&oidStruct; return oid; - } diff --git a/java/xpcom/connect/src/ORB.h b/java/xpcom/connect/src/ORB.h index b9b6f4d6e93b..9158badfdc02 100644 --- a/java/xpcom/connect/src/ORB.h +++ b/java/xpcom/connect/src/ORB.h @@ -31,6 +31,7 @@ public: virtual ~ORB(); virtual bcOID RegisterStub(bcIStub *stub); virtual void RegisterStubWithOID(bcIStub *stub, bcOID *oid); + virtual void UnregisterStub(bcOID oid); virtual bcICall * CreateCall(bcIID *, bcOID *, bcMID); virtual int SendReceive(bcICall *); private: diff --git a/java/xpcom/java/classes/org/mozilla/xpcom/ProxyFactory.java b/java/xpcom/java/classes/org/mozilla/xpcom/ProxyFactory.java index 6b96acde8819..5b7f603d2977 100644 --- a/java/xpcom/java/classes/org/mozilla/xpcom/ProxyFactory.java +++ b/java/xpcom/java/classes/org/mozilla/xpcom/ProxyFactory.java @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +/* -*- Mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of @@ -27,20 +27,20 @@ import java.lang.ref.*; class ProxyKey { ProxyKey(long _oid, IID _iid) { - oid = new Long(_oid); - iid = _iid; + oid = new Long(_oid); + iid = _iid; } public boolean equals(Object obj) { - if (! (obj instanceof ProxyKey)) { - return false; - } - return (oid.equals(((ProxyKey)obj).oid) && iid.equals(((ProxyKey)obj).iid)); + if (! (obj instanceof ProxyKey)) { + return false; + } + return (oid.equals(((ProxyKey)obj).oid) && iid.equals(((ProxyKey)obj).iid)); } public int hashCode() { - return oid.hashCode(); + return oid.hashCode(); } public String toString() { - return "org.mozilla.xpcom.ProxyFactory.ProxyKey "+oid+" "+iid; + return "org.mozilla.xpcom.ProxyFactory.ProxyKey "+oid+" "+iid; } Long oid; IID iid; @@ -51,34 +51,34 @@ public class ProxyFactory { Debug.log("--[java] ProxyFactory.getInterface "+iid); return InterfaceRegistry.getInterface(iid); } - + public static Object getProxy(long oid, IID iid, long orb) { try { - Debug.log("--[java] ProxyFactory.getProxy "+iid); - ProxyKey key = new ProxyKey(oid, iid); - Object obj = null; - Object result = null; - if (proxies != null) { - obj = proxies.get(key); - if (obj != null - && (obj instanceof Reference)) { - result = ((Reference)obj).get(); + Debug.log("--[java] ProxyFactory.getProxy "+iid); + ProxyKey key = new ProxyKey(oid, iid); + Object obj = null; + Object result = null; + if (proxies != null) { + obj = proxies.get(key); + if (obj != null + && (obj instanceof Reference)) { + result = ((Reference)obj).get(); + } + } else { + proxies = new Hashtable(); } - } else { - proxies = new Hashtable(); - } - if (result == null) { - Class inter = getInterface(iid); - if (inter == null) { - Debug.log("--[java] ProxyFactory.getProxy we did not find interface for iid="+iid+"returing null"); - return null; + if (result == null) { + Class inter = getInterface(iid); + if (inter == null) { + Debug.log("--[java] ProxyFactory.getProxy we did not find interface for iid="+iid+"returing null"); + return null; + } + InvocationHandler handler = new ProxyHandler(oid, iid, orb); + result = Proxy.newProxyInstance(inter.getClassLoader(), new Class[] {inter},handler); + proxies.put(new WeakReference(result), key); } - InvocationHandler handler = new ProxyHandler(oid, iid, orb); - result = Proxy.newProxyInstance(inter.getClassLoader(), new Class[] {inter},handler); - proxies.put(new WeakReference(result), key); - } - Debug.log("--[java] ProxyFactory.getProxy we got proxy "+result); - return result; + Debug.log("--[java] ProxyFactory.getProxy we got proxy "+result); + return result; } catch (Exception e) { Debug.log("--[java] ProxyFactory.getProxy we got exception "+e); } diff --git a/java/xpcom/java/classes/org/mozilla/xpcom/ProxyHandler.java b/java/xpcom/java/classes/org/mozilla/xpcom/ProxyHandler.java index 20ce17c58ec3..ac4afbbf05ad 100644 --- a/java/xpcom/java/classes/org/mozilla/xpcom/ProxyHandler.java +++ b/java/xpcom/java/classes/org/mozilla/xpcom/ProxyHandler.java @@ -25,9 +25,10 @@ import java.lang.reflect.*; class ProxyHandler implements InvocationHandler { ProxyHandler(long _oid, IID _iid, long _orb) { - oid = _oid; - iid = _iid; - orb = _orb; + oid = _oid; + iid = _iid; + orb = _orb; + Utilities.callMethod(oid, null, iid, orb, null); //it is hack method = null means addref } public Object invoke(Object proxy, Method method, @@ -39,6 +40,7 @@ class ProxyHandler implements InvocationHandler { } else if (str.equals("clone")) { throw new java.lang.CloneNotSupportedException(); } else if (str.equals("finalize")) { + Utilities.callMethod(oid, method, iid, orb, args); finalize(); } else if (str.equals("equals")) { if (args[0] instanceof ProxyHandler) { @@ -64,3 +66,5 @@ class ProxyHandler implements InvocationHandler { private long orb; } + + diff --git a/java/xpcom/java/classes/org/mozilla/xpcom/Utilities.java b/java/xpcom/java/classes/org/mozilla/xpcom/Utilities.java index 8dceb7fc95b4..9b463201fdb6 100644 --- a/java/xpcom/java/classes/org/mozilla/xpcom/Utilities.java +++ b/java/xpcom/java/classes/org/mozilla/xpcom/Utilities.java @@ -74,7 +74,14 @@ public class Utilities { static Object callMethod(long oid, Method method, IID iid, long orb , Object[] args) { Debug.log("--[java]Utilities.callMethod "+method); - int mid = InterfaceRegistry.getIndexByMethod(method, iid); + int mid; + if (method == null) { + mid = 1; //it is hack method = null means addref + } else if ("finalize".equals(method.getName())) { + mid = 2; + } else { + mid = InterfaceRegistry.getIndexByMethod(method, iid); + } if (mid < 0) { Debug.log("--[java]Utilities.callMethod we do not have implementation for "+method); return null; diff --git a/java/xpcom/java/src/bcJavaStub.cpp b/java/xpcom/java/src/bcJavaStub.cpp index 10f2547ae04a..4e598ae1ede8 100644 --- a/java/xpcom/java/src/bcJavaStub.cpp +++ b/java/xpcom/java/src/bcJavaStub.cpp @@ -34,7 +34,7 @@ jclass bcJavaStub::objectClass = NULL; jclass bcJavaStub::utilitiesClass = NULL; jmethodID bcJavaStub::callMethodByIndexMID = NULL; -bcJavaStub::bcJavaStub(jobject obj) { +bcJavaStub::bcJavaStub(jobject obj) : orb(NULL) { PRLogModuleInfo *log = bcJavaGlobal::GetLog(); PR_LOG(log,PR_LOG_DEBUG,("--bcJavaStub::bcJavaStub \n")); if (!obj) { @@ -43,11 +43,24 @@ bcJavaStub::bcJavaStub(jobject obj) { } JNIEnv * env = bcJavaGlobal::GetJNIEnv(); object = env->NewGlobalRef(obj); + refCounter = 0; } bcJavaStub::~bcJavaStub() { bcJavaGlobal::GetJNIEnv()->DeleteGlobalRef(object); + if (orb != NULL) { + orb->UnregisterStub(oid); + } +} + + +void bcJavaStub::SetORB(bcIORB *_orb) { + orb = _orb; +} + +void bcJavaStub::SetOID(bcOID _oid) { + oid = _oid; } void bcJavaStub::Dispatch(bcICall *call) { @@ -57,6 +70,20 @@ void bcJavaStub::Dispatch(bcICall *call) { bcIID iid; bcOID oid; bcMID mid; jobjectArray args; call->GetParams(&iid, &oid, &mid); + + if (mid == 1) { //AddRef + refCounter++; + return; + } else if (mid == 2) { //Release + refCounter--; + printf("-java mid==2\n"); + if (refCounter <= 0) { + printf("-java delete\n"); + delete this; + return; + } + } + nsIInterfaceInfo *interfaceInfo; nsIInterfaceInfoManager* iimgr; if((iimgr = XPTI_GetInterfaceInfoManager()) != NULL) { diff --git a/java/xpcom/java/src/bcJavaStub.h b/java/xpcom/java/src/bcJavaStub.h index 6840d28a44c7..a5ccb11b298b 100644 --- a/java/xpcom/java/src/bcJavaStub.h +++ b/java/xpcom/java/src/bcJavaStub.h @@ -31,8 +31,13 @@ class bcJavaStub : public bcIStub { bcJavaStub(jobject obj); virtual ~bcJavaStub(); virtual void Dispatch(bcICall *call) ; + virtual void SetORB(bcIORB *orb); + virtual void SetOID(bcOID oid); private: + bcIORB *orb; + bcOID oid; jobject object; + PRUint32 refCounter; static jclass objectClass; static jclass utilitiesClass; static jmethodID callMethodByIndexMID; diff --git a/java/xpcom/java/src/org_mozilla_xpcom_Utilities.cpp b/java/xpcom/java/src/org_mozilla_xpcom_Utilities.cpp index d010306a8e25..941f5cf648da 100644 --- a/java/xpcom/java/src/org_mozilla_xpcom_Utilities.cpp +++ b/java/xpcom/java/src/org_mozilla_xpcom_Utilities.cpp @@ -52,8 +52,15 @@ JNIEXPORT jobject JNICALL Java_org_mozilla_xpcom_Utilities_callMethodByIndex str = env->GetStringUTFChars(jiid,NULL); iid.Parse(str); env->ReleaseStringUTFChars(jiid,str); + if (mid == 2) { + INVOKE_RELEASE(&oid,&iid,orb); + return NULL; + } else if (mid == 1) { + INVOKE_ADDREF(&oid,&iid,orb); + return NULL; + } bcICall *call = orb->CreateCall(&iid, &oid, mid); - + /*****/ nsIInterfaceInfo *interfaceInfo; nsIInterfaceInfoManager* iimgr; diff --git a/java/xpcom/xpcom/bcXPCOMMarshalToolkit.cpp b/java/xpcom/xpcom/bcXPCOMMarshalToolkit.cpp index b64854c5d33f..2711840f0bf5 100644 --- a/java/xpcom/xpcom/bcXPCOMMarshalToolkit.cpp +++ b/java/xpcom/xpcom/bcXPCOMMarshalToolkit.cpp @@ -31,7 +31,7 @@ static NS_DEFINE_CID(kXPCOMStubsAndProxies,BC_XPCOMSTUBSANDPROXIES_CID); static nsID nullID = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}}; bcXPCOMMarshalToolkit::bcXPCOMMarshalToolkit(PRUint16 _methodIndex, nsIInterfaceInfo *_interfaceInfo, - nsXPTCMiniVariant* _params, bcIORB *_orb) { + nsXPTCMiniVariant* _params, bcIORB *_orb) { callSide = onClient; orb = _orb; methodIndex = _methodIndex; diff --git a/java/xpcom/xpcom/bcXPCOMProxy.cpp b/java/xpcom/xpcom/bcXPCOMProxy.cpp index ff8391cd4b02..373619a11225 100644 --- a/java/xpcom/xpcom/bcXPCOMProxy.cpp +++ b/java/xpcom/xpcom/bcXPCOMProxy.cpp @@ -49,10 +49,12 @@ bcXPCOMProxy::bcXPCOMProxy(bcOID _oid, const nsIID &_iid, bcIORB *_orb) { orb = _orb; interfaceInfo = NULL; PR_LOG(log, PR_LOG_DEBUG, ("--[c++] bcXPCOMProxy::bcXPCOMProxy this: %p iid: %s\n",this, iid.ToString())); + INVOKE_ADDREF(&oid,&iid,orb); } bcXPCOMProxy::~bcXPCOMProxy() { NS_IF_RELEASE(interfaceInfo); + INVOKE_RELEASE(&oid,&iid,orb); } @@ -174,7 +176,7 @@ nsrefcnt bcXPCOMProxy::Release(void) { nsrefcnt cnt = (nsrefcnt) PR_AtomicDecrement((PRInt32*)&mRefCnt); PR_LOG(log, PR_LOG_DEBUG, ("--[c++] bcXPCOMProxy::Release %d\n",(unsigned)cnt)); if(0 == cnt) { - delete this; + delete this; } return cnt; } diff --git a/java/xpcom/xpcom/bcXPCOMStub.cpp b/java/xpcom/xpcom/bcXPCOMStub.cpp index 4a2e5e5cf7e5..599f1162b0b0 100644 --- a/java/xpcom/xpcom/bcXPCOMStub.cpp +++ b/java/xpcom/xpcom/bcXPCOMStub.cpp @@ -52,10 +52,11 @@ struct CallInfo { PRBool completed; }; -bcXPCOMStub::bcXPCOMStub(nsISupports *o) : object(o) { +bcXPCOMStub::bcXPCOMStub(nsISupports *o) : object(o), orb(NULL) { PRLogModuleInfo *log = bcXPCOMLog::GetLog(); PR_LOG(log, PR_LOG_DEBUG, ("--bcXPCOMStub::bcXPCOMStub\n")); NS_ADDREF(object); + refCounter = 0; nsresult rv; _mOwningThread = PR_CurrentThread(); eventQService = do_GetService(kEventQueueServiceCID); @@ -75,6 +76,9 @@ bcXPCOMStub::bcXPCOMStub(nsISupports *o) : object(o) { bcXPCOMStub::~bcXPCOMStub() { NS_RELEASE(object); + if (orb != NULL) { + orb->UnregisterStub(oid); + } } void bcXPCOMStub::DispatchAndSaveThread(bcICall *call, nsIEventQueue *eventQueue) { @@ -109,25 +113,47 @@ void bcXPCOMStub::DispatchAndSaveThread(bcICall *call, nsIEventQueue *eventQueue nsCOMPtr stubsAndProxiesService; stubsAndProxiesService = do_GetService(kStubsAndProxies); stubsAndProxiesService->PushEventQueue(eventQueue); - //nb return value; excepion handling - PR_LOG(log, PR_LOG_DEBUG, ("--bcXPCOMStub::DispatchAndSaveThreade about to XPTC_InvokeByIndex\n")); - nsresult result = XPTC_InvokeByIndex(object, mid, paramCount, params); - PR_LOG(log, PR_LOG_DEBUG, ("--bcXPCOMStub::DispatchAndSaveThreade after XPTC_InvokeByIndex\n")); - bcIMarshaler * m = call->GetMarshaler(); - m->WriteSimple(&result, bc_T_U32); - if (NS_SUCCEEDED(result) - && mt != NULL) { - PR_LOG(log, PR_LOG_DEBUG, ("--bcXPCOMStub::DispatchAndSaveThreade about to mt->Marshal\n")); - mt->Marshal(m); - delete m; + if (mid == 2) { //Release + if (refCounter <= 0) { + NS_DELETEXPCOM(this); + } + } else { + PR_LOG(log, PR_LOG_DEBUG, ("--bcXPCOMStub::DispatchAndSaveThreade about to XPTC_InvokeByIndex\n")); + nsresult result = XPTC_InvokeByIndex(object, mid, paramCount, params); + PR_LOG(log, PR_LOG_DEBUG, ("--bcXPCOMStub::DispatchAndSaveThreade after XPTC_InvokeByIndex\n")); + bcIMarshaler * m = call->GetMarshaler(); + m->WriteSimple(&result, bc_T_U32); + if (NS_SUCCEEDED(result) + && mt != NULL) { + PR_LOG(log, PR_LOG_DEBUG, ("--bcXPCOMStub::DispatchAndSaveThreade about to mt->Marshal\n")); + mt->Marshal(m); + delete m; + } + delete mt; } - delete mt; //pop caller eventQueue stubsAndProxiesService->PopEventQueue(NULL); return; } + void bcXPCOMStub::Dispatch(bcICall *call) { PRLogModuleInfo *log = bcXPCOMLog::GetLog(); + /* AddRef Release handling is here. + */ + bcIID iid; bcOID oid; bcMID mid; + call->GetParams(&iid, &oid, &mid); + if (mid == 1) { //AddRef + refCounter++; + return; + } else if (mid == 2) { //Release + refCounter--; + if (refCounter > 0) { + // if refCounter <= 0 wrapped object has to be released. + // That release should happen in the appropriate thread + return; + } + } + if (_mOwningThread == PR_CurrentThread() || NULL == (void*)owningEventQ) { DispatchAndSaveThread(call); @@ -176,6 +202,13 @@ void bcXPCOMStub::Dispatch(bcICall *call) { } +void bcXPCOMStub::SetORB(bcIORB *_orb) { + orb = _orb; +} + +void bcXPCOMStub::SetOID(bcOID _oid) { + oid = _oid; +} static void* EventHandler(PLEvent *self) { PRLogModuleInfo *log = bcXPCOMLog::GetLog(); diff --git a/java/xpcom/xpcom/bcXPCOMStub.h b/java/xpcom/xpcom/bcXPCOMStub.h index c73cd30963b9..548290fbd498 100644 --- a/java/xpcom/xpcom/bcXPCOMStub.h +++ b/java/xpcom/xpcom/bcXPCOMStub.h @@ -32,13 +32,19 @@ public: bcXPCOMStub(nsISupports *obj); virtual ~bcXPCOMStub(); virtual void Dispatch(bcICall *call) ; + virtual void SetORB(bcIORB *orb); + virtual void SetOID(bcOID oid); void DispatchAndSaveThread(bcICall *call, nsIEventQueue *q = NULL); private: nsISupports *object; + bcIORB *orb; + bcOID oid; void* _mOwningThread; nsCOMPtr owningEventQ; nsCOMPtr eventQService; - + PRUint32 refCounter; }; #endif + + diff --git a/java/xpcom/xpcom/bcXPCOMStubsAndProxies.cpp b/java/xpcom/xpcom/bcXPCOMStubsAndProxies.cpp index 5228eec70c9e..42c5fc7a8474 100644 --- a/java/xpcom/xpcom/bcXPCOMStubsAndProxies.cpp +++ b/java/xpcom/xpcom/bcXPCOMStubsAndProxies.cpp @@ -150,6 +150,7 @@ NS_IMETHODIMP bcXPCOMStubsAndProxies::GetEventQueue(nsIEventQueue **eventQueue) } return NS_OK; } + NS_IMETHODIMP bcXPCOMStubsAndProxies::PopEventQueue(nsIEventQueue **_eventQueue) { PRLogModuleInfo *log = bcXPCOMLog::GetLog(); PR_LOG(log, PR_LOG_DEBUG, ("--bcXPCOMStubsAndProxies::PopEventQueue\n"));