From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.9 required=5.0 tests=BAYES_00,FORGED_GMAIL_RCVD, FREEMAIL_FROM autolearn=no autolearn_force=no version=3.4.4 Path: border1.nntp.dca3.giganews.com!border2.nntp.dca3.giganews.com!border4.nntp.dca.giganews.com!border2.nntp.dca.giganews.com!nntp.giganews.com!usenet.blueworldhosting.com!feeder02.blueworldhosting.com!eternal-september.org!feeder.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Natasha Kerensikova Newsgroups: comp.lang.ada Subject: Reference counting and idempotent finalize Date: Wed, 11 Sep 2013 10:45:37 +0000 (UTC) Organization: A noiseless patient Spider Message-ID: Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Injection-Date: Wed, 11 Sep 2013 10:45:37 +0000 (UTC) Injection-Info: mx05.eternal-september.org; posting-host="31d6bde745a337034b005384ef225743"; logging-data="14849"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX195RxXXWq7CV4fP3os5Bj6r" User-Agent: slrn/0.9.9p1 (FreeBSD) Cancel-Lock: sha1:F8LLpj9X1fC+leQoKpZWC5A1yXw= X-Original-Bytes: 2930 Xref: number.nntp.dca.giganews.com comp.lang.ada:183331 Date: 2013-09-11T10:45:37+00:00 List-Id: Hello, I have recently reinvented the reference counted wheel, and been told that I got it all wrong because Finalize must be idempotent. However I already diffusely knew that, though I cannot remember from where it comes or whether I thought of it as a hard requirement or only as a good practice (the difference is hard to tell when such a rule is internalized). Anyway, my naive implementation looks like that: procedure Finalize (Self : in out Reference) is begin Release (Self.Access_Value); end Finalize; procedure Release (Access_Value : in out Access_To_Actual_Data) is begin if Access_Value /= null then Access_Value.all.Counter := Access_Value.all.Counter - 1; if Access_Value.all.Counter = 0 then Unchecked_Deallocation_Instance (Access_Value); else Access_Value := null; end if; end if; end Release; For the reference, I used explicit dereference because in the real code the parameter is not called Access_Value and is not obviously an access, so I thought it clearer that way. And the procedure Release is used because Finalize feels "special" so I don't want to call it myself. As far as I can see, Access_Value = null could be post condition for Release, and unless the code flow is interrupted by an exception, that looks extremely idempotent to me. Am I missing something here? I neglected the possibility of exceptional flow interruption because I felt that an exception in Finalize triggers the end of the world (the same way I've felt for a long time the idempotency requirement). Now having done the research, 7.6.1(13) doesn't really mention the world ending, that looks quite close to it, doesn't it? Am I missing something on the exception part? Or is my implementation good enough? Thanks in advance for your help, Natasha