changeset 160:5802131432e4 v2

fixed regression: race condition in Promise DFA refactoring
author cin
date Thu, 18 Feb 2016 19:38:54 +0300
parents 5558e43c79bb
children 2a8466f0cb8a
files Implab/AbstractEvent.cs Implab/Parsing/CDFADefinition.cs Implab/Parsing/DFADefinition.cs Implab/Parsing/EDFADefinition.cs
diffstat 4 files changed, 15 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/Implab/AbstractEvent.cs	Thu Feb 18 16:06:14 2016 +0300
+++ b/Implab/AbstractEvent.cs	Thu Feb 18 19:38:54 2016 +0300
@@ -160,8 +160,12 @@
 
                 if (slot < RESERVED_HANDLERS_COUNT) {
 
-                    if (slot == 0)
-                        Interlocked.CompareExchange(ref m_handlers, new THandler[RESERVED_HANDLERS_COUNT], null);
+                    if (slot == 0) {
+                        m_handlers = new THandler[RESERVED_HANDLERS_COUNT];
+                    } else {
+                        while (m_handlers == null)
+                            Thread.MemoryBarrier();
+                    }
 
                     m_handlers[slot] = handler;
 
--- a/Implab/Parsing/CDFADefinition.cs	Thu Feb 18 16:06:14 2016 +0300
+++ b/Implab/Parsing/CDFADefinition.cs	Thu Feb 18 19:38:54 2016 +0300
@@ -11,10 +11,8 @@
         }
 
         public CDFADefinition Optimize() {
-            var optimized = new CDFADefinition(new CharAlphabet());
-
-            Optimize(optimized, m_alphabet, optimized.Alphabet);
-            return optimized;
+            
+            return (CDFADefinition)Optimize(alphabet => new CDFADefinition((CharAlphabet)alphabet), m_alphabet, new CharAlphabet());
         }
 
         public void PrintDFA() {
--- a/Implab/Parsing/DFADefinition.cs	Thu Feb 18 16:06:14 2016 +0300
+++ b/Implab/Parsing/DFADefinition.cs	Thu Feb 18 19:38:54 2016 +0300
@@ -66,8 +66,8 @@
             m_states[s1].transitions[symbol] = s2;
         }
 
-        public void Optimize<TA>(IDFADefinition minimalDFA,IAlphabet<TA> sourceAlphabet, IAlphabet<TA> minimalAlphabet) {
-            Safe.ArgumentNotNull(minimalDFA, "minimalDFA");
+        protected IDFADefinition Optimize<TA>(Func<IAlphabet<TA>, IDFADefinition> dfaFactory,IAlphabet<TA> sourceAlphabet, IAlphabet<TA> minimalAlphabet) {
+            Safe.ArgumentNotNull(dfaFactory, "dfaFactory");
             Safe.ArgumentNotNull(minimalAlphabet, "minimalAlphabet");
 
             var setComparer = new CustomEqualityComparer<HashSet<int>>(
@@ -211,6 +211,8 @@
             
             // построение автомата
 
+            var minimalDFA = dfaFactory(minimalAlphabet);
+
             var states = new int[ optimalMap.Length ];
             states[0] = UNREACHEBLE_STATE;
             
@@ -237,6 +239,7 @@
                 }
             }
 
+            return minimalDFA;
         }
 
         public void PrintDFA<TA>(IAlphabet<TA> alphabet) {
--- a/Implab/Parsing/EDFADefinition.cs	Thu Feb 18 16:06:14 2016 +0300
+++ b/Implab/Parsing/EDFADefinition.cs	Thu Feb 18 19:38:54 2016 +0300
@@ -18,10 +18,8 @@
         }
 
         public EDFADefinition<T> Optimize() {
-            var optimized = new EDFADefinition<T>(new EnumAlphabet<T>());
-            Optimize(optimized, m_alphabet, optimized.Alphabet);
-
-            return optimized;
+            
+            return (EDFADefinition<T>)Optimize(alphabet => new EDFADefinition<T>((EnumAlphabet<T>)alphabet), m_alphabet, new EnumAlphabet<T>());
         }
 
         public void PrintDFA() {