From 3edae667b3955a561296a23122f86b35ec928a98 Mon Sep 17 00:00:00 2001 From: Eugene Baranov Date: Sun, 30 Nov 2014 22:52:14 +0200 Subject: [PATCH] [JENKINS-25514] Fixed lock case in FutureImpl when some other process is waiting for build in queue. --- .../java/hudson/model/queue/FutureImpl.java | 8 +++++ .../src/test/java/hudson/model/QueueTest.java | 30 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/core/src/main/java/hudson/model/queue/FutureImpl.java b/core/src/main/java/hudson/model/queue/FutureImpl.java index da63f9c11d..2104dd4fcf 100644 --- a/core/src/main/java/hudson/model/queue/FutureImpl.java +++ b/core/src/main/java/hudson/model/queue/FutureImpl.java @@ -84,6 +84,14 @@ public final class FutureImpl extends AsyncFutureImpl implements Que } } + @Override + public synchronized void setAsCancelled() { + super.setAsCancelled(); + if (!start.isDone()) { + start.setAsCancelled(); + } + } + synchronized void addExecutor(@Nonnull Executor executor) { this.executors.add(executor); } diff --git a/test/src/test/java/hudson/model/QueueTest.java b/test/src/test/java/hudson/model/QueueTest.java index 93bcb5ba05..5c83d8b8f1 100644 --- a/test/src/test/java/hudson/model/QueueTest.java +++ b/test/src/test/java/hudson/model/QueueTest.java @@ -62,6 +62,7 @@ import java.util.List; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; +import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; @@ -579,4 +580,33 @@ public class QueueTest extends HudsonTestCase { } catch (CancellationException e) { } } + + public void testWaitForStartAndCancelBeforeStart() throws Exception { + final OneShotEvent ev = new OneShotEvent(); + FreeStyleProject p = createFreeStyleProject(); + + QueueTaskFuture f = p.scheduleBuild2(10); + final Queue.Item item = Queue.getInstance().getItem(p); + assertNotNull(item); + + final ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1); + executor.schedule(new Runnable() { + @Override + public void run() { + try { + Queue.getInstance().doCancelItem(item.id); + } catch (IOException e) { + e.printStackTrace(); + } catch (ServletException e) { + e.printStackTrace(); + } + } + }, 2, TimeUnit.SECONDS); + + try { + f.waitForStart(); + fail("Expected an CancellationException to be thrown"); + } catch (CancellationException e) {} + } + }