Keeping a list of instances and garbage-collection

Christopher Wright dhasenan at gmail.com
Mon Mar 30 15:37:15 PDT 2009


grauzone wrote:
> Christopher Wright wrote:
>> grauzone wrote:
>>> Jarrett Billingsley wrote:
>>>> On Sun, Mar 29, 2009 at 4:42 PM, Leandro Lucarella 
>>>> <llucax at gmail.com> wrote:
>>>>> This was discussed several times in the past. For example:
>>>>> http://www.digitalmars.com/d/archives/digitalmars/D/learn/weak_references_13301.html 
>>>>>
>>>>> http://www.digitalmars.com/d/archives/digitalmars/D/learn/Soft_weak_references_8264.html 
>>>>>
>>>>> http://www.digitalmars.com/d/archives/digitalmars/D/announce/ANN_WeakObjectReference_-_class_to_hold_weak_references_9103.html 
>>>>>
>>>>> etc.
>>>>>
>>>>> I hope it helps.
>>>>
>>>> The one provided by Bill:
>>>>
>>>> http://www.dsource.org/projects/scrapple/browser/trunk/weakref
>>>>
>>>> seems to work fine, and has the advantage of working in both Phobos 
>>>> and Tango.
>>>
>>> First, I doubt this actually works. The WeakRef stores the pointer as 
>>> size_t, but the GC is conservative and will still recognize the 
>>> size_t as a pointer. The unittest in the existing code only works, 
>>> because he uses an explicit delete on the referenced object.
>>
>> If the WeakRef is on the stack, this is true.
>>
>> If the WeakRef is part of an aggregate type that contains pointers, 
>> this is true.
> 
> If WeakRef is a class, this is also true. Because all objects contain a 
> hidden monitor pointer, and the monitor is subject to garbage collection 
> AFAIK.
> 
>> Otherwise, the GC will see that the relevant block is marked as having 
>> no pointers.
>>
>> True -- weakref is a difficult thing to make thread-safe.
> 
> It seems there's still work to do, and a thread-safe WeakRef can't be 
> created with the current interfaces. Is this true?
> 
> I'm thinking rt_attachDisposeEvent() should take a *pointer* to the 
> reference instead of the reference itself (effectively a double 
> pointer), and clear this pointer during garbage collection, when all 
> threads are still globally locked.

Hold on, I think this isn't a real issue.

You have essentially:
class WeakRef
{
	const xor = 0x101010101;
	size_t value;
	bool collected;
	Object toObject()
	{
		if (collected) return null;
		auto ptr = cast(void*)(value ^ xor);
		auto obj = *cast(Object*)&ptr;
		if (collected) return null;
		return obj;
	}
}


After casting, you have a strong reference to the object, so it's 
impossible for the object to be collected if it hasn't yet been 
collected. If the object was collected between the two checks, you just 
have an invalid object reference that nobody ever uses. As long as the 
compiler doesn't do nasty reordering things, you should be fine.



More information about the Digitalmars-d mailing list