提交 d249d524 编写于 作者: K kohsuke

bug fix.


git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@1298 71c3de6d-444a-0410-be80-ed276b4c234a
上级 2b1d1753
......@@ -91,6 +91,8 @@ public class Channel {
* same method on the given <tt>instance</tt> object.
*/
/*package*/ synchronized <T> T export(Class<T> type, T instance) {
if(instance==null)
return null;
// TODO: unexport
final int id = exportedObjects.intern(instance);
......@@ -154,6 +156,10 @@ public class Channel {
/**
* Notifies the remote peer that we are closing down.
*
* Execution of this command also triggers the {@link ReaderThread} to shut down
* and quit. The {@link CloseCommand} is always the last command to be sent on
* {@link ObjectOutputStream}, and it's the last command to be read.
*/
private static final class CloseCommand extends Command {
protected void execute(Channel channel) {
......@@ -175,15 +181,19 @@ public class Channel {
public void close() throws IOException {
if(closed) return;
send(new CloseCommand());
// TODO: would be nice if we can wait for the completion of pending requests
terminate(null);
// make sure no other commands get executed in between.
synchronized(this) {
send(new CloseCommand());
oos.close();
// TODO: would be nice if we can wait for the completion of pending requests
terminate(null);
}
}
private final class ReaderThread extends Thread {
public ReaderThread(String name) {
super("DataChannel reader thread: "+name);
super("Channel reader thread: "+name);
}
public void run() {
......@@ -204,9 +214,8 @@ public class Channel {
}
}
ois.close();
oos.close();
} catch (IOException e) {
logger.log(Level.SEVERE, "I/O error in DataChannel",e);
logger.log(Level.SEVERE, "I/O error in channel",e);
terminate(e);
}
}
......
package hudson.remoting;
/**
* @author Kohsuke Kawaguchi
*/
package hudson.remoting;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;
/**
* Manages unique ID for classloaders.
* Manages unique ID for exported objects.
*
* @author Kohsuke Kawaguchi
*/
final class ExportTable<T> {
private final Map<Integer, WeakReference<T>> table = new HashMap<Integer, WeakReference<T>>();
private final WeakHashMap<T,Integer> reverse = new WeakHashMap<T,Integer>();
private final Map<Integer,T> table = new HashMap<Integer,T>();
private final Map<T,Integer> reverse = new HashMap<T,Integer>();
// id==0 is reserved for bootstrap classloader
private int iota = 1;
public synchronized int intern(T t) {
if(t==null) return 0; // bootstrap classloader
public synchronized int intern(T cl) {
if(cl==null) return 0; // bootstrap classloader
Integer id = reverse.get(cl);
Integer id = reverse.get(t);
if(id==null) {
id = iota++;
table.put(id,new WeakReference<T>(cl));
reverse.put(cl,id);
table.put(id,t);
reverse.put(t,id);
}
return id;
}
public synchronized T get(int id) {
WeakReference<T> ref = table.get(id);
if(ref==null) return null;
return ref.get();
return table.get(id);
}
public synchronized void unexport(T t) {
if(t==null) return;
Integer id = reverse.remove(t);
if(id==null) return; // presumably already unexported
table.remove(id);
}
}
package hudson.remoting;
import java.util.concurrent.Future;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
......
package hudson.remoting;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.io.ObjectInputStream;
import java.io.BufferedOutputStream;
import java.io.PipedOutputStream;
import java.io.Serializable;
/**
* @author Kohsuke Kawaguchi
......
package hudson.remoting;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.io.Serializable;
import java.io.ObjectInputStream;
import java.io.IOException;
import java.lang.reflect.Method;
/**
* Sits behind a proxy object and implements the proxy logic.
......@@ -104,6 +104,8 @@ final class RemoteInvocationHandler implements InvocationHandler, Serializable {
protected Serializable perform(Channel channel) throws Throwable {
Object o = channel.exportedObjects.get(oid);
if(o==null)
throw new IllegalStateException("Unable to call "+methodName+". Invalid object ID "+oid);
try {
return (Serializable)choose(o).invoke(o,arguments);
} catch (InvocationTargetException e) {
......
......@@ -2,12 +2,12 @@ package hudson.remoting;
import java.io.IOException;
import java.io.Serializable;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.concurrent.Future;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Request/response pattern over {@link Command}.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册