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=1.5 required=5.0 tests=BAYES_00,FROMSPACE, FROM_ADDR_WS,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,7675210751e9faaa,start X-Google-Attributes: gid103376,public From: " "@deneb.cygnus.argh.org (Florian Weimer) Subject: Handling exceptions to create an atomic operation Date: 1999/12/04 Message-ID: <87r9h2ecol.fsf@deneb.cygnus.argh.org>#1/1 X-Deja-AN: 556630056 Mail-Copies-To: never Content-Type: text/plain; charset=us-ascii X-Complaints-To: abuse@cygnus.argh.org X-Trace: deneb.cygnus.argh.org 944335178 5558 192.168.1.2 (4 Dec 1999 19:19:38 GMT) Organization: Penguin on board Mime-Version: 1.0 User-Agent: Gnus/5.0803 (Gnus v5.8.3) Emacs/20.4 NNTP-Posting-Date: 4 Dec 1999 19:19:38 GMT Newsgroups: comp.lang.ada Date: 1999-12-04T19:19:38+00:00 List-Id: An operation which internally creates several objects should appear to the caller as one operation which can either complete fail or succeed. The following code (using the POSIX bindings) illustrates the problem: begin Open_Template (Proc_Template); Create_Pipe (Read_End => Input_Read, Write_End => Input_Write); Create_Pipe (Read_End => Output_Read, Write_End => Output_Write); Create_Pipe (Read_End => Error_Read, Write_End => Error_Write); Set_File_Action_To_Close (Proc_Template, Input_Write); Set_File_Action_To_Close (Proc_Template, Output_Read); Set_File_Action_To_Close (Proc_Template, Error_Read); Start_Process (PID, Path, Proc_Template); Close_Template (Proc_Template); exception when others => ??? -- What to do? end; If one of the initialization steps fails, the steps executed so far have to be reverted. A few possible solution came to my mind: - Nesting exception handler blocks (looks horrible because you quickly get a very deep nesting level) - Use local variables to keep track of the operations which have already been completed, and one big exception handler which makes the necessary cleanups (I don't know yet whether I like this one or not) - Cleanup code duplication (error prone) - (The C style: goto in exception handler to cleanup code -- fortunately, this one doesn't work...) - Nested subprogram for each operation, one subprogram calls the next one in the sequence of operations (keeps object creation and corresponding exception handler together, results in moderate but constant nesting level) Perhaps there are even better solutions? Which one is the most practical and most Ada-like in your opinion? (BTW: Where can I get usage examples for the POSIX binding? I fear that my code will look very bizarre to the experienced Ada programmer if I follow my own ideas of doing things...)