From: Alex P. <pes...@ma...> - 2011-03-27 12:57:42
|
On 03/25/11 21:16, Adriano dos Santos Fernandes wrote: > >> Let's suppose that user implemented some helper around IAttachment*, >> which is not refCounted as you wish. Please explain, how must behave >> that object when detach is requested, but there are some other threads, >> using that object. >> > Let me first say something about your refcounted approach: > > Current, when an user detachs and attachment, all handles related to it > and not-yet-freed are closed. > > Let say you did the same when calling IAttachment::detach. Then your > refcount don't work, cause it will wipe pointers to objects with references. > > Let say it don't free the subobjects. Then you're making a common > situation (close a parent -> close children) to leak memory. > > Now about your question, more directly. If this thread is doing > something inside the yvalve, the detach may (*internally) decrement a > refcounter and don't free the object, so we don't see a crash inside the > yvalve. As soon the yvalve release this reference, the object is wiped. This is wrong suggestion. We must return correct status value from detach, but what can we return if we just decrement refcounter? And what should we do when we try to do real job, but something goes wrong? This is specially well seen on a sample with commit and some error thrown when doing DFW. This is the place where presence of reference counters in API objects obviously helps. Certainly, a more or less cunning combination of smart pointer to refcounted helper object, containing lock and a flag, will work (at least I do not see reason why should it not work). But if it's OK for yValve (if we forget about extra performance loss due to the lock), I think that suggesting users to implement something similar themselves is not good idea. Another approach that will sooner of all work is when detach/drop/commit/etc do not dispose/release an object. This must be done explicitly, i.e. the sequence of calls is: ITransaction* tra = att->startTransaction(); // do some job with that transaction tra->commit(); tra->dispose(); This works, but looks bad for ST appliactions. > Note we don't need any effort to support this. As soon we remove > addRef/release from IInterface, we can make YAttachment and friends to > inherit from RefCounted and IAttachment and friends. > > So I insist, moving addRef/release to the API fixes nothing and only > complicate things. Transactions has no release, it's freed by > commit/rollback. Attachments has no release, it's freed by detach/drop. > There is no reason to insert a release function in them that sometimes > do a thing (decrement a refcounter) and sometimes do another (rollback > or detach). What to do if release/dispose is called for not detached/committed object is really hard question. The most logical way is to treat death of the object from release/dispose exactly like from process exit. And this is in accordance with at least OLE DB standards. |