OSDN Git Service

Revert "セマフォーだとデッドロックを起こすことがあるのでリーダーライターロッカーに変更した"
authortest <test@yahoo.co.jp>
Tue, 5 Feb 2019 12:03:51 +0000 (21:03 +0900)
committertest <test@yahoo.co.jp>
Tue, 5 Feb 2019 12:03:51 +0000 (21:03 +0900)
This reverts commit 182f1aef06140e95191f3ad12a30e9cad446c028.

Core/Document.cs
Core/StringBuffer.cs

index ed6fdf3..0a42405 100644 (file)
@@ -1160,11 +1160,30 @@ namespace FooEditEngine
         {
             try
             {
-                await this.buffer.SaveAsync(fs, tokenSource);
+                await this.buffer.LockAsync().ConfigureAwait(false);
+                StringBuilder line = new StringBuilder();
+                for (int i = 0; i < this.Length; i++)
+                {
+                    char c = this[i];
+                    line.Append(c);
+                    if (c == Document.NewLine || i == this.Length - 1)
+                    {
+                        string str = line.ToString();
+                        str = str.Replace(Document.NewLine.ToString(), fs.NewLine);
+                        await fs.WriteAsync(str).ConfigureAwait(false);
+                        line.Clear();
+                        if (tokenSource != null)
+                            tokenSource.Token.ThrowIfCancellationRequested();
+#if TEST_ASYNC
+                    System.Threading.Thread.Sleep(10);
+#endif
+                    }
+                }
+                this.Dirty = false;
             }
             finally
             {
-                this.Dirty = false;
+                this.buffer.UnLock();
             }
         }
 
index 57aaacd..0fdc448 100644 (file)
@@ -41,7 +41,6 @@ namespace FooEditEngine
         GapBuffer<char> buf = new GapBuffer<char>();
         const int MaxSemaphoreCount = 1;
         SemaphoreSlim Semaphore = new SemaphoreSlim(MaxSemaphoreCount);
-        ReaderWriterLockSlim rwlock = new ReaderWriterLockSlim();
 
         public StringBuffer()
         {
@@ -59,6 +58,31 @@ 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()
         {
@@ -77,14 +101,14 @@ namespace FooEditEngine
 
         public string ToString(int index, int length)
         {
-            this.rwlock.EnterReadLock();
+            this.Lock();
 
             StringBuilder temp = new StringBuilder();
             temp.Clear();
             for (int i = index; i < index + length; i++)
                 temp.Append(buf[i]);
 
-            this.rwlock.ExitReadLock();
+            this.UnLock();
 
             return temp.ToString();
         }
@@ -146,19 +170,19 @@ namespace FooEditEngine
 
         internal void Replace(GapBuffer<char> buf)
         {
-            this.rwlock.EnterWriteLock();
+            this.Lock();
 
             this.Clear();
             this.buf = buf;
 
-            this.rwlock.ExitWriteLock();
+            this.UnLock();
 
             this.Update(this, new DocumentUpdateEventArgs(UpdateType.Replace, 0, 0, buf.Count));
         }
 
         internal void Replace(int index, int length, IEnumerable<char> chars,int count)
         {
-            this.rwlock.EnterWriteLock();
+            this.Lock();
 
             try{
                 if (length > 0)
@@ -167,7 +191,7 @@ namespace FooEditEngine
             }
             finally
             {
-                this.rwlock.ExitWriteLock();
+                this.UnLock();
             }
 
             this.Update(this, new DocumentUpdateEventArgs(UpdateType.Replace, index, length, count));
@@ -188,11 +212,11 @@ namespace FooEditEngine
                 //内部形式に変換する
                 var internal_str = from s in str where s != '\r' && s != '\0' select s;
 
-                this.rwlock.EnterWriteLock();
+                await this.LockAsync().ConfigureAwait(false);
                 //str.lengthは事前に確保しておくために使用するので影響はない
                 this.buf.InsertRange(index, internal_str, str.Length);
 
-                this.rwlock.ExitWriteLock();
+                this.UnLock();
 
                 if (tokenSource != null)
                     tokenSource.Token.ThrowIfCancellationRequested();
@@ -204,36 +228,6 @@ namespace FooEditEngine
             } while (readCount > 0);
         }
 
-        internal async Task SaveAsync(TextWriter fs,CancellationTokenSource tokenSource=null)
-        {
-            try
-            {
-                this.rwlock.EnterWriteLock();
-                StringBuilder line = new StringBuilder();
-                for (int i = 0; i < this.Length; i++)
-                {
-                    char c = this[i];
-                    line.Append(c);
-                    if (c == Document.NewLine || i == this.Length - 1)
-                    {
-                        string str = line.ToString();
-                        str = str.Replace(Document.NewLine.ToString(), fs.NewLine);
-                        await fs.WriteAsync(str).ConfigureAwait(false);
-                        line.Clear();
-                        if (tokenSource != null)
-                            tokenSource.Token.ThrowIfCancellationRequested();
-#if TEST_ASYNC
-                        System.Threading.Thread.Sleep(10);
-#endif
-                    }
-                }
-            }
-            finally
-            {
-                this.rwlock.ExitWriteLock();
-            }
-        }
-
         internal void ReplaceRegexAll(LineToIndexTable layoutlines, Regex regex, string pattern, bool groupReplace)
         {
             for (int i = 0; i < layoutlines.Count; i++)
@@ -247,7 +241,7 @@ namespace FooEditEngine
                         return pattern;
                 });
 
-                this.rwlock.EnterWriteLock();
+                this.Lock();
                 try
                 {
                     //空行は削除する必要はない
@@ -257,7 +251,7 @@ namespace FooEditEngine
                 }
                 finally
                 {
-                    this.rwlock.ExitWriteLock();
+                    this.UnLock();
                 }
 
                 this.Update(this, new DocumentUpdateEventArgs(UpdateType.Replace, lineHeadIndex, lineLength, output.Length, i));
@@ -275,7 +269,7 @@ namespace FooEditEngine
                 int newLineLength = lineLength;
                 while ((right = ts.IndexOf(this.buf, left, lineHeadIndex + newLineLength)) != -1)
                 {
-                    this.rwlock.EnterWriteLock();
+                    this.Lock();
                     try
                     {
                         this.buf.RemoveRange(right, target.Length);
@@ -283,7 +277,7 @@ namespace FooEditEngine
                     }
                     finally
                     {
-                        this.rwlock.ExitWriteLock();
+                        this.UnLock();
 
                     }
                     left = right + pattern.Length;
@@ -297,12 +291,12 @@ namespace FooEditEngine
 
         internal int IndexOf(string target, int start,bool ci = false)
         {
-            this.rwlock.EnterReadLock();
+            this.Lock();
 
             TextSearch ts = new TextSearch(target,ci);
             int patternIndex = ts.IndexOf(this.buf, start,this.buf.Count);
 
-            this.rwlock.ExitReadLock();
+            this.UnLock();
 
             return patternIndex;
         }