From: Alex P. <pes...@ma...> - 2011-03-24 14:56:44
|
On 03/24/11 17:50, Adriano dos Santos Fernandes wrote: > On 24-03-2011 11:36, Alex Peshkoff wrote: >> Well, an example. >> >> I have database attachment and want to use it in some background thread. >> Attachment may be closed at some random moment. I have a choice - check >> some flags before each use of it (and anyway have problems - may be it >> was closed at some point before that check and actual use) or add >> reference to it and use without risk of segfault. Certainly, I must >> check status vector after each operation, and after getting 'invalid >> handle value' return from the thread. But checking status is anyway good >> style, therefore with reference counter in attachment handle I write >> code for that thread as if I'm the owner of an attachment. And I'm >> really one of it's owners after addRef() call! >> > And let me say why it don't work. > > User first get a pointer (refcount = 1) from Firebird. > > Then he may use it and "close at some random moment". So let say, he has > two threads: > > T1: globalObj->addRef(); > T1: globalObj->doSomething(); > T1: globalObj->release(); > > T2: globalObj->release(); > > Nothing prevent the random moment to call T2 release first than T1 > addRef. So it will segfault, because the release will wipe toe object > from memory. > > So you may do some extra addRef and fake the system. But then you don't > need any of them, and would just handle it without a public interface > baggage that serves nothing. > > You see, reference counting alone don't solve the user problem. When used wrong - yes, do not. But if: T1: globalObj->addRef(); T1: start T2 /* that's using globalObj */ It's OK. BTW, it's present in MS docs - "You must also call AddRef on a pointer before passing it ....". |