Skip to content
Permalink
Browse files
[FIXED JENKINS-8703] fixed a race condition in the pipe connection.
(cherry picked from commit 67ce74f)

Conflicts:

	changelog.html
  • Loading branch information
kohsuke authored and vjuranek committed Aug 17, 2011
1 parent ce54cd0 commit 9b28cf9a780bcc429c02645995c41c3ceec34c90
Showing with 66 additions and 3 deletions.
  1. +3 −0 changelog.html
  2. +4 −2 remoting/src/main/java/hudson/remoting/Pipe.java
  3. +58 −0 remoting/src/test/java/Driver8703.java
  4. +1 −1 remoting/src/test/java/hudson/remoting/PipeTest.java
@@ -58,6 +58,9 @@
<li class=bug>
Tests not recognized as failed if test initialization failed
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-6700">issue 6700</a>)
<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>)
</ul>
</div><!--=TRUNK-END=-->

@@ -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);
@@ -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);
@@ -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();
}
}
@@ -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();
@@ -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 {

0 comments on commit 9b28cf9

Please sign in to comment.