comp.lang.ada
 help / color / mirror / Atom feed
* Handling exceptions to create an atomic operation
@ 1999-12-04  0:00 Florian Weimer
  1999-12-05  0:00 ` Robert A Duff
  1999-12-13  0:00 ` Matthew Heaney
  0 siblings, 2 replies; 4+ messages in thread
From: Florian Weimer @ 1999-12-04  0:00 UTC (permalink / raw)


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...)




^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Handling exceptions to create an atomic operation
  1999-12-04  0:00 Handling exceptions to create an atomic operation Florian Weimer
@ 1999-12-05  0:00 ` Robert A Duff
  1999-12-12  0:00   ` Florian Weimer
  1999-12-13  0:00 ` Matthew Heaney
  1 sibling, 1 reply; 4+ messages in thread
From: Robert A Duff @ 1999-12-05  0:00 UTC (permalink / raw)


" "@deneb.cygnus.argh.org (Florian Weimer) writes:

> An operation which internally creates several objects should appear to
> the caller as one operation which can either complete fail or succeed.

Consider using controlled types.

- Bob




^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Handling exceptions to create an atomic operation
  1999-12-05  0:00 ` Robert A Duff
@ 1999-12-12  0:00   ` Florian Weimer
  0 siblings, 0 replies; 4+ messages in thread
From: Florian Weimer @ 1999-12-12  0:00 UTC (permalink / raw)


Robert A Duff <bobduff@world.std.com> writes:

> " "@deneb.cygnus.argh.org (Florian Weimer) writes:
> 
> > An operation which internally creates several objects should appear to
> > the caller as one operation which can either complete fail or succeed.
> 
> Consider using controlled types.

Something like the C++ auto_ptr template?  This sounds like a
good suggestion.  In fact, the code looks much cleaner now.  Thanks.

Limited types, however, seem to be a bit difficult to handle this way.
It's probably more reasonable to hack FLORIST to use controlled types
than to play with Unrestricted_Access (or even Unchecked_Access)...




^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Handling exceptions to create an atomic operation
  1999-12-04  0:00 Handling exceptions to create an atomic operation Florian Weimer
  1999-12-05  0:00 ` Robert A Duff
@ 1999-12-13  0:00 ` Matthew Heaney
  1 sibling, 0 replies; 4+ messages in thread
From: Matthew Heaney @ 1999-12-13  0:00 UTC (permalink / raw)


In article <87r9h2ecol.fsf@deneb.cygnus.argh.org> , " 
"@deneb.cygnus.argh.org (Florian Weimer) wrote:

> 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:

[snipped]

> 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)

The blocks only require partial nesting:

    begin

      begin
       Open_Template (Proc_Template);
      exception
       when others =>
           <handle open_template error>
           return;  -- or whatever
      end;

      begin
       Create_Pipe (Read_End => Input_Read, Write_End => Input_Write);
      exception
        <close template>
        return;
      end;

      <individual blocks for each statement>

    end;


>   - 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)

You could combine these ideas; for example, the outermost exception
handler checks to see if the proc_template is open (assuming there's a
predicate function to do that), and then closes it if it is.


>   - (The C style: goto in exception handler to cleanup code --
>      fortunately, this one doesn't work...)

If you have separate blocks for each statement, you can jump from an
exception handler to a location between blocks, eg

     ...

      begin
       Create_Pipe (Read_End => Error_Read, Write_End => Error_Write);
      exception
        when others =>
           <handle create_pipe error only>
           goto Do_Close_Template;
      end;

      ...

      <<Do_Close_Template>> begin
       Close_Template (Proc_Template);
      exception
        when others =>
          <handle close error>
      end;



--
Creationists attempt to draw a line between evolutionary biology and the
rest of science by remarking that large-scale evolution cannot be
observed.  This tactic fails.  Large-scale evolution is no more
inaccessible to observation than nuclear reactions or the molecular
composition of water.

Abusing Science: The Case Against Creationism
Philip Kitcher




^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~1999-12-13  0:00 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-12-04  0:00 Handling exceptions to create an atomic operation Florian Weimer
1999-12-05  0:00 ` Robert A Duff
1999-12-12  0:00   ` Florian Weimer
1999-12-13  0:00 ` Matthew Heaney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox