gnodet commented on a change in pull request #627:
URL: https://github.com/apache/maven/pull/627#discussion_r761458908



##########
File path: 
maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoExecutor.java
##########
@@ -202,6 +210,80 @@ private void execute( MavenSession session, MojoExecution 
mojoExecution, Project
             }
         }
 
+        try ( ProjectLock lock = new ProjectLock( session, mojoDescriptor, 
aggregatorLock ) )
+        {
+            doExecute( session, mojoExecution, projectIndex, dependencyContext 
);
+        }
+    }
+
+    /**
+     * Aggregating mojo executions (possibly) modify all MavenProjects, 
including those that are currently in use
+     * by concurrently running mojo executions. To prevent race conditions, an 
aggregating execution will block
+     * all other executions until finished.
+     * We also lock on a given project to forbid a forked lifecycle to be 
executed concurrently with the project.
+     * TODO: ideally, the builder should take care of the ordering in a 
smarter way
+     * TODO: and concurrency issues fixed with MNG-7157
+     */
+    private static class ProjectLock implements AutoCloseable
+    {
+        final Lock acquiredAggregatorLock;
+        final Lock acquiredProjectLock;
+
+        ProjectLock( MavenSession session, MojoDescriptor mojoDescriptor, 
ReadWriteLock aggregatorLock )
+        {
+            if ( session.getRequest().getDegreeOfConcurrency() > 1 )
+            {
+                boolean aggregator = mojoDescriptor.isAggregator();
+                acquiredAggregatorLock = aggregator ? 
aggregatorLock.writeLock() : aggregatorLock.readLock();
+                acquiredProjectLock = getProjectLock( session );
+                acquiredAggregatorLock.lock();
+                acquiredProjectLock.lock();
+            }
+            else
+            {
+                acquiredAggregatorLock = null;
+                acquiredProjectLock = null;
+            }
+        }
+
+        @Override
+        public void close()
+        {
+            // release the lock in the reverse order of the acquisition
+            if ( acquiredProjectLock != null )
+            {
+                acquiredProjectLock.unlock();
+            }
+            if ( acquiredAggregatorLock != null )
+            {
+                acquiredAggregatorLock.unlock();
+            }
+        }
+
+        @SuppressWarnings( { "unchecked", "rawtypes" } )
+        private Lock getProjectLock( MavenSession session )
+        {
+            final Lock acquiredProjectLock;
+            SessionData data = session.getRepositorySession().getData();
+            Map<MavenProject, Lock> locks = ( Map ) data.get( 
ProjectLock.class );

Review comment:
       `SessionData` has that from 
https://github.com/apache/maven-resolver/commit/e5c8763dfe390a537911094810d0bcf4c58180eb
 but that's not yet released afaik.
   I can add a TODO.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to