OSDN Git Service

デッドロックを起こしそうなところがあった
authortest <test@yahoo.co.jp>
Wed, 6 Feb 2019 04:01:51 +0000 (13:01 +0900)
committertest <test@yahoo.co.jp>
Wed, 6 Feb 2019 04:01:51 +0000 (13:01 +0900)
Core/Document.cs
Core/StringBuffer.cs

index 6f7998a..6e3993e 100644 (file)
@@ -1135,15 +1135,11 @@ namespace FooEditEngine
             try
             {
                 this.Clear();
-                this.LayoutLines.IsFrozneDirtyFlag = true;
                 await this.buffer.LoadAsync(fs, tokenSource);
             }
             finally
             {
-                this.Dirty = false; //ファイルの内容とドキュメントの中身は同じなのでダーティフラグは偽にする
                 this.PerformLayout();
-                //これ以降の操作にだけダーティフラグを適用しないとおかしなことになる
-                this.LayoutLines.IsFrozneDirtyFlag = false;
                 if (this.LoadProgress != null)
                     this.LoadProgress(this, new ProgressEventArgs(ProgressState.Complete));
             }
@@ -1155,11 +1151,10 @@ namespace FooEditEngine
         /// <param name="fs">IStreamWriterオブジェクト</param>
         /// <param name="tokenSource">キャンセルトークン</param>
         /// <returns>Taskオブジェクト</returns>
-        /// <remarks>非同期操作中はこのメソッドを実行することはできません。同時にダーティフラグもクリアされます</remarks>
+        /// <remarks>非同期操作中はこのメソッドを実行することはできません</remarks>
         public async Task SaveAsync(TextWriter fs, CancellationTokenSource tokenSource = null)
         {
             await this.buffer.SaveAsync(fs, tokenSource);
-            this.Dirty = false;
         }
 
         /// <summary>
index d1247ab..09993df 100644 (file)
@@ -33,7 +33,7 @@ namespace FooEditEngine
         /// </summary>
         /// <param name="index">インデックス</param>
         /// <returns>Tを返す</returns>
-        T this[int index]{get;}
+        T this[int index] { get; }
     }
 
     sealed class StringBuffer : IEnumerable<char>, IRandomEnumrator<char>
@@ -41,6 +41,7 @@ namespace FooEditEngine
         GapBuffer<char> buf = new GapBuffer<char>();
         const int MaxSemaphoreCount = 1;
         SemaphoreSlim Semaphore = new SemaphoreSlim(MaxSemaphoreCount);
+        ReaderWriterLockSlim rwlock = new ReaderWriterLockSlim();
 
         public StringBuffer()
         {
@@ -58,31 +59,6 @@ namespace FooEditEngine
             }
         }
 
-        /// <summary>
-        /// ロックを解除します
-        /// </summary>
-        public void UnLock()
-        {
-            this.Semaphore.Release();
-        }
-
-        /// <summary>
-        /// ロックします
-        /// </summary>
-        public void Lock()
-        {
-            this.Semaphore.Wait();
-        }
-
-        /// <summary>
-        /// ロックします
-        /// </summary>
-        /// <returns>Taskオブジェクト</returns>
-        public Task LockAsync()
-        {
-            return this.Semaphore.WaitAsync();
-        }
-
         public StringBuffer(StringBuffer buffer)
             : this()
         {
@@ -101,14 +77,14 @@ namespace FooEditEngine
 
         public string ToString(int index, int length)
         {
-            this.Lock();
+            this.rwlock.EnterReadLock();
 
             StringBuilder temp = new StringBuilder();
             temp.Clear();
             for (int i = index; i < index + length; i++)
                 temp.Append(buf[i]);
 
-            this.UnLock();
+            this.rwlock.ExitReadLock();
 
             return temp.ToString();
         }
@@ -128,11 +104,11 @@ namespace FooEditEngine
             }
         }
 
-        public IEnumerable<Tuple<int,int>> ForEachLines(int startIndex, int endIndex, int maxCharCount = -1)
+        public IEnumerable<Tuple<int, int>> ForEachLines(int startIndex, int endIndex, int maxCharCount = -1)
         {
             int currentLineHeadIndex = startIndex;
             int currentLineLength = 0;
-            
+
             for (int i = startIndex; i <= endIndex; i++)
             {
                 currentLineLength++;
@@ -146,7 +122,7 @@ namespace FooEditEngine
                     uc != UnicodeCategory.EnclosingMark &&
                     uc != UnicodeCategory.Surrogate)
                     {
-                        yield return new Tuple<int,int>(currentLineHeadIndex, currentLineLength);
+                        yield return new Tuple<int, int>(currentLineHeadIndex, currentLineLength);
                         currentLineHeadIndex += currentLineLength;
                         currentLineLength = 0;
                     }
@@ -155,7 +131,7 @@ namespace FooEditEngine
             if (currentLineLength > 0)
                 yield return new Tuple<int, int>(currentLineHeadIndex, currentLineLength);
         }
-        
+
         public int Length
         {
             get { return this.buf.Count; }
@@ -170,28 +146,29 @@ namespace FooEditEngine
 
         internal void Replace(GapBuffer<char> buf)
         {
-            this.Lock();
+            this.rwlock.EnterWriteLock();
 
             this.Clear();
             this.buf = buf;
 
-            this.UnLock();
+            this.rwlock.ExitWriteLock();
 
             this.Update(this, new DocumentUpdateEventArgs(UpdateType.Replace, 0, 0, buf.Count));
         }
 
-        internal void Replace(int index, int length, IEnumerable<char> chars,int count)
+        internal void Replace(int index, int length, IEnumerable<char> chars, int count)
         {
-            this.Lock();
+            this.rwlock.EnterWriteLock();
 
-            try{
+            try
+            {
                 if (length > 0)
                     this.buf.RemoveRange(index, length);
                 this.buf.InsertRange(index, chars, count);
             }
             finally
             {
-                this.UnLock();
+                this.rwlock.ExitWriteLock();
             }
 
             this.Update(this, new DocumentUpdateEventArgs(UpdateType.Replace, index, length, count));
@@ -212,11 +189,11 @@ namespace FooEditEngine
                 //内部形式に変換する
                 var internal_str = from s in str where s != '\r' && s != '\0' select s;
 
-                await this.LockAsync().ConfigureAwait(false);
+                this.rwlock.EnterWriteLock();
                 //str.lengthは事前に確保しておくために使用するので影響はない
                 this.buf.InsertRange(index, internal_str, str.Length);
 
-                this.UnLock();
+                this.rwlock.ExitWriteLock();
 
                 if (tokenSource != null)
                     tokenSource.Token.ThrowIfCancellationRequested();
@@ -232,7 +209,7 @@ namespace FooEditEngine
         {
             try
             {
-                await this.LockAsync().ConfigureAwait(false);
+                this.rwlock.EnterReadLock();
                 StringBuilder line = new StringBuilder();
                 for (int i = 0; i < this.Length; i++)
                 {
@@ -247,14 +224,14 @@ namespace FooEditEngine
                         if (tokenSource != null)
                             tokenSource.Token.ThrowIfCancellationRequested();
 #if TEST_ASYNC
-                    System.Threading.Thread.Sleep(10);
+                        System.Threading.Thread.Sleep(10);
 #endif
                     }
                 }
             }
             finally
             {
-                this.UnLock();
+                this.rwlock.ExitReadLock();
             }
         }
 
@@ -271,7 +248,7 @@ namespace FooEditEngine
                         return pattern;
                 });
 
-                this.Lock();
+                this.rwlock.EnterWriteLock();
                 try
                 {
                     //空行は削除する必要はない
@@ -281,25 +258,25 @@ namespace FooEditEngine
                 }
                 finally
                 {
-                    this.UnLock();
+                    this.rwlock.ExitWriteLock();
                 }
 
                 this.Update(this, new DocumentUpdateEventArgs(UpdateType.Replace, lineHeadIndex, lineLength, output.Length, i));
             }
         }
 
-        internal void ReplaceAll(LineToIndexTable layoutlines,string target, string pattern, bool ci = false)
+        internal void ReplaceAll(LineToIndexTable layoutlines, string target, string pattern, bool ci = false)
         {
             TextSearch ts = new TextSearch(target, ci);
             char[] pattern_chars = pattern.ToCharArray();
-            for(int i = 0; i < layoutlines.Count; i++)
+            for (int i = 0; i < layoutlines.Count; i++)
             {
                 int lineHeadIndex = layoutlines.GetIndexFromLineNumber(i), lineLength = layoutlines.GetLengthFromLineNumber(i);
                 int left = lineHeadIndex, right = lineHeadIndex;
                 int newLineLength = lineLength;
                 while ((right = ts.IndexOf(this.buf, left, lineHeadIndex + newLineLength)) != -1)
                 {
-                    this.Lock();
+                    this.rwlock.EnterWriteLock();
                     try
                     {
                         this.buf.RemoveRange(right, target.Length);
@@ -307,7 +284,7 @@ namespace FooEditEngine
                     }
                     finally
                     {
-                        this.UnLock();
+                        this.rwlock.ExitWriteLock();
 
                     }
                     left = right + pattern.Length;
@@ -319,14 +296,14 @@ namespace FooEditEngine
             }
         }
 
-        internal int IndexOf(string target, int start,bool ci = false)
+        internal int IndexOf(string target, int start, bool ci = false)
         {
-            this.Lock();
+            this.rwlock.EnterReadLock();
 
-            TextSearch ts = new TextSearch(target,ci);
-            int patternIndex = ts.IndexOf(this.buf, start,this.buf.Count);
+            TextSearch ts = new TextSearch(target, ci);
+            int patternIndex = ts.IndexOf(this.buf, start, this.buf.Count);
 
-            this.UnLock();
+            this.rwlock.ExitReadLock();
 
             return patternIndex;
         }
@@ -337,7 +314,7 @@ namespace FooEditEngine
         internal void Clear()
         {
             this.buf.Clear();
-            this.Update(this, new DocumentUpdateEventArgs(UpdateType.Clear, 0, this.buf.Count,0));
+            this.Update(this, new DocumentUpdateEventArgs(UpdateType.Clear, 0, this.buf.Count, 0));
         }
 
         internal IEnumerable<char> GetEnumerator(int start, int length)
@@ -373,7 +350,7 @@ namespace FooEditEngine
         int patternLength;
         Dictionary<char, int> qsTable = new Dictionary<char, int>();
         bool caseInsenstive;
-        public TextSearch(string pattern,bool ci = false)
+        public TextSearch(string pattern, bool ci = false)
         {
             this.patternLength = pattern.Length;
             this.caseInsenstive = ci;
@@ -402,7 +379,7 @@ namespace FooEditEngine
                     this.qsTable[pattern[i]] = len - i;
             }
         }
-        public int IndexOf(GapBuffer<char> buf, int start,int end)
+        public int IndexOf(GapBuffer<char> buf, int start, int end)
         {
             //QuickSearch法
             int buflen = buf.Count - 1;