You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by hu...@apache.org on 2023/02/13 22:23:45 UTC

[plc4x] branch develop updated: fix(code-gen): Handle the case where while dispatching types the consumer modify the consumer list.

This is an automated email from the ASF dual-hosted git repository.

hutcheb pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git


The following commit(s) were added to refs/heads/develop by this push:
     new e369b2ea12 fix(code-gen): Handle the case where while dispatching types the consumer modify the consumer list.
e369b2ea12 is described below

commit e369b2ea12e3b0a863cc3b0b28ede33d45dae18d
Author: Ben Hutcheson <be...@gmail.com>
AuthorDate: Mon Feb 13 23:20:15 2023 +0100

    fix(code-gen): Handle the case where while dispatching types the consumer modify the consumer list.
---
 .../mspec/parser/MessageFormatListener.java        | 34 +++++++++++++++-------
 1 file changed, 23 insertions(+), 11 deletions(-)

diff --git a/code-generation/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/parser/MessageFormatListener.java b/code-generation/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/parser/MessageFormatListener.java
index 293a6ef3fb..d332024b1f 100644
--- a/code-generation/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/parser/MessageFormatListener.java
+++ b/code-generation/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/parser/MessageFormatListener.java
@@ -49,7 +49,6 @@ import java.nio.charset.Charset;
 import java.util.*;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CompletionStage;
-import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.function.Consumer;
 import java.util.stream.Collectors;
 
@@ -881,19 +880,32 @@ public class MessageFormatListener extends MSpecBaseListener implements LazyType
 
         types.put(typeName, type);
 
-        // TODO:- Figure out why we need a write on copy array to get around a Concurrent Modification Exception being raised.
-        List<Consumer<TypeDefinition>> waitingConsumers = typeDefinitionConsumers.getOrDefault(typeName, new CopyOnWriteArrayList<>());
+        while (typeDefinitionConsumers.getOrDefault(typeName, new LinkedList<>()).size() != 0) {
+
+            consumerDispatchType(typeName, type);
+        }
+
+        typeDefinitionConsumers.remove(typeName);
+    }
+
+    private void consumerDispatchType(String typeName, TypeDefinition type) {
+        List<Consumer<TypeDefinition>> waitingConsumers = typeDefinitionConsumers.getOrDefault(typeName, new LinkedList<>());
         LOGGER.debug("{} waiting for {}", waitingConsumers.size(), typeName);
 
-        LinkedList<Consumer<TypeDefinition>> removeList = new LinkedList<>();
-        for (Consumer<TypeDefinition> setter : waitingConsumers) {
+        Iterator<Consumer<TypeDefinition>> consumerIterator = waitingConsumers.iterator();
+        List<Consumer<TypeDefinition>> removedItems = new ArrayList<>();
+
+        while (consumerIterator.hasNext()) {
+            Consumer<TypeDefinition> setter = consumerIterator.next();
             LOGGER.debug("setting {} for {}", typeName, setter);
-            setter.accept(type);
-            removeList.add(setter);
+            removedItems.add(setter);
         }
 
-        waitingConsumers.removeAll(removeList);
-        typeDefinitionConsumers.remove(typeName);
+        waitingConsumers.removeAll(removedItems);
+
+        for (Consumer<TypeDefinition> setter : removedItems) {
+            setter.accept(type);
+        }
     }
 
     @Override
@@ -907,9 +919,9 @@ public class MessageFormatListener extends MSpecBaseListener implements LazyType
         } else {
             // put up order
             if (LOGGER.isDebugEnabled()) {
-                LOGGER.debug("{} already waiting for {}", typeDefinitionConsumers.getOrDefault(typeRefName, new CopyOnWriteArrayList<>()).size(), typeRefName);
+                LOGGER.debug("{} already waiting for {}", typeDefinitionConsumers.getOrDefault(typeRefName, new LinkedList<>()).size(), typeRefName);
             }
-            typeDefinitionConsumers.putIfAbsent(typeRefName, new CopyOnWriteArrayList<>());
+            typeDefinitionConsumers.putIfAbsent(typeRefName, new LinkedList<>());
             typeDefinitionConsumers.get(typeRefName).add(setTypeDefinition);
         }
     }