<div>Locking during finalization is often considered to be a bad idea. &nbsp;In particular, locking without a timeout introduces the possibility that you will hang the finalization thread, preventing further objects from being finalized. &nbsp;But clearly, that&#39;s not what&#39;s happening here.</div>
<div><br></div><div>Other questions that probably don&#39;t matter but might be interesting to know:</div><div><br></div><div>Can we assume that the finalization thread isn&#39;t the first place where this lock is required? &nbsp;That your log starts somewhere in the middle?</div>
<div><br></div><div>Is this under x86 or x64 or both?</div><div><br></div><div>Are you creating any additional AppDomains in the process?</div><div><br></div><br><div class="gmail_quote">On Wed, Nov 5, 2008 at 10:15 AM, William Reade <span dir="ltr">&lt;<a href="mailto:william@resolversystems.com">william@resolversystems.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">Hi Curt<br>
<br>
I am indeed; that&#39;s how I know thread 2 is the GC thread. Is locking during GC forbidden?<br>
<br>
William<br>
<br>
Curt Hagenlocher wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="Ih2E3d">
...or, for that matter, any __del__ methods from within Python -- which ultimately are handled by finalization.<br>
<br></div><div class="Ih2E3d">
On Wed, Nov 5, 2008 at 9:37 AM, Curt Hagenlocher &lt;<a href="mailto:curt@hagenlocher.org" target="_blank">curt@hagenlocher.org</a> &lt;mailto:<a href="mailto:curt@hagenlocher.org" target="_blank">curt@hagenlocher.org</a>&gt;&gt; wrote:<br>

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