Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[FIXED JENKINS-8703] fixed a race condition in the pipe connection.
  • Loading branch information
kohsuke committed Jul 1, 2011
1 parent a34186b commit 67ce74f
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 3 deletions.
3 changes: 3 additions & 0 deletions changelog.html
Expand Up @@ -55,6 +55,9 @@
<!-- Record your changes in the trunk here. -->
<div id="trunk" style="display:none"><!--=TRUNK-BEGIN=-->
<ul class=image>
<li class=bug>
Fixed a race condition in the remoting that can break the pipe support
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-8703">issue 8703</a>)
<li class=bug>
Restart button does not restart jenkins after plugin upload
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-10044">issue 10044</a>)
Expand Down
6 changes: 4 additions & 2 deletions remoting/src/main/java/hudson/remoting/Pipe.java
Expand Up @@ -142,8 +142,9 @@ private void writeObject(ObjectOutputStream oos) throws IOException {
oos.writeBoolean(true); // marker
oos.writeInt(oid);
} else {
// remote will read from local
int oid = Channel.current().export(out);
// remote will read from local this object gets unexported when the pipe is connected.
// see ConnectCommand
int oid = Channel.current().export(out,false);

oos.writeBoolean(false);
oos.writeInt(oid);
Expand Down Expand Up @@ -197,6 +198,7 @@ public void run() {
try {
final ProxyOutputStream ros = (ProxyOutputStream) channel.getExportedObject(oidRos);
channel.unexport(oidRos);
// the above unexport cancels out the export in writeObject above
ros.connect(channel, oidPos);
} catch (IOException e) {
logger.log(Level.SEVERE,"Failed to connect to pipe",e);
Expand Down
58 changes: 58 additions & 0 deletions remoting/src/test/java/Driver8703.java
@@ -0,0 +1,58 @@
import hudson.remoting.PipeTest;
import org.jvnet.hudson.test.Bug;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
* Test bed to reproduce JENKINS-8703.
*
* @author Kohsuke Kawaguchi
*/
public class Driver8703 {
@Bug(8703)
public static void main(String[] args) throws Throwable {
// int i=0;
// while (true) {
// System.out.println(i++);
// foo();
// }

ExecutorService es = Executors.newCachedThreadPool();
List<Future> flist = new ArrayList<Future>();
for (int i=0; i<10000; i++) {
flist.add(es.submit(new Callable<Object>() {
public Object call() throws Exception {
Thread.currentThread().setName("testing");
try {
foo();
return null;
} catch (Exception e) {
throw e;
} catch (Throwable t) {
throw new Exception(t);
} finally {
Thread.currentThread().setName("done");
}
}
}));
}

for (Future ff : flist) {
ff.get();
}

System.out.println("All done");
es.shutdown();
}

private static void foo() throws Throwable {
PipeTest t = new PipeTest();
t.setName("testSaturation");
t.runBare();
}
}
2 changes: 1 addition & 1 deletion remoting/src/test/java/hudson/remoting/PipeTest.java
Expand Up @@ -154,6 +154,7 @@ public void testSaturation() throws Exception {
final Pipe p = Pipe.createLocalToRemote();

Thread writer = new Thread() {
final Thread mainThread = Thread.currentThread(); // this makes it easy to see the relationship between the thread pair in the debugger
@Override
public void run() {
OutputStream os = p.getOut();
Expand Down Expand Up @@ -199,7 +200,6 @@ public ISaturationTest call() throws IOException {
private InputStream in;
public void ensureConnected() throws IOException {
in = pipe.getIn();
in.available();
}

public int readFirst() throws IOException {
Expand Down

0 comments on commit 67ce74f

Please sign in to comment.