<br><br><div class="gmail_quote">---------- Forwarded message ----------<br>From: <b class="gmail_sendername">Eliot Miranda</b> <span dir="ltr">&lt;<a href="mailto:eliot.miranda@gmail.com">eliot.miranda@gmail.com</a>&gt;</span><br>
Date: Fri, Jun 7, 2013 at 12:59 PM<br>Subject: Re: [Pharo-dev] FogBugz (Case [Issue]10840) Collection - WeakSet&gt;&gt;#size utterly broken<br>To: Pharo Development List &lt;<a href="mailto:pharo-dev@lists.pharo.org">pharo-dev@lists.pharo.org</a>&gt;<br>
<br><br>Oops, I&#39;m soooo stupid :)<div><br></div><div>Instead, put the count in the finalization loop, and compare against it.  e.g.</div><div><br></div><div><div>finalizationProcess</div><div><span style="white-space:pre-wrap">        </span>[true] whileTrue: [ </div>

<div><span style="white-space:pre-wrap">                </span>WeakFinalizationList initTestPair.</div><div><span style="white-space:pre-wrap">                </span>FinalizationSemaphore wait.</div><div>&gt;&gt;&gt;<span style="white-space:pre-wrap">                </span>FinalizationCount := FinalizationCount + 1.</div>

<div><span style="white-space:pre-wrap">                </span>FinalizationLock critical: [</div><div><span style="white-space:pre-wrap">                        </span>WeakFinalizationList checkTestPair.</div><div><span style="white-space:pre-wrap">                        </span>FinalizationDependents do: <span style="white-space:pre-wrap">        </span>[:weakDependent |</div>

<div><span style="white-space:pre-wrap">                                </span>weakDependent ifNotNil: [</div><div><span style="white-space:pre-wrap">                                        </span>[ weakDependent finalizeValues ] on: Exception fork: [:ex | ex pass ] ]]]].</div>
<div><br></div><div>finalizationCount</div><div><span style="white-space:pre-wrap">        </span>^FinalizationCount</div><div><br></div><div><br></div><div><div>Set subclass: #WeakSet</div><div><span style="white-space:pre-wrap">        </span>instanceVariableNames: &#39;flag <span style="border-collapse:collapse;font-family:arial,sans-serif;font-size:14px">finalizationCount</span>&#39;</div>

<div><span style="white-space:pre-wrap">        </span>classVariableNames: &#39;&#39;</div><div><span style="white-space:pre-wrap">        </span>poolDictionaries: &#39;&#39;</div><div><span style="white-space:pre-wrap">        </span>category: &#39;Collections-Weak&#39;</div>

</div><div><br></div><div><div style="border-collapse:collapse;font-family:arial,sans-serif;font-size:14px">size</div><div style="border-collapse:collapse;font-family:arial,sans-serif;font-size:14px">      | newFinalizationCount |</div>

<div style="border-collapse:collapse;font-family:arial,sans-serif;font-size:14px">      newFinalizationCount := WeakArray getFinalizationCount.</div><div style="border-collapse:collapse;font-family:arial,sans-serif;font-size:14px">

      newFinalizationCount == finalizationCount ifTrue:</div><div class="im"><div style="border-collapse:collapse;font-family:arial,sans-serif;font-size:14px">          [^tally].</div><div style="border-collapse:collapse;font-family:arial,sans-serif;font-size:14px">

      tally := self computeActualSIze.</div></div><span style="border-collapse:collapse;font-family:arial,sans-serif;font-size:14px">      finalizationCount := </span><span style="border-collapse:collapse;font-family:arial,sans-serif;font-size:14px">newFinalizationCount</span></div>
<div><div class="h5">
<div><br></div><br><div class="gmail_quote">On Fri, Jun 7, 2013 at 11:30 AM, Eliot Miranda <span dir="ltr">&lt;<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<br><br><div class="gmail_quote"><div><div>On Fri, Jun 7, 2013 at 2:34 AM, Camille Teruel <span dir="ltr">&lt;<a href="mailto:camille.teruel@gmail.com" target="_blank">camille.teruel@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div style="word-wrap:break-word"><div> On 7 juin 2013, at 11:19, Pharo Issue Tracker wrote:<div><br><blockquote type="cite"><div>A FogBugz case was edited by Stephane Ducasse.<br><br>Case ID:      10840<br>Title:        WeakSet&gt;&gt;#size utterly broken<br>


Status:       Resolved (Fix Review Needed)<br>Category:     Bug<br>Project:      Collection<br>Area:         Misc<br>Priority:     3 - Must Fix<br>Milestone:    Pharo3.0: 30/03/2014<br>Assigned To:  Camille Teruel<br><br>


URL:          <a href="https://pharo.fogbugz.com/f/cases/10840" target="_blank">https://pharo.fogbugz.com/f/cases/10840</a><br><br>Last message:<br>Please can you send a mail to the mailing-list so that we all discuss this problems.<br>


</div></blockquote><br><div>Hello everyone,<div><br></div><div>WeakSet&gt;&gt;#size is broken as demonstrated by the following snippet:</div><div><br></div><div>set := WeakSet new.</div><div>set add: Object new.</div><div>


Smalltalk garbageCollect.</div><div>set size. &quot;answers 1 instead of 0&quot;</div><div><br></div><div>That is because a WeakSet has no mean to know when its items get garbage collected, and thus the tally cannot be updated.</div>


<div>So we need to override #size in Weak, I propose:</div><div><div>size</div><div><span style="white-space:pre-wrap">        </span>| counter |</div><div><span style="white-space:pre-wrap">        </span>counter := 0.</div><div><span style="white-space:pre-wrap">        </span>self do: [ :e | counter := counter + 1 ].</div>


<div><span style="white-space:pre-wrap">        </span>^ counter</div></div><div>But that it rather inefficient for such a simple query.</div><div><div>Any proposition?</div></div></div></div></div></div></blockquote><div><br></div>


</div></div><div>One way is to add WeakSets to FInalizationDependents and implement finalizeValues to update the size.  But that&#39;s making work.  A lazy solution might be better.</div><div><br></div><div>You *could*, I suppose, use the VM&#39;s count of the number of incremental and full GCs (alas there&#39;s no single count).  I think this is too ugly and one would need something neater, but it would work like this:</div>


<div><br></div><div>size</div><div>      | newGCCount |</div><div>      newGCCount := self getGCCount.</div><div>      newGCCount == existingGCCount ifTrue:</div><div>          [^tally].</div><div>      tally := self computeActualSIze.</div>


<div>      existingGCCount := newGCCount</div><div><br></div><div>where</div><div>    getGCCount</div><div>        ^(Smalltalk vmParameterAt: 7) + (Smalltalk vmParameterAt: 9)</div><div>      </div><div>There are obviously thread-safety issues here, but there are issues with the existing code and your suggestion too ;)</div>


<div><br></div><div>The most useful single count here would be a count that was incremented once in each GC that finalized one or more references.</div><div><br></div><div>Note also that for this to be reliable instances&#39; record of the count would have to be invalidated on snapshot or start-up, which could entail an expensive allInstancesDo:.</div>


<div><br></div><div>Perhaps the class WeakSet should maintain its instances in (of course) a WeakSet and then add only itself to FinalizationDependents and enumerate the set on finalization?</div><div><br></div><div><br>

</div>
<div><br></div><div>I note that in the VisualWorks VM, objects that have references finalized are added to a queue so every instance that loses a reference gets sent finalize, instead of only dependents as in Squeak.  This has its won problems (the VM must cope with a potentially large list) but I think it provides more convenient control.</div>

<div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><div><div><div><div><br></div><div>The bug entry is: <a href="https://pharo.fogbugz.com/f/cases/10840" target="_blank">https://pharo.fogbugz.com/f/cases/10840</a></div>


</div><div><br></div></div><blockquote type="cite"><div><br><br>If you do not want to receive automatic notifications anymore, change your preferences in the Options screen. (<a href="https://pharo.fogbugz.com/default.asp?pg=pgPrefs" target="_blank">https://pharo.fogbugz.com/default.asp?pg=pgPrefs</a>)<br>


</div></blockquote></div><br></div></div></blockquote></div></div><span><font color="#888888"><br><br clear="all"><div><br></div>-- <br>best,<div>Eliot</div>
</font></span></blockquote></div><br><br clear="all"><div><br></div></div></div><span class="HOEnZb"><font color="#888888">-- <br>best,<div>Eliot</div>
</font></span></div>
</div><br><br clear="all"><div><br></div>-- <br>best,<div>Eliot</div>