From f877f94c13de1df96866aa420496f2c0a9fab60d Mon Sep 17 00:00:00 2001 From: Raymond Lu Date: Mon, 5 Nov 2007 17:13:43 -0500 Subject: [svn-r14238] Bug fix: It's reported by the CGNS people. When an external link was opened twice, the library had some trouble to close in the end. The problem came from the field "holding_file" of H5O_loc_t. It's used to indicate special links like external links. The fix is to turn it off whenever H5O_open is called. Later the caller function should turn it on when it needs to. Tested on kagiso, linew, and smirom. --- configure | 2 +- src/H5A.c | 6 ++-- src/H5L.c | 3 +- src/H5O.c | 14 ++++++-- src/H5Oprivate.h | 2 +- test/external.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++ test/extlink_file.h5 | Bin 0 -> 2864 bytes 7 files changed, 109 insertions(+), 11 deletions(-) create mode 100644 test/extlink_file.h5 diff --git a/configure b/configure index 5a6a27f..c77aece 100755 --- a/configure +++ b/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Id: configure.in 14213 2007-10-21 22:11:17Z epourmal . +# From configure.in Id: configure.in 14215 2007-10-21 22:18:13Z epourmal . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for HDF5 1.8.0-beta4post1. # diff --git a/src/H5A.c b/src/H5A.c index 4a09fde..8e464af 100644 --- a/src/H5A.c +++ b/src/H5A.c @@ -223,8 +223,7 @@ H5Acreate2(hid_t loc_id, const char *attr_name, hid_t type_id, hid_t space_id, hid_t ret_value; /* Return value */ FUNC_ENTER_API(H5Acreate2, FAIL) - H5TRACE6("i", "i*siiii", loc_id, attr_name, type_id, space_id, - acpl_id, aapl_id); + H5TRACE6("i", "i*siiii", loc_id, attr_name, type_id, space_id, acpl_id, aapl_id); /* check arguments */ if(H5I_ATTR == H5I_get_type(loc_id)) @@ -1869,8 +1868,7 @@ H5Aiterate2(hid_t loc_id, H5_index_t idx_type, H5_iter_order_t order, herr_t ret_value; /* Return value */ FUNC_ENTER_API(H5Aiterate2, FAIL) - H5TRACE6("e", "iIiIo*hx*x", loc_id, idx_type, order, idx, op, - op_data); + H5TRACE6("e", "iIiIo*hx*x", loc_id, idx_type, order, idx, op, op_data); /* check arguments */ if(H5I_ATTR == H5I_get_type(loc_id)) diff --git a/src/H5L.c b/src/H5L.c index 78a78f2..020f7c2 100644 --- a/src/H5L.c +++ b/src/H5L.c @@ -1152,8 +1152,7 @@ H5Literate(hid_t grp_id, H5_index_t idx_type, H5_iter_order_t order, herr_t ret_value; /* Return value */ FUNC_ENTER_API(H5Literate, FAIL) - H5TRACE6("e", "iIiIo*hx*x", grp_id, idx_type, order, idx_p, op, - op_data); + H5TRACE6("e", "iIiIo*hx*x", grp_id, idx_type, order, idx_p, op, op_data); /* Check arguments */ id_type = H5I_get_type(grp_id); diff --git a/src/H5O.c b/src/H5O.c index 15cafc5..94435f5 100644 --- a/src/H5O.c +++ b/src/H5O.c @@ -1051,10 +1051,15 @@ done: * Programmer: Robb Matzke * Monday, January 5, 1998 * + * Modification: + * Raymond Lu + * 5 November 2007 + * Turn off the holding file variable if it's on. When it's + * needed, the caller will turn it on again. *------------------------------------------------------------------------- */ herr_t -H5O_open(const H5O_loc_t *loc) +H5O_open(H5O_loc_t *loc) { herr_t ret_value = SUCCEED; /* Return value */ @@ -1069,8 +1074,11 @@ H5O_open(const H5O_loc_t *loc) HDfprintf(H5DEBUG(O), "> %a\n", loc->addr); #endif - /* Increment open-lock counters */ - loc->file->nopen_objs++; + /* Turn off the variable for holding file or increment open-lock counters */ + if(loc->holding_file) + loc->holding_file = FALSE; + else + loc->file->nopen_objs++; done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 06c5ebf..31738a9 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -533,7 +533,7 @@ struct H5P_genplist_t; H5_DLL herr_t H5O_init(void); H5_DLL herr_t H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, hid_t ocpl_id, H5O_loc_t *loc/*out*/); -H5_DLL herr_t H5O_open(const H5O_loc_t *loc); +H5_DLL herr_t H5O_open(H5O_loc_t *loc); H5_DLL herr_t H5O_close(H5O_loc_t *loc); H5_DLL int H5O_link(const H5O_loc_t *loc, int adjust, hid_t dxpl_id); H5_DLL struct H5O_t *H5O_protect(H5O_loc_t *loc, hid_t dxpl_id); diff --git a/test/external.c b/test/external.c index 44e586d..59e6be8 100644 --- a/test/external.c +++ b/test/external.c @@ -21,10 +21,13 @@ */ #include "h5test.h" +#define LINKED_FILE "extlink_file.h5" + const char *FILENAME[] = { "extern_1", "extern_2", "extern_3", + "extern_4", NULL }; @@ -814,6 +817,95 @@ test_3 (hid_t fapl) /*------------------------------------------------------------------------- + * Function: test_4 + * + * Purpose: Tests opening an external link twice. It exposed a bug + * in the library. This function tests the fix. + * + * Return: Success: 0 + * + * Failure: number of errors + * + * Programmer: Raymond Lu + * 5 November 2007 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +test_4 (hid_t fapl) +{ + hid_t fid, gid, xid, xid2; + char filename[1024]; /*file name */ + char pathname[1024]; + char linked_pathname[1024]; + char *srcdir = getenv("srcdir"); /*where the src code is located*/ + + TESTING("opening external link twice"); + + h5_fixname(FILENAME[3], fapl, filename, sizeof filename); + + if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + goto error; + + if((gid = H5Gopen(fid, "/", H5P_DEFAULT)) < 0) + goto error; + + pathname[0] = '\0'; + /* Generate correct name for test file by prepending the source path */ + if(srcdir && ((HDstrlen(srcdir) + HDstrlen(LINKED_FILE) + 1) < sizeof(pathname))) { + HDstrcpy(pathname, srcdir); + HDstrcat(pathname, "/"); + } + HDstrcat(pathname, LINKED_FILE); + + /* Create an external link to an existing file*/ + if(H5Lcreate_external(pathname, "/group", gid, " link", H5P_DEFAULT, H5P_DEFAULT) < 0) + goto error; + + if(H5Gclose(gid) < 0) + goto error; + + if(H5Fclose(fid) < 0) + goto error; + + /* Reopen the file */ + if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + goto error; + + /* Open the external link */ + if((xid = H5Gopen(fid, "/ link", H5P_DEFAULT)) < 0) + goto error; + + /* Open the external link twice */ + if((xid2 = H5Gopen(xid, ".", H5P_DEFAULT)) < 0) + goto error; + + if(H5Gclose(xid2) < 0) + goto error; + + if(H5Gclose(xid) < 0) + goto error; + + if(H5Fclose(fid) < 0) + goto error; + + PASSED(); + return 0; + + error: + H5E_BEGIN_TRY { + H5Gclose(gid); + H5Gclose(xid); + H5Gclose(xid2); + H5Fclose(fid); + } H5E_END_TRY; + return 1; +} + + +/*------------------------------------------------------------------------- * Function: main * * Purpose: Runs external dataset tests. @@ -861,6 +953,7 @@ main (void) nerrors += test_1h(); nerrors += test_2(fapl); nerrors += test_3(fapl); + nerrors += test_4(fapl); if (nerrors>0) goto error; if (H5Fclose(file) < 0) goto error; diff --git a/test/extlink_file.h5 b/test/extlink_file.h5 new file mode 100644 index 0000000..92ed32c Binary files /dev/null and b/test/extlink_file.h5 differ -- cgit v0.12