Skip to content

Commit

Permalink
[FIXED JENKINS-12625] Apply fix for java-level deadlock
Browse files Browse the repository at this point in the history
Applied the same changes that were made to core in jenkinsci/jenkins@0c6138c to the Ivy project classes.
  • Loading branch information
tbingaman committed Feb 2, 2012
1 parent 8d43b0c commit 4a6e793
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 31 deletions.
35 changes: 18 additions & 17 deletions src/main/java/hudson/ivy/AbstractIvyProject.java
Expand Up @@ -48,27 +48,28 @@ protected AbstractIvyProject(ItemGroup parent, String name) {
}

@Override
protected void updateTransientActions() {
synchronized(transientActions) {
super.updateTransientActions();
protected List<Action> createTransientActions() {
List<Action> r = super.createTransientActions();

// if we just pick up the project actions from the last build,
// and if the last build failed very early, then the reports that
// kick in later (like test results) won't be displayed.
// so pick up last successful build, too.
Set<Class> added = new HashSet<Class>();
addTransientActionsFromBuild(getLastBuild(),added);
addTransientActionsFromBuild(getLastSuccessfulBuild(),added);
// if we just pick up the project actions from the last build,
// and if the last build failed very early, then the reports that
// kick in later (like test results) won't be displayed.
// so pick up last successful build, too.
Set<Class> added = new HashSet<Class>();
addTransientActionsFromBuild(getLastBuild(), r, added);
addTransientActionsFromBuild(getLastSuccessfulBuild(), r, added);

for (Trigger trigger : triggers) {
Collection<Action> a = trigger.getProjectActions();
if(a!=null)
transientActions.addAll(a);
}
}
for (Trigger<?> trigger : triggers)
r.addAll(trigger.getProjectActions());

return r;
}

protected abstract void addTransientActionsFromBuild(R lastBuild, Set<Class> added);
/**
* @param collection
* Add the transient actions to this collection.
*/
protected abstract void addTransientActionsFromBuild(R lastBuild, List<Action> collection, Set<Class> added);

public abstract boolean isUseUpstreamParameters();

Expand Down
11 changes: 7 additions & 4 deletions src/main/java/hudson/ivy/IvyModule.java
Expand Up @@ -389,6 +389,11 @@ public boolean isFingerprintConfigured() {
return true;
}

@Override // to make this accessible to IvyModuleSet
protected void updateTransientActions() {
super.updateTransientActions();
}

@Override
protected void buildDependencyGraph(DependencyGraph graph) {
// Allow a module's publishers to add to the dependency graph.
Expand Down Expand Up @@ -494,7 +499,7 @@ public String getShortDescription() {
}

@Override
protected void addTransientActionsFromBuild(IvyBuild build, Set<Class> added) {
protected void addTransientActionsFromBuild(IvyBuild build, List<Action> collection, Set<Class> added) {
if (build == null)
return;
List<IvyReporter> list = build.projectActionReporters;
Expand All @@ -505,9 +510,7 @@ protected void addTransientActionsFromBuild(IvyBuild build, Set<Class> added) {
if (!added.add(step.getClass()))
continue; // already added
try {
Action a = step.getProjectAction(this);
if (a != null)
transientActions.add(a);
collection.addAll(step.getProjectActions(this));
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Failed to getProjectAction from " + step + ". Report issue to plugin developers.", e);
}
Expand Down
23 changes: 13 additions & 10 deletions src/main/java/hudson/ivy/IvyModuleSet.java
Expand Up @@ -246,35 +246,38 @@ public IvyModule getModule(String name) {
return getItem(name);
}

@Override
@Override // to make this accessible from IvyModuleSetBuild
protected void updateTransientActions() {
super.updateTransientActions();
}

@Override
protected List<Action> createTransientActions() {
List<Action> r = super.createTransientActions();
for (IvyModule module: modules.values()) {
module.updateTransientActions();
}
if(publishers!=null) // this method can be loaded from within the onLoad method, where this might be null
for (BuildStep step : publishers) {
Collection<? extends Action> a = step.getProjectActions(this);
if(a!=null)
transientActions.addAll(a);
r.addAll(step.getProjectActions(this));
}

if (buildWrappers!=null)
for (BuildWrapper step : buildWrappers) {
Collection<? extends Action> a = step.getProjectActions(this);
if(a!=null)
transientActions.addAll(a);
r.addAll(step.getProjectActions(this));
}

return r;
}

@Override
protected void addTransientActionsFromBuild(IvyModuleSetBuild build, Set<Class> added) {
protected void addTransientActionsFromBuild(IvyModuleSetBuild build, List<Action> collection, Set<Class> added) {
if(build==null) return;

for (Action a : build.getActions())
if(a instanceof IvyAggregatedReport)
if(added.add(a.getClass()))
transientActions.add(((IvyAggregatedReport)a).getProjectAction(this));
collection.add(((IvyAggregatedReport)a).getProjectAction(this));

List<IvyReporter> list = build.projectActionReporters;
if(list==null) return;
Expand All @@ -283,7 +286,7 @@ protected void addTransientActionsFromBuild(IvyModuleSetBuild build, Set<Class>
if(!added.add(step.getClass())) continue; // already added
Action a = step.getAggregatedProjectAction(this);
if(a!=null)
transientActions.add(a);
collection.add(a);
}
}

Expand Down
31 changes: 31 additions & 0 deletions src/main/java/hudson/ivy/IvyReporter.java
Expand Up @@ -36,6 +36,8 @@

import java.io.IOException;
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;

import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
import org.apache.tools.ant.BuildEvent;
Expand Down Expand Up @@ -191,11 +193,40 @@ public boolean end(IvyBuild build, Launcher launcher, BuildListener listener) th
*
* @return
* null not to contribute an action, which is the default.
* @deprecated as of 1.21
* Use {@link #getProjectActions(IvyModule)} instead.
*/
public Action getProjectAction(IvyModule module) {
return null;
}

/**
* Equivalent of {@link BuildStep#getProjectActions(AbstractProject)}
* for {@link IvyReporter}.
*
* <p>
* Registers a transient action to {@link IvyModule} when it's rendered.
* This is useful if you'd like to display an action at the module level.
*
* <p>
* Since this contributes a transient action, the returned {@link Action}
* will not be serialized.
*
* <p>
* For this method to be invoked, your {@link IvyReporter} has to invoke
* {@link IvyBuildProxy#registerAsProjectAction(IvyReporter)} during the build.
*
* @return
* can be empty but never null.
* @since 1.21
*/
public Collection<? extends Action> getProjectActions(IvyModule module) {
// delegate to getProjectAction (singular) for backward compatible behavior
Action a = getProjectAction(module);
if (a==null) return Collections.emptyList();
return Collections.singletonList(a);
}

/**
* Works like {@link #getProjectAction(IvyModule)} but
* works at {@link IvyModuleSet} level.
Expand Down

0 comments on commit 4a6e793

Please sign in to comment.