File D:\maven-qcr-plugin-testsunitaires\qcr4java\jenkins-master\target\site\qc\core\src\main\java\hudson\model\queue\WorkUnitContext.java.html

1 /*
2 * The MIT License
3 *
4 * Copyright (c) 2010, InfraDNA, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24 package hudson.model.queue;
25
26 import hudson.model.Action;
27 import hudson.model.Executor;
28 import hudson.model.Queue;
29 import hudson.model.Queue.BuildableItem;
30 import hudson.model.Queue.Task;
31
32 import java.util.ArrayList;
33 import java.util.Collections;
34 import java.util.List;
35
36 /**
37 * Holds the information shared between {@link WorkUnit}s created from the same {@link Task}.
38 *
39 * @author Kohsuke Kawaguchi
40 */
41 public final class WorkUnitContext {
42
43 public final BuildableItem item;
44
45 public final Task task;
46
47 /**
48 * Once the execution starts and completes, update this future object with the outcome.
49 */
50 public final FutureImpl future;
51
52 /**
53 * Associated parameters to the build.
54 */
55 public final List<Action> actions;
56
57 private final Latch startLatch, endLatch;
58
59 private List<WorkUnit> workUnits = new ArrayList<WorkUnit>();
60
61 /**
62 * If the execution is aborted, set to non-null that indicates where it was aborted.
63 */
64 private volatile Throwable aborted;
65
66 public WorkUnitContext(BuildableItem item) {
67 this.item = item;
68 this.task = item.task;
69 this.future = (FutureImpl)item.getFuture();
70 this.actions = item.getActions();
71
72 // +1 for the main task
73 int workUnitSize = Tasks.getSubTasksOf(task).size();
74 startLatch = new Latch(workUnitSize) {
75 @Override
76 protected void onCriteriaMet() {
77 // on behalf of the member Executors,
78 // the one that executes the main thing will send notifications
79 Executor e = Executor.currentExecutor();
80 if (e.getCurrentWorkUnit().isMainWork()) {
81 e.getOwner().taskAccepted(e,task);
82 }
83 }
84 };
85
86 endLatch = new Latch(workUnitSize);
87 }
88
89 /**
90 * Called by the executor that executes a member {@link SubTask} that belongs to this task
91 * to create its {@link WorkUnit}.
92 */
93 public WorkUnit createWorkUnit(SubTask execUnit) {
94 future.addExecutor(Executor.currentExecutor());
95 WorkUnit wu = new WorkUnit(this, execUnit);
96 workUnits.add(wu);
97 return wu;
98 }
99
100 public List<WorkUnit> getWorkUnits() {
101 return Collections.unmodifiableList(workUnits);
102 }
103
104 public WorkUnit getPrimaryWorkUnit() {
105 return workUnits.get(0);
106 }
107
108 /**
109 * All the {@link Executor}s that jointly execute a {@link Task} call this method to synchronize on the start.
110 */
111 public void synchronizeStart() throws InterruptedException {
112 startLatch.synchronize();
113 // the main thread will send a notification
114 Executor e = Executor.currentExecutor();
115 WorkUnit wu = e.getCurrentWorkUnit();
116 if (wu.isMainWork()) {
117 future.start.set(e.getCurrentExecutable());
118 }
119 }
120
121 /**
122 * All the {@link Executor}s that jointly execute a {@link Task} call this method to synchronize on the end of the task.
123 *
124 * @throws InterruptedException
125 * If any of the member thread is interrupted while waiting for other threads to join, all
126 * the member threads will report {@link InterruptedException}.
127 */
128 public void synchronizeEnd(Queue.Executable executable, Throwable problems, long duration) throws InterruptedException {
129 endLatch.synchronize();
130
131 // the main thread will send a notification
132 Executor e = Executor.currentExecutor();
133 WorkUnit wu = e.getCurrentWorkUnit();
134 if (wu.isMainWork()) {
135 if (problems == null) {
136 future.set(executable);
137 e.getOwner().taskCompleted(e, task, duration);
138 } else {
139 future.set(problems);
140 e.getOwner().taskCompletedWithProblems(e, task, duration, problems);
141 }
142 }
143 }
144
145 /**
146 * When one of the work unit is aborted, call this method to abort all the other work units.
147 */
148 public synchronized void abort(Throwable cause) {
149 if (cause==null) throw new IllegalArgumentException();
150 if (aborted!=null) return; // already aborted
151 aborted = cause;
152 startLatch.abort(cause);
153 endLatch.abort(cause);
154
155 Thread c = Thread.currentThread();
156 for (WorkUnit wu : workUnits) {
157 Executor e = wu.getExecutor();
158 if (e!=null && e!=c)
159 e.interrupt();
160 }
161 }
162 }
163