On 04/07/11 14:55, Dmitry Yemanov wrote:
> 30.03.2011 21:45, Vlad Khorsun wrote:
>
>>> What would do a detach/commit/etc in an object when refcount>  1?
>>      Call corresponding method of real object. And not touch refcount.
>>
>>> What would do a detach/commit/etc in an object when refcount = 1?
>>      Same as above.
> Sorry for ignorance, but why refcount is not decremented in these cases? 
> I mean, what is the point in requiring an extra release() call if the 
> user has explicitly stated that he no longer needs an object. Note that 
> we don't require an explicit addRef() call when the object gets created.

To give good answer to this question we should decide, how exact are we
going to follow reference counter logic in OLE2.

Formal approach says - number of addRef()/release() calls for an object
should match. Constructor creates an object with 0 reference counter.
When an object is returned from _any_ function, addRef should be called.
This addRef is for the process of returning object - imagine that we
return not newly created object but already existing. That object may be
used in some other place. If it's reference counter is decreased in some
other place to become 0 without such addRef() we may return from
function pointer to deallocated memory instead good object. Calling the
paired release() is responsibility of code which invoked the function
which returned an object. There are 2 typical usages: without smart
pointers and with them. In the first case typical code looks like:

Object* obj = getObject(...);
obj->blaBlaBla();
obj->release();    // refCounter becomes 0, object destroyed

With smart pointers:

Smart<Object> obj = getObject(...);    // refCounter == 2
obj->release();        // refCounter == 1
obj->blaBlaBla();
// In ~Smart() refCounter will become 0 and object will be destroyed

If we want detach to decrement refCounter (I must say we can do it if we
want, we are not OLE2) first sample looks very good for us:

IAttachment* att = provider->attachDatabase(...);
att->doSomething();
att->detach();

But with smart pointers we must do the following:

Smart<IAttachment> at = ...
att->release();        // refCounter == 1
att->blaBlaBla();

We want to detach - and here problems come. We can't simply call:

att->detach();

because ~Smart() will try to release an already destroyed object,
causing AV. From formal POV we must:

att->addRef();
att->detach();

which is correct, but ugly. Or we may do the following:

Smart<IAttachment> at = ...;    // refCounter == 2
att->blaBlaBla();
att->detach();        // refCounter == 1
// In ~Smart() refCounter will become 0 and object will be destroyed

This looks good, but somehow breaks smart pointers - if detach is not
done, object will leak. On the other hand, this is like ISC API behaves now.

Must say that if we decide to use approach with detach() decrementing
refCounter(), people may themself choose, what way do they prefer - from
fbclient library POV it will make no difference.


------------------------------------------------------------------------------
Xperia(TM) PLAY
It's a major breakthrough. An authentic gaming
smartphone on the nation's most reliable network.
And it wants your games.
http://p.sf.net/sfu/verizon-sfdev
Firebird-Devel mailing list, web interface at 
https://lists.sourceforge.net/lists/listinfo/firebird-devel

Reply via email to