INTEGRATION: CWS uno2 (1.27.2.1.16); FILE MERGED

2003/04/10 13:50:26 sb 1.27.2.1.16.3: #108825# In the RefHolder, keep a hard reference to the local object (the java_environment will only hold it weakly, so that a local object might be garbage-collected otherwise).
2003/04/07 08:33:33 sb 1.27.2.1.16.2: #108678# Replaced sandbox-based proxy with java.lang.reflect based one.
2003/04/04 09:13:59 sb 1.27.2.1.16.1: #108628# Always send back a release for a known object in mapInterfaceFrom (e.g., when the object is a local one mapped out via another bridge and now mapped back in); cleaned up handling of disposed bridge.
This commit is contained in:
Rüdiger Timm 2003-04-23 16:03:59 +00:00
parent dc80c49936
commit b8789bce5c

View file

@ -2,9 +2,9 @@
* *
* $RCSfile: java_remote_bridge.java,v $ * $RCSfile: java_remote_bridge.java,v $
* *
* $Revision: 1.28 $ * $Revision: 1.29 $
* *
* last change: $Author: hr $ $Date: 2003-03-26 12:32:59 $ * last change: $Author: rt $ $Date: 2003-04-23 17:03:59 $
* *
* The Contents of this file are made available subject to the terms of * The Contents of this file are made available subject to the terms of
* either of the following licenses * either of the following licenses
@ -81,9 +81,6 @@ import java.util.Vector;
import com.sun.star.lib.util.IInvokeHook; import com.sun.star.lib.util.IInvokeHook;
import com.sun.star.lib.util.IInvokable; import com.sun.star.lib.util.IInvokable;
import com.sun.star.lib.sandbox.generic.DispatcherAdapterBase;
import com.sun.star.bridge.XBridge; import com.sun.star.bridge.XBridge;
import com.sun.star.bridge.XInstanceProvider; import com.sun.star.bridge.XInstanceProvider;
@ -100,9 +97,6 @@ import com.sun.star.lang.DisposedException;
import com.sun.star.lib.sandbox.Disposable; import com.sun.star.lib.sandbox.Disposable;
import com.sun.star.lib.uno.environments.java.IRequester;
import com.sun.star.lib.uno.environments.java.Proxy;
import com.sun.star.lib.uno.environments.remote.IMessage; import com.sun.star.lib.uno.environments.remote.IMessage;
import com.sun.star.lib.uno.environments.remote.IProtocol; import com.sun.star.lib.uno.environments.remote.IProtocol;
import com.sun.star.lib.uno.environments.remote.IReceiver; import com.sun.star.lib.uno.environments.remote.IReceiver;
@ -133,12 +127,15 @@ import com.sun.star.uno.Any;
* The protocol to used is passed by name, the bridge * The protocol to used is passed by name, the bridge
* then looks for it under <code>com.sun.star.lib.uno.protocols</code>. * then looks for it under <code>com.sun.star.lib.uno.protocols</code>.
* <p> * <p>
* @version $Revision: 1.28 $ $ $Date: 2003-03-26 12:32:59 $ * @version $Revision: 1.29 $ $ $Date: 2003-04-23 17:03:59 $
* @author Kay Ramme * @author Kay Ramme
* @see com.sun.star.lib.uno.environments.remote.IProtocol * @see com.sun.star.lib.uno.environments.remote.IProtocol
* @since UDK1.0 * @since UDK1.0
*/ */
public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBridge, Disposable, XComponent, IStableObject { public class java_remote_bridge
implements IBridge, IReceiver, RequestHandler, XBridge, Disposable,
XComponent, IStableObject
{
/** /**
* When set to true, enables various debugging output. * When set to true, enables various debugging output.
*/ */
@ -205,7 +202,7 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
String oid_o[] = new String[]{oid}; String oid_o[] = new String[]{oid};
_java_environment.registerInterface(null, oid_o, interfaceType ); _java_environment.registerInterface(null, oid_o, interfaceType );
addRefHolder(interfaceType, oid); addRefHolder(null, interfaceType, oid);
} }
else { else {
Object object = null; Object object = null;
@ -284,8 +281,9 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
} }
// dispose this bridge only within an error // dispose this bridge only within an error
if(!_quit && !java_remote_bridge.this._disposed) if (!_quit) {
java_remote_bridge.this.dispose(throwable); java_remote_bridge.this.dispose(throwable);
}
return null; return null;
} }
@ -303,8 +301,6 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
protected IEnvironment _java_environment; protected IEnvironment _java_environment;
protected MessageDispatcher _messageDispatcher; protected MessageDispatcher _messageDispatcher;
protected int _life_count = 0; // determines if this bridge is alife, which is controlled by acquire and release calls protected int _life_count = 0; // determines if this bridge is alife, which is controlled by acquire and release calls
protected boolean _disposed = false;
protected boolean _disposing = false;
protected Hashtable _refHolders; // holds descriptions for out mapped objects, so we can release protected Hashtable _refHolders; // holds descriptions for out mapped objects, so we can release
// the outmapped objects when the bridge is to be disposed // the outmapped objects when the bridge is to be disposed
@ -317,6 +313,12 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
protected IThreadPool _iThreadPool; protected IThreadPool _iThreadPool;
// Variable state must only be used while synchronized on this object:
private int state = STATE_ALIVE;
private static final int STATE_ALIVE = 0;
private static final int STATE_DISPOSING = 1;
private static final int STATE_DISPOSED = 2;
/** /**
* This method is for testing only. * This method is for testing only.
*/ */
@ -337,10 +339,13 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
Type _type; Type _type;
String _oid; String _oid;
int _mapCount; int _mapCount;
Object _hardRef;
// keep a hard reference to the object, the java_environment will
// only hold it weakly
} }
final void addRefHolder(Type type, String oid) { final void addRefHolder(Object obj, Type type, String oid) {
acquire(); acquire();
synchronized(_refHolders) { synchronized(_refHolders) {
@ -350,9 +355,11 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
refHolder = new RefHolder(); refHolder = new RefHolder();
refHolder._type = type; refHolder._type = type;
refHolder._oid = oid; refHolder._oid = oid;
refHolder._hardRef = obj;
_refHolders.put(oid + type, refHolder); _refHolders.put(oid + type, refHolder);
} }
// assert refHolder._hardRef == obj;
++ refHolder._mapCount; ++ refHolder._mapCount;
} }
@ -506,6 +513,8 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
_listeners = new Vector(); _listeners = new Vector();
_stableListeners = new Vector(); _stableListeners = new Vector();
proxyFactory = new ProxyFactory(this);
// create the message dispatcher and start it // create the message dispatcher and start it
_messageDispatcher = new MessageDispatcher(); _messageDispatcher = new MessageDispatcher();
_messageDispatcher.start(); _messageDispatcher.start();
@ -564,8 +573,7 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
* @see com.sun.star.uno.IBridge#mapInterfaceTo * @see com.sun.star.uno.IBridge#mapInterfaceTo
*/ */
public Object mapInterfaceTo(Object object, Type type) { public Object mapInterfaceTo(Object object, Type type) {
if(_disposed) throw new DisposedException( checkDisposed();
"java_remote_bridge(" + this + ").mapInterfaceTo - is disposed");
String oid[] = new String[1]; String oid[] = new String[1];
@ -574,7 +582,7 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
oid[0] = (String)object; oid[0] = (String)object;
else { else {
_java_environment.registerInterface(object, oid, type); _java_environment.registerInterface(object, oid, type);
addRefHolder(type, oid[0]); addRefHolder(object, type, oid[0]);
} }
if(DEBUG) System.err.println("##### " + getClass() + " - mapInterfaceTo:" + object + " interface:" + type + " " + oid[0]); if(DEBUG) System.err.println("##### " + getClass() + " - mapInterfaceTo:" + object + " interface:" + type + " " + oid[0]);
@ -590,56 +598,32 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
* @see com.sun.star.uno.IBridge#mapInterfaceFrom * @see com.sun.star.uno.IBridge#mapInterfaceFrom
*/ */
public Object mapInterfaceFrom(Object oId, Type type) { public Object mapInterfaceFrom(Object oId, Type type) {
if(_disposed) throw new DisposedException( checkDisposed();
"java_remote_bridge(" + this + ").mapInterfaceFrom - is disposed"); // TODO What happens if an exception is thrown after the call to
// acquire, but before it is guaranteed that a pairing release will be
// called eventually?
acquire(); acquire();
String oid = (String) oId;
// see if we already have object with zInterface of given oid Object object = _java_environment.getRegisteredInterface(oid, type);
Object object = _java_environment.getRegisteredInterface((String)oId, type); if (object == null) {
object = _java_environment.registerInterface(
if(object != null) { proxyFactory.create(oid, type), new String[] { oid }, type);
if(object instanceof DispatcherAdapterBase) { // the proxy sends a release when finalized
DispatcherAdapterBase dispatcherAdapterBase = (DispatcherAdapterBase)object; } else {
if(dispatcherAdapterBase.getObject() instanceof DispatcherAdapterBase) {
dispatcherAdapterBase = (DispatcherAdapterBase)dispatcherAdapterBase.getObject();
if((dispatcherAdapterBase.getObject() instanceof String)) { // is it my proxy?
try { try {
sendRequest(oId, sendRequest(oid, type, "release", null,
type,
"release",
null,
new Boolean[] { new Boolean(_forceSynchronous) }, new Boolean[] { new Boolean(_forceSynchronous) },
new Boolean[] { new Boolean(_forceSynchronous) }); new Boolean[] { new Boolean(_forceSynchronous) });
} } catch (Error e) {
catch(RuntimeException runtimeException) { throw e;
throw runtimeException; } catch (RuntimeException e) {
} throw e;
catch(Throwable throwable) { } catch (Throwable e) {
throw new com.sun.star.uno.RuntimeException(getClass().getName() + ".mapInterfaceFrom - unexpected:" + throwable); throw new com.sun.star.uno.RuntimeException(
getClass().getName() + ".mapInterfaceFrom - unexpected: "
+ e);
} }
} }
}
}
}
else {
String oid[] = new String[]{(String)oId};
// boolean virtual = false;
// if(oid[0].startsWith("virtual:")) {
// oid[0] = oid[0].substring(8);
// virtual = true;
// }
Object proxy = Proxy.create(this, oid[0], type, false, _forceSynchronous); // this proxy sends a release, when finalized
object = _java_environment.registerInterface(proxy, oid, type);
}
if(DEBUG) System.err.println("##### " + getClass() + " - mapInterfaceFrom:" + oId + " interface:" + type + " " + object);
return object; return object;
} }
@ -696,10 +680,8 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
private synchronized void dispose(Throwable throwable) { private synchronized void dispose(Throwable throwable) {
if(DEBUG) System.err.println("##### " + getClass().getName() + ".dispose - life count:" + _life_count); if(DEBUG) System.err.println("##### " + getClass().getName() + ".dispose - life count:" + _life_count);
if(_disposed) throw new DisposedException("java_remote_bridge(" + this + ").dispose - is disposed"); if (state == STATE_ALIVE) {
state = STATE_DISPOSING;
if(!_disposing) {
_disposing = true;
notifyListeners(); notifyListeners();
notifyStableListeners(); notifyStableListeners();
@ -764,7 +746,9 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
_java_environment = null; _java_environment = null;
_messageDispatcher = null; _messageDispatcher = null;
_disposed = true; // TODO! Is it intended that state is left as STATE_DISPOSING
// when an exception is thrown?
state = STATE_DISPOSED;
} }
catch(InterruptedException interruptedException) { catch(InterruptedException interruptedException) {
System.err.println(getClass().getName() + ".dispose - InterruptedException:" + interruptedException); System.err.println(getClass().getName() + ".dispose - InterruptedException:" + interruptedException);
@ -838,11 +822,8 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
+ exception + " " + result); + exception + " " + result);
} }
// FIXME _disposed read outside of synchronized block // FIXME checkDisposed called outside of synchronized block
if (_disposed) { checkDisposed();
throw new DisposedException("java_remote_bridge(" + this
+ ").sendReply - is disposed");
}
try { try {
synchronized (_outputStream) { synchronized (_outputStream) {
@ -860,7 +841,17 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
} }
} }
public Object sendRequest(Object object, Type type, String operation, Object params[], Boolean synchron[], Boolean mustReply[]) throws Throwable { public Object sendRequest(String oid, Type type, String operation,
Object[] args)
throws Throwable
{
return sendRequest(
oid, type, operation, args,
_forceSynchronous ? new Boolean[] { Boolean.TRUE } : null,
_forceSynchronous ? new Boolean[] { Boolean.TRUE } : null);
}
private Object sendRequest(Object object, Type type, String operation, Object params[], Boolean synchron[], Boolean mustReply[]) throws Throwable {
if(DEBUG) System.err.println("##### " + getClass().getName() + ".sendRequest:" + object + " " + type +" " + operation + " " + synchron + " " + mustReply); if(DEBUG) System.err.println("##### " + getClass().getName() + ".sendRequest:" + object + " " + type +" " + operation + " " + synchron + " " + mustReply);
Object result = null; Object result = null;
@ -870,8 +861,7 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
if(mustReply == null) if(mustReply == null)
mustReply = new Boolean[1]; mustReply = new Boolean[1];
if(_disposed) throw new DisposedException( checkDisposed();
"java_remote_bridge(" + this + ").sendRequest - is disposed");
if(operation.equals("acquire")) acquire(); // keep this bridge alife if(operation.equals("acquire")) acquire(); // keep this bridge alife
@ -948,4 +938,14 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
public void removeStableListener(IStableListener stableListener) { public void removeStableListener(IStableListener stableListener) {
_stableListeners.removeElement(stableListener); _stableListeners.removeElement(stableListener);
} }
// This function must only be called while synchronized on this object:
private void checkDisposed() {
if (state == STATE_DISPOSED) {
throw new DisposedException("java_remote_bridge " + this
+ " is disposed");
}
}
private final ProxyFactory proxyFactory;
} }