Bugzilla – Bug 312985
Threading.SyncronizationException thrown on calling Monitor.Exit on an object that has not been locked.
Last modified: 2007-09-15 21:24:46 UTC
---- Reported by gileslforster@yahoo.co.uk 2003-10-18 09:57:06 MST ---- Please fill in this template when reporting a bug, unless you know what you are doing. Description of Problem: Steps to reproduce the problem: Bellow a simple console application calling Monitor.Exit(obj) on an object to which Monitor.Enter(obj) has not been called. using System; using System.Threading; namespace ConsoleApplication { class Class1 { [STAThread] static void Main(string[] args) { Class1 x = new Class1(); Monitor.Exit(x); Console.WriteLine("All done."); } } } Actual Results: [giles@Linux-02 Mono]$ mono ConsoleApplication.exe Unhandled Exception: System.Threading.SynchronizationLockException: Not locked in (unmanaged) /usr/lib/libmono.so.0(mono_raise_exception+0x20) [0x400aa8e9] in (unmanaged) /usr/lib/libmono.so.0(mono_monitor_exit+0x3b) [0x400c387d] in (unmanaged) /usr/lib/libmono.so.0 [0x400c3939] in <0x0003b> System.Threading.Monitor:Exit (object) in <0x00036> ConsoleApplication.Class1:Main (string[]) Expected Results: [giles@Linux-02 Mono]$ mono ConsoleApplication.exe All done. [giles@Linux-02 Mono]$ How often does this happen? Always. Additional Information: Under .NET 1.1 on Windows the default behaviour is to ignore the fact that Enter() has not been called if calling Exit() on an unlocked object for the current thread. On Mono it throws a SynchronizationLockException, leading to incompatible code. Not sure what the ECMA standard says but don't know where to look. Thanks, Giles ---- Additional Comments From dick@ximian.com 2003-10-20 11:12:34 MST ---- Looks like the ms Monitor implementation is rather buggy. using System; using System.Threading; namespace ConsoleApplication { class Class1 { static Class1 x; static void OtherThread() { Monitor.Exit(x); Console.WriteLine("Passed x Exit"); } [STAThread] static void Main(string[] args) { x = new Class1(); Monitor.Enter(x); Thread thr=new Thread(new ThreadStart(Class1.OtherThread)); thr.Start(); thr.Join(); Console.WriteLine("All done."); } } } prints both WriteLines for me, ms runtime 1.1. Reading the Monitor class documentation again, I suppose it could be argued that "The current thread does not own the lock for the specified object" could be read so as to not throw SynchronizationLockException when the object is not locked at all, but unless my test above is faulty, it isn't thrown even when another thread _does_ own the lock. (Changing the Monitor.Exit(x) into a Monitor.Enter(x) does deadlock as expected though.) ---- Additional Comments From gonzalo@ximian.com 2005-06-24 03:50:44 MST ---- This was fixed on 2005-05-05. Unknown bug field "cf_op_sys_details" encountered while moving bug <cf_op_sys_details>Standard Install</cf_op_sys_details>