So, the obvious question for me is whether or not you're using any finalizers.<br><br><div class="gmail_quote">On Wed, Nov 5, 2008 at 5:57 AM, William Reade <span dir="ltr"><<a href="mailto:william@resolversystems.com">william@resolversystems.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">Hi all<br>
<br>
While running the numpy tests, I've come across a situation which, to the best of my knowledge, is simply impossible. I'm hoping that one of the local .NET gurus will be able to tell me what I'm missing, or point me somewhere I can get more insight.<br>
<br>
The 4 methods involved are as follows:<br>
-----------------------<br>
public int GetThreadId()<br>
{<br>
return Thread.CurrentThread.ManagedThreadId;<br>
}<br>
<br>
public void WriteFlush(string info)<br>
{<br>
Console.WriteLine(info);<br>
Console.Out.Flush();<br>
}<br>
<br>
public void EnsureGIL()<br>
{<br>
Monitor.Enter(this.dispatcherLock);<br>
this.WriteFlush(String.Format(<br>
"EnsureGIL ({1}) {0}", this.GetThreadId(), Builtin.id(this.dispatcherLock)));<br>
}<br>
<br>
public void ReleaseGIL()<br>
{<br>
this.WriteFlush(String.Format(<br>
"ReleaseGIL ({1}) {0}\n", this.GetThreadId(), Builtin.id(this.dispatcherLock)));<br>
Monitor.Exit(this.dispatcherLock);<br>
}<br>
-----------------------<br>
...and they can, and do, occasionally produce output as follows:<br>
-----------------------<br>
EnsureGIL (443) 2<br>
EnsureGIL (443) 1 <- omg, wtf, bbq, etc.<br>
ReleaseGIL (443) 2<br>
<br>
EnsureGIL (443) 2<br>
ReleaseGIL (443) 1<br>
<br>
ReleaseGIL (443) 2<br>
-----------------------<br>
When this happens, the process continues happily for a short time and then falls over in a later call to ReleaseGIL (after successfully calling it several times). The error is " Object synchronization method was called from an unsynchronized block of code", which I understand to mean "you can't release this lock because you don't hold it".<br>
<br>
It doesn't happen very often, but I can usually reproduce it by running test_multiarray.TestFromToFile.test_malformed a few hundred times. It may be relevant to note that thread 2 is the GC thread, and thread 1 is the main thread. I have considered the following possibilities:<br>
<br>
(1) That I'm locking on the wrong object. I believe that isn't the case, because it's constructed only once, as a "new Object()" (ie, a reference type), and is only subsequently used for locking; and, because it keeps the same ipy id throughout.<br>
<br>
(2) That Monitor.Enter occasionally allows two different threads to acquire the same lock. I consider this extremely unlikely, because... well, how many multithreaded .NET apps already exist? If Monitor really were broken, I think we'd probably know about it by now.<br>
<br>
(3) That calling Flush() on a SyncTextWriter (the type of Console.Out) doesn't actually do anything, and the output is somehow wrongly ordered (although I can't imagine how this could actually be: if the locking is really working, then my console writes are strictly sequential). I don't have access to the code, so I have no idea how it's implemented, but even if this is the case it doesn't help much with the fundamental problem (the synchronisation error which follows).<br>
<br>
Apart from the above, I'm out of ideas. Can anyone suggest what I've missed?<br>
<br>
William<br>
_______________________________________________<br>
Users mailing list<br>
<a href="mailto:Users@lists.ironpython.com" target="_blank">Users@lists.ironpython.com</a><br>
<a href="http://lists.ironpython.com/listinfo.cgi/users-ironpython.com" target="_blank">http://lists.ironpython.com/listinfo.cgi/users-ironpython.com</a><br>
</blockquote></div><br>