htrdr

Solving radiative transfer in heterogeneous media
git clone git://git.meso-star.fr/htrdr.git
Log | Files | Refs | README | LICENSE

commit 55d19477d5b6c54e505c1da7eb13d38d1606b630
parent 2ecfccbc66376507399baf8e67446d01afa322d9
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Fri, 28 Sep 2018 15:17:59 +0200

Fix the update of the file stamps

The stamp of a given file was updated on the invocation of the
"is_file_updated" function. This function do not update the file stamp
anymore. One have to explicitly call the "update_file_stamp" function to
update the stamp of a given file.

The stamps of the HTCP, HTGOP and HTMIE files are now updated *after*
the generation of the "cloud grids" in order to avoid unforeseen
behaviors. If the htrdr process was killed during the generation
of the grids, the next invocation of the htrdr program might skip the
generation of some grids built from outdated HTCP/HTGOP/HTMIE
files.

Diffstat:
Msrc/htrdr.c | 182+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
Msrc/htrdr_c.h | 5+++++
Msrc/htrdr_sky.c | 14++++++++++++++
3 files changed, 147 insertions(+), 54 deletions(-)

diff --git a/src/htrdr.c b/src/htrdr.c @@ -189,6 +189,76 @@ error: goto exit; } +static res_T +open_file_stamp + (struct htrdr* htrdr, + const char* filename, + struct stat* out_stat, /* Stat of the submitted filename */ + int* out_fd, /* Descriptor of the opened file. Must be closed by the caller */ + struct str* stamp_filename) +{ + struct stat statbuf; + struct str str; + int err; + int fd = -1; + res_T res = RES_OK; + ASSERT(htrdr && filename && out_fd && out_stat && stamp_filename); + + str_init(htrdr->allocator, &str); + + err = stat(filename, &statbuf); + if(err) { + htrdr_log_err(htrdr, "%s: could not stat the file -- %s.\n", + filename, strerror(errno)); + res = RES_IO_ERR; + goto error; + } + + if(!S_ISREG(statbuf.st_mode)) { + htrdr_log_err(htrdr, "%s: not a regular file.\n", filename); + res = RES_IO_ERR; + goto error; + } + + res = create_directory(htrdr, ".htrdr/"); + if(res != RES_OK) goto error; + + #define CHK_STR(Func, ErrMsg) { \ + res = str_##Func; \ + if(res != RES_OK) { \ + htrdr_log_err(htrdr, "%s: "ErrMsg"\n", filename); \ + goto error; \ + } \ + } (void)0 + CHK_STR(set(&str, filename), "could not copy the filename"); + CHK_STR(set(&str, basename(str_get(&str))), "could not setup the basename"); + CHK_STR(insert(&str, 0, ".htrdr/"), "could not setup the stamp directory"); + CHK_STR(append(&str, ".stamp"), "could not setup the stamp extension"); + #undef CHK_STR + + fd = open(str_cget(&str), O_CREAT|O_RDWR, S_IRUSR|S_IWUSR); + if(fd < 0) { + htrdr_log_err(htrdr, "%s: could not open/create the file -- %s.\n", + str_cget(&str), strerror(errno)); + res = RES_IO_ERR; + goto error; + } + + CHK(str_copy_and_clear(stamp_filename, &str) == RES_OK); + +exit: + str_release(&str); + *out_fd = fd; + *out_stat = statbuf; + return res; +error: + if(fd >= 0) { + CHK(close(fd) == 0); + fd = -1; + } + goto exit; +} + /******************************************************************************* * Local functions ******************************************************************************/ @@ -402,7 +472,7 @@ htrdr_log_warn(struct htrdr* htrdr, const char* msg, ...) /******************************************************************************* * Local functions ******************************************************************************/ -extern LOCAL_SYM res_T +extern LOCAL_SYM res_T open_output_stream (struct htrdr* htrdr, const char* filename, @@ -460,90 +530,94 @@ error: res_T is_file_updated(struct htrdr* htrdr, const char* filename, int* out_upd) { - struct str str; + struct str stamp_filename; struct stat statbuf; ssize_t n; off_t size; struct timespec mtime; int fd = -1; - int err; int upd = 1; res_T res = RES_OK; ASSERT(htrdr && filename && out_upd); - str_init(htrdr->allocator, &str); + str_init(htrdr->allocator, &stamp_filename); - err = stat(filename, &statbuf); - if(err) { - htrdr_log_err(htrdr, "%s: could not stat the file -- %s.\n", - filename, strerror(errno)); + res = open_file_stamp(htrdr, filename, &statbuf, &fd, &stamp_filename); + if(res != RES_OK) goto error; + + n = read(fd, &mtime, sizeof(mtime)); + if(n < 0) { + htrdr_log_err(htrdr, "%s: could not read the `mtime' data -- %s.\n", + str_cget(&stamp_filename), strerror(errno)); res = RES_IO_ERR; goto error; } - if(!S_ISREG(statbuf.st_mode)) { - htrdr_log_err(htrdr, "%s: not a regular file.\n", filename); - res = RES_IO_ERR; - goto error; + upd = (size_t)n != sizeof(mtime) + ||mtime.tv_nsec != statbuf.st_mtim.tv_nsec + ||mtime.tv_sec != statbuf.st_mtim.tv_sec; + + if(!upd) { + n = read(fd, &size, sizeof(size)); + if(n < 0) { + htrdr_log_err(htrdr, "%s: could not read the `size' data -- %s.\n", + str_cget(&stamp_filename), strerror(errno)); + res = RES_IO_ERR; + goto error; + } + upd = (size_t)n != sizeof(size) || statbuf.st_size != size; } - res = create_directory(htrdr, ".htrdr/"); - if(res != RES_OK) goto error; +exit: + *out_upd = upd; + str_release(&stamp_filename); + if(fd >= 0) CHK(close(fd) == 0); + return res; +error: + goto exit; +} - #define CHK_STR(Func, ErrMsg) { \ - res = str_##Func; \ - if(res != RES_OK) { \ - htrdr_log_err(htrdr, "%s: "ErrMsg"\n", filename); \ - goto error; \ - } \ - } (void)0 - CHK_STR(set(&str, filename), "could not copy the filename"); - CHK_STR(set(&str, basename(str_get(&str))), "could not setup the basename"); - CHK_STR(insert(&str, 0, ".htrdr/"), "could not setup the stamp directory"); - CHK_STR(append(&str, ".stamp"), "could not setup the stamp extension"); - #undef CHK_STR + +res_T +update_file_stamp(struct htrdr* htrdr, const char* filename) +{ + struct str stamp_filename; + struct stat statbuf; + int fd = -1; + ssize_t n; + res_T res = RES_OK; + ASSERT(htrdr && filename); + + str_init(htrdr->allocator, &stamp_filename); + + res = open_file_stamp(htrdr, filename, &statbuf, &fd, &stamp_filename); + if(res != RES_OK) goto error; #define CHK_IO(Func, ErrMsg) { \ if((Func) < 0) { \ htrdr_log_err(htrdr, "%s: "ErrMsg" -- %s.\n", \ - str_cget(&str), strerror(errno)); \ + str_cget(&stamp_filename), strerror(errno)); \ res = RES_IO_ERR; \ goto error; \ } \ } (void) 0 - fd = open(str_cget(&str), O_CREAT|O_RDWR, S_IRUSR|S_IWUSR); - CHK_IO(fd, "could not open/create the file"); - - CHK_IO(n = read(fd, &mtime, sizeof(mtime)), "could not read the `mtime' data"); + CHK_IO(lseek(fd, 0, SEEK_SET), "could not rewind the file descriptor"); - upd = (size_t)n != sizeof(mtime) - ||mtime.tv_nsec != statbuf.st_mtim.tv_nsec - ||mtime.tv_sec != statbuf.st_mtim.tv_sec; + /* NOTE: Ignore n >=0 but != sizeof(DATA). In such case stamp is currupted + * and on the next invocation on the same filename, this function will + * return 1 */ + n = write(fd, &statbuf.st_mtim, sizeof(statbuf.st_mtim)); + CHK_IO(n, "could not update the `mtime' data"); + n = write(fd, &statbuf.st_size, sizeof(statbuf.st_size)); + CHK_IO(n, "could not update the `size' data"); - if(!upd) { - CHK_IO(n = read(fd, &size, sizeof(size)), "could not read the `size' data"); - upd = (size_t)n != sizeof(size) || statbuf.st_size != size; - } - - if(upd) { - CHK_IO(lseek(fd, 0, SEEK_SET), "could not rewind the file descriptor"); - - /* NOTE: Ignore n >=0 but != sizeof(DATA). In such case stamp is currupted - * and on the next invocation on the same filename, this function will - * return 1 */ - n = write(fd, &statbuf.st_mtim, sizeof(statbuf.st_mtim)); - CHK_IO(n, "could not update the `mtime' data"); - n = write(fd, &statbuf.st_size, sizeof(statbuf.st_size)); - CHK_IO(n, "could not update the `size' data"); - - CHK_IO(fsync(fd), "could not sync the file with storage device"); - } + CHK_IO(fsync(fd), "could not sync the file with storage device"); #undef CHK_IO + exit: - *out_upd = upd; - str_release(&str); + str_release(&stamp_filename); if(fd >= 0) CHK(close(fd) == 0); return res; error: diff --git a/src/htrdr_c.h b/src/htrdr_c.h @@ -91,6 +91,11 @@ is_file_updated int* is_upd); extern LOCAL_SYM res_T +update_file_stamp + (struct htrdr* htrdr, + const char* filename); + +extern LOCAL_SYM res_T create_directory (struct htrdr* htrdt, const char* path); diff --git a/src/htrdr_sky.c b/src/htrdr_sky.c @@ -1494,6 +1494,20 @@ htrdr_sky_create time_dump(&t0, TIME_ALL, NULL, buf, sizeof(buf)); htrdr_log(htrdr, "Setup clouds in %s\n", buf); + /* Update the file stamps */ + if(htcp_upd) { + res = update_file_stamp(sky->htrdr, htcp_filename); + if(res != RES_OK) goto error; + } + if(htmie_upd) { + res = update_file_stamp(sky->htrdr, htmie_filename); + if(res != RES_OK) goto error; + } + if(htgop_upd) { + res = update_file_stamp(sky->htrdr, htgop_filename); + if(res != RES_OK) goto error; + } + time_current(&t0); res = setup_atmosphere(sky, optical_thickness_threshold); if(res != RES_OK) goto error;