EnterUpgradeableReadLockに入った後、EnterWriteLock/ExitWriteLockを実行し、ExitUpgradeableReadLockで抜けた後に、EnterWriteLockを実行するとデッドロックするというバグを見つけました。たぶん直るであろうパッチはこんな感じ。
ReaderWriterLockSlim.cs.patch, ReaderWriterLockSlimTest.cs.patch
Index: ReaderWriterLockSlim.cs
===================================================================
--- ReaderWriterLockSlim.cs (revision 135929)
+++ ReaderWriterLockSlim.cs (working copy)
@@ -288,8 +288,11 @@
}
//Debug.Assert (numUpgradeWaiters > 0);
- write_thread = upgradable_thread = null;
- owners = 0;
+ if (upgradable_thread == Thread.CurrentThread)
+ owners = 1;
+ else
+ owners = 0;
+ write_thread = null;
ExitAndWakeUpAppropriateWaiters ();
}
Index: ReaderWriterLockSlimTest.cs
===================================================================
--- ReaderWriterLockSlimTest.cs (revision 135929)
+++ ReaderWriterLockSlimTest.cs (working copy)
@@ -391,5 +391,18 @@
t.Join ();
}
}
+
+ [Test]
+ public void EnterWriteLock_After_ExitUpgradeableReadLock ()
+ {
+ var v = new ReaderWriterLockSlim ();
+
+ v.EnterUpgradeableReadLock ();
+ Assert.IsTrue (v.TryEnterWriteLock (100));
+ v.ExitWriteLock ();
+ v.ExitUpgradeableReadLock ();
+ Assert.IsTrue (v.TryEnterWriteLock (100));
+ v.ExitWriteLock ();
+ }
}
}
いやぁ…今作っているDHTを使ったP2Pアプリの開発中に見つけたんですがね、
問題があることに気がついたのが、21時。どういうタイミングで再現するのか探すのに1時間。
自分のコードに問題があると考え、トレースすること1時間。
なんか記憶が飛んだ1時間。
原因箇所を特定するのに1時間、そしてMonoのReaderWriterLockSlimにバグがあることがわかりました…
くそー、原因を探すのに3時間もかかったぜー orz
でも、このパッチが合っているかどうかわからないけど、後は丸投げしちゃえっ