[GRASS5] gis lib: write error function (put_row.c)

Hi,

while having the problem that a disk run out of space
while using r.in.gdal, I found that

write_error()
in src/libes/gis/put_row.c
just contains G_warning() and not G_fatal_error().

Are there objections to change this to
G_fatal_error("...unable to write row...")
?

It doesn't make much sense to continue writing to a full disk.

Markus

Markus Neteler wrote:

while having the problem that a disk run out of space
while using r.in.gdal, I found that

write_error()
in src/libes/gis/put_row.c
just contains G_warning() and not G_fatal_error().

Are there objections to change this to
G_fatal_error("...unable to write row...")
?

It doesn't make much sense to continue writing to a full disk.

Writes could theoretically fail for reasons other than a full disk,
although I can't actually think of anything which would be
recoverable.

If you change write_error() to call G_fatal_error(), I suggest
changing the calling functions to return "void" rather than a status
value. That way, if anything was actually checking the return value
and attempting recovery, you'll get compilation errors alerting you to
the fact.

In all probability, it should just call G_fatal_error(). If there are
specific cases which actually want to handle the error, they can use
G_set_error_routine().

More generally, library functions which only rarely fail should just
call G_fatal_error() IMHO, rather than returning an error status and
thereby passing the responsibility to the individual modules.

--
Glynn Clements <glynn.clements@virgin.net>

On Tue, Oct 22, 2002 at 01:11:51PM +0100, Glynn Clements wrote:

Markus Neteler wrote:

> while having the problem that a disk run out of space
> while using r.in.gdal, I found that
>
> write_error()
> in src/libes/gis/put_row.c
> just contains G_warning() and not G_fatal_error().
>
> Are there objections to change this to
> G_fatal_error("...unable to write row...")
> ?
>
> It doesn't make much sense to continue writing to a full disk.

Writes could theoretically fail for reasons other than a full disk,
although I can't actually think of anything which would be
recoverable.

If you change write_error() to call G_fatal_error(), I suggest
changing the calling functions to return "void" rather than a status
value. That way, if anything was actually checking the return value
and attempting recovery, you'll get compilation errors alerting you to
the fact.

In all probability, it should just call G_fatal_error(). If there are
specific cases which actually want to handle the error, they can use
G_set_error_routine().

More generally, library functions which only rarely fail should just
call G_fatal_error() IMHO, rather than returning an error status and
thereby passing the responsibility to the individual modules.

If you change G_put_raster_row(), et al. to return void, then it isn't
very easy to tell where the error came from. I thought folks wanted
to get G_fatal_error() out of library functions...

--
static const char signature =
  "Copyright (c) 2002 Eric G. Miller <egm2@jps.net>";

Eric G. Miller wrote:

> > while having the problem that a disk run out of space
> > while using r.in.gdal, I found that
> >
> > write_error()
> > in src/libes/gis/put_row.c
> > just contains G_warning() and not G_fatal_error().
> >
> > Are there objections to change this to
> > G_fatal_error("...unable to write row...")
> > ?
> >
> > It doesn't make much sense to continue writing to a full disk.
>
> Writes could theoretically fail for reasons other than a full disk,
> although I can't actually think of anything which would be
> recoverable.
>
> If you change write_error() to call G_fatal_error(), I suggest
> changing the calling functions to return "void" rather than a status
> value. That way, if anything was actually checking the return value
> and attempting recovery, you'll get compilation errors alerting you to
> the fact.
>
> In all probability, it should just call G_fatal_error(). If there are
> specific cases which actually want to handle the error, they can use
> G_set_error_routine().
>
> More generally, library functions which only rarely fail should just
> call G_fatal_error() IMHO, rather than returning an error status and
> thereby passing the responsibility to the individual modules.

If you change G_put_raster_row(), et al. to return void, then it isn't
very easy to tell where the error came from.

But how much code actually cares? How many programs actually check the
return value of G_put_raster_row() etc? And, of those, how many do
something other than just call G_fatal_error()?

Unless a significant number of programs actually check the status and
do something other than call G_fatal_error(), the library function may
as well call G_fatal_error() itself.

I thought folks wanted to get G_fatal_error() out of library
functions...

Which folks? Not me.

Either the library function handles the error itself, or a hundred
individual modules all have to handle the error. The former seems
preferable to me.

More generally, I'd like to push as much of the work as possible down
into the libraries, to make the coding of modules as simple as
possible.

In a similar vein, I'd like to be able to get rid of all of the
explicit calls to G_find_file(), and the need to pass the mapset
around separately. The vast majority of modules should be able to just
pass an abstract map name around; only the libraries would care
whether it was relative or fully qualified.

The main issue there is that we would have to either:

a) change the format of qualified map names to "big-endian", e.g.
"mapset/map" rather than "map@mapset", so that appending suffices to a
map name works correctly, or

b) provide a function for generating derived map names, and ensure
that modules used that rather than e.g. strcat().

Unfortunately, a) screws backward compatibility, while b) is error
prone (i.e. it requires that programmers actually use the defined
interface rather than strcat()).

Moving functionality down into the libraries not only simplifies
coding, but it can provide possibilities to extend the semantics
without having to rewrite lots of individual modules.

--
Glynn Clements <glynn.clements@virgin.net>

On Tue, 22 Oct 2002 18:25, Markus Neteler wrote:

Hi,

while having the problem that a disk run out of space
while using r.in.gdal, I found that

write_error()
in src/libes/gis/put_row.c
just contains G_warning() and not G_fatal_error().

Are there objections to change this to
G_fatal_error("...unable to write row...")
?

It doesn't make much sense to continue writing to a full disk.

BUT, you can't clean up after G_fatal_error.

If you run out of disk space the first thing you want to do is delete
temporary raster files. If you call G_fatal_error the temporary file is
left in place, aggrevating the problem.

(Did I mention I had problems with a script that had a faulty region
setting and the whole thing failed because s.to.rast called
G_fatal_error when it failed to write a row and left a 2GB file in the
.tmp directory. After a few attempts at this my disk was full and the
script was failing because there wasn't any disk space.)

Regards
Gordon

--

Gordon Keith
Programmer/Data Analyst
Marine Acoustics
CSIRO Marine Research
http://www.marine.csiro.au

The main thing is to keep the main thing the main thing.

Gordon Keith wrote:

> while having the problem that a disk run out of space
> while using r.in.gdal, I found that
>
> write_error()
> in src/libes/gis/put_row.c
> just contains G_warning() and not G_fatal_error().
>
> Are there objections to change this to
> G_fatal_error("...unable to write row...")
> ?
>
> It doesn't make much sense to continue writing to a full disk.

BUT, you can't clean up after G_fatal_error.

You can install a handler with G_set_error_routine(). If the handler
returns, then exit() will be called; however, you can use
setjmp/longmp to return control to the application.

If you run out of disk space the first thing you want to do is delete
temporary raster files. If you call G_fatal_error the temporary file is
left in place, aggrevating the problem.

Then handle fatal errors. Or, where possible, delete the file as soon
as it has been opened.

However, G_fatal_error() should probably try harder to clean up;
although we would probably need e.g. G_really_fatal_error() for
situations which are so bad that cleanup should not be attempted (if
memory is corrupted, you don't want to do anything dangerous like
deleting files, in case the filenames have been corrupted).

--
Glynn Clements <glynn.clements@virgin.net>

On Tue, Oct 22, 2002 at 10:48:13PM +0100, Glynn Clements wrote:

> I thought folks wanted to get G_fatal_error() out of library
> functions...

Which folks? Not me.

Either the library function handles the error itself, or a hundred
individual modules all have to handle the error. The former seems
preferable to me.

I thought one of the reasons we wanted abort()/exit() type function
calls removed from library functions is that they really interfere
with any future possibility of using libgis, et al. in long lived
programs (like GUI's). I'm fairly certain I didn't invent the idea :wink:

More generally, I'd like to push as much of the work as possible down
into the libraries, to make the coding of modules as simple as
possible.

Well, here we don't disagree.

In a similar vein, I'd like to be able to get rid of all of the
explicit calls to G_find_file(), and the need to pass the mapset
around separately. The vast majority of modules should be able to just
pass an abstract map name around; only the libraries would care
whether it was relative or fully qualified.

Yes, just G_open_<thing>(const char *path) returns <thing>_t, and if
the function can't find it, well that's the way it goes. Unfortunately,
all modules are too close to the implementation details...

The main issue there is that we would have to either:

a) change the format of qualified map names to "big-endian", e.g.
"mapset/map" rather than "map@mapset", so that appending suffices to a
map name works correctly, or

b) provide a function for generating derived map names, and ensure
that modules used that rather than e.g. strcat().

Unfortunately, a) screws backward compatibility, while b) is error
prone (i.e. it requires that programmers actually use the defined
interface rather than strcat()).

Well, I never liked the <name>@<mapset> thing. I don't think it worked
out as well as its designers envisoned. I'd still rather see:

<mapset>/<thing>/<name>/

with all the stuff for the "thing" named "name" under the "name"
directory. Then again, possibly even get rid of "thing" and just
discern the type of "thing" by the contents of the directory...
Anyway, I think it should map to the filesystem in a easily
understood manner for the user...

Then we can talk about tiled rasters....

--
static const char signature =
  "Copyright (c) 2002 Eric G. Miller <egm2@jps.net>";

Eric G. Miller wrote:

> > I thought folks wanted to get G_fatal_error() out of library
> > functions...
>
> Which folks? Not me.
>
> Either the library function handles the error itself, or a hundred
> individual modules all have to handle the error. The former seems
> preferable to me.

I thought one of the reasons we wanted abort()/exit() type function
calls removed from library functions is that they really interfere
with any future possibility of using libgis, et al. in long lived
programs (like GUI's). I'm fairly certain I didn't invent the idea :wink:

OK. G_fatal_error() doesn't have to terminate the program; perhaps we
should use something with a different name. It's fatal in the sense
that it doesn't return to the caller.

I do see the point regarding long-lived programs. Real exceptions
would be nice, but we ought to be able to provide an adequate
simulation with a stack of error handlers and setjmp/longmp.

Or have G_maybe_fatal_error() for library functions. The code would be
written to allow for this function returning, but it would actually
call G_fatal_error() unless the program had called e.g.
G_disable_fatal_errors(). IOW, programs which explicitly ask for
status returns get them, otherwise errors are "fatal".

I still think that ACID commit/rollback would be a good idea. It
wouldn't be massively hard to implement, assuming that we're dealing
with whole maps (i.e. you can't have one user updating the cell data
while another is updating the colour table).

> In a similar vein, I'd like to be able to get rid of all of the
> explicit calls to G_find_file(), and the need to pass the mapset
> around separately. The vast majority of modules should be able to just
> pass an abstract map name around; only the libraries would care
> whether it was relative or fully qualified.

Yes, just G_open_<thing>(const char *path) returns <thing>_t, and if
the function can't find it, well that's the way it goes. Unfortunately,
all modules are too close to the implementation details...

However, much of it is boilerplate; AFAICT, most modules only deal
with mapsets because the API forces them to.

> The main issue there is that we would have to either:
>
> a) change the format of qualified map names to "big-endian", e.g.
> "mapset/map" rather than "map@mapset", so that appending suffices to a
> map name works correctly, or
>
> b) provide a function for generating derived map names, and ensure
> that modules used that rather than e.g. strcat().
>
> Unfortunately, a) screws backward compatibility, while b) is error
> prone (i.e. it requires that programmers actually use the defined
> interface rather than strcat()).

Well, I never liked the <name>@<mapset> thing. I don't think it worked
out as well as its designers envisoned. I'd still rather see:

<mapset>/<thing>/<name>/

with all the stuff for the "thing" named "name" under the "name"
directory. Then again, possibly even get rid of "thing" and just
discern the type of "thing" by the contents of the directory...
Anyway, I think it should map to the filesystem in a easily
understood manner for the user...

The main issue with the "thing" part is whether we think that being
able to have both a vector map and a raster map with the same name is
a good idea or not. Personally, I think not.

--
Glynn Clements <glynn.clements@virgin.net>

"Markus" == Markus Neteler <neteler@itc.it> writes:

Markus> Hi, while having the problem that a disk run out of space
Markus> while using r.in.gdal, I found that

Markus> write_error() in src/libes/gis/put_row.c just contains
Markus> G_warning() and not G_fatal_error().

I know this may seem trivial, but why does grass use "libes" instead
of the more common "lib"? It seems gratuitously different. Is there
a reason for the difference? It "bothers" me aesthetically.

--
Russell Senior ``I've seen every kind of critter God ever made,
seniorr@aracnet.com and I ain't never seen a meaner, lower, more
                         stinkin' yellow hypocrite than you!''
                                        -- Burl Ives as Rufus Hennessy

On Wed, Oct 23, 2002 at 01:36:50AM -0700, Russell Senior wrote:

>>>>> "Markus" == Markus Neteler <neteler@itc.it> writes:

Markus> Hi, while having the problem that a disk run out of space
Markus> while using r.in.gdal, I found that

Markus> write_error() in src/libes/gis/put_row.c just contains
Markus> G_warning() and not G_fatal_error().

I know this may seem trivial, but why does grass use "libes" instead
of the more common "lib"? It seems gratuitously different. Is there
a reason for the difference? It "bothers" me aesthetically.

... enjoy the new GRASS 5.1: There the directory is called 'lib/':

http://freegis.org/cgi-bin/viewcvs.cgi/grass51/

The decision to use 'libes' within GRASS 5.0 was taken in mid 80th (AFAIK).

Cheers

Markus

Discussion about running GRASS on parallel computers arise
from time to time. For those interested, I found an article
that may be of interest :

Scientific Computing Using POOMA. in C/C++ Users Journal,
November 2002.

POOMA stands for Parallel Object-Oriented Methods and Aplication
and it is a toolkit developped by Los Alamos National Laboratory.

A summary is :

POOMA is a high-performance C++ toolkit for parallel scientific
computation. POOMA's object-oriented design facilitates rapid
application development. POOMA has been optimized to take full
advantage of massively parallel machines. POOMA is available
free ofcharge in order to facilitate its use in both industrial
and researchenvironments.

Two WEB sites :

http://www.acl.lanl.gov/pooma/index.html

http://www.codesourcery.com/pooma/pooma

A manual is avalaible at

http://www.codesourcery.com/pooma/pooma_manual

The only drawback is that it uses C++.

--
Robert Lagacé, professeur
Directeur du programme de génie agroenvironnemental
Pavillon Comtois
Université Laval
Ste-Foy, Québec, G1K 7P4
tel : (418)-656-2131#2276
Fax : (418)-656-3723
E-mail : lagace@grr.ulaval.ca