From 653870dd035c76e2cf592cfcb768e95b72936c9d Mon Sep 17 00:00:00 2001 From: Vailin Choi Date: Fri, 1 Apr 2016 17:39:46 -0500 Subject: [svn-r29606] Fix for shared file pointer HDFFV-9469. This is the same fix for revise_chunks (#28908). Tested on jam, platypus, emu, kite, moohan, ostrich, osx1010test, quail. --- src/H5Dio.c | 6 +++ src/H5T.c | 28 +++++++++++ test/tfile.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 192 insertions(+) diff --git a/src/H5Dio.c b/src/H5Dio.c index 5a931cf..58031e8 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -420,6 +420,9 @@ H5D__read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, if(H5D__get_dxpl_cache(dxpl_id, &dxpl_cache) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't fill dxpl cache") + /* Patch the top level file pointer for dt->shared->u.vlen.f if needed */ + H5T_patch_vlen_file(dataset->shared->type, dataset->oloc.file); + /* Set up datatype info for operation */ if(H5D__typeinfo_init(dataset, dxpl_cache, dxpl_id, mem_type_id, FALSE, &type_info) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set up type info") @@ -640,6 +643,9 @@ H5D__write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, if(H5D__get_dxpl_cache(dxpl_id, &dxpl_cache) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't fill dxpl cache") + /* Patch the top level file pointer for dt->shared->u.vlen.f if needed */ + H5T_patch_vlen_file(dataset->shared->type, dataset->oloc.file); + /* Set up datatype info for operation */ if(H5D__typeinfo_init(dataset, dxpl_cache, dxpl_id, mem_type_id, TRUE, &type_info) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set up type info") diff --git a/src/H5T.c b/src/H5T.c index 29d8f40..9673ee9 100644 --- a/src/H5T.c +++ b/src/H5T.c @@ -5452,3 +5452,31 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5T_patch_file() */ + +/*------------------------------------------------------------------------- + * Function: H5T_patch_vlen_file + * + * Purpose: Patch the top-level file pointer contained in (dt->shared->u.vlen.f) + * to point to f. This is possible because + * the top-level file pointer can be closed out from under + * dt while dt is contained in the shared file's cache. + * + * Return: SUCCEED + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_patch_vlen_file(H5T_t *dt, H5F_t *f) +{ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* Sanity check */ + HDassert(dt); + HDassert(dt->shared); + HDassert(f); + + if((dt->shared->type == H5T_VLEN) && dt->shared->u.vlen.f != f) + dt->shared->u.vlen.f = f; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5T_patch_vlen_file() */ diff --git a/test/tfile.c b/test/tfile.c index 2e24791..784e4ad 100644 --- a/test/tfile.c +++ b/test/tfile.c @@ -74,6 +74,7 @@ #define DSET_NAME "dataset" #define ATTR_NAME "attr" #define TYPE_NAME "type" +#define DSET_VL "vlinteger" #define FILE4 "tfile4.h5" #define OBJ_ID_COUNT_0 0 @@ -2073,6 +2074,162 @@ test_file_double_dataset_open(void) /**************************************************************** ** +** test_open2x_vlen(): +** This is the helper routine used by test_open2x_vlen(). +** This is modified based on the customer's test program. +** (HDFFV-9469): +** --read from the specified dataset +** +*****************************************************************/ +static void +CheckRead(hid_t did) +{ + hid_t mtid = -1; + hid_t sid = -1; + hvl_t *read = NULL; + herr_t ret; + int ndims; + hsize_t dims[1]={1}; + + mtid = H5Tvlen_create(H5T_NATIVE_INT64); + CHECK(mtid, FAIL, "H5Tvlen_create"); + + sid = H5Dget_space(did); + CHECK(sid, FAIL, "H5Dget_space"); + + ndims = H5Sget_simple_extent_dims(sid, dims, NULL); + CHECK(ndims, FAIL, "H5Sget_simple_extent_dims"); + + read = (hvl_t *) HDmalloc (dims[0] * sizeof (hvl_t)); + CHECK_PTR(read, "HDmalloc"); + + ret = H5Dread(did, mtid, H5S_ALL, H5S_ALL, H5P_DEFAULT, read); + CHECK(ret, FAIL, "H5Dread"); + + ret = H5Dvlen_reclaim(mtid, sid, H5P_DEFAULT, read); + CHECK(ret, FAIL, "H5Dvlen_reclaim"); + + HDfree(read); + + ret = H5Tclose(mtid); + CHECK(ret, FAIL, "H5Tclose"); + + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); +} /* CheckRead */ + +/**************************************************************** +** +** test_open2x_vlen(): +** This test is modified based on the customer's test program. +** (HDFFV-9469): +** --open a file and a dataset with variable length type twice +** --close both opens of the file +** --close the dataset from first open +** --verify that reading from the dataset (second open) is successful +** +*****************************************************************/ +static void +test_open2x_vlen(void) +{ + hid_t fid1 = -1, fid2 = -1; + hid_t did1 = -1, did2 = -1; + hid_t sid = -1; + hid_t ftid = -1; + hid_t mtid = -1; + hsize_t dims[1] = { 1 }; + int64_t integers[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + hvl_t written; + herr_t ret; /* Generic return value */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing open file and variable length dataset twice and closing 1 dataset\n")); + + /* Setting up the test file */ + + written.p = integers; + written.len = 10; + + fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid1, FAIL, "H5Fcreate"); + + /* Create a variable-length type */ + ftid = H5Tvlen_create(H5T_STD_I64LE); + CHECK(ftid, FAIL, "H5Tvlen_create"); + mtid = H5Tvlen_create(H5T_NATIVE_INT64); + CHECK(mtid, FAIL, "H5Tvlen_create"); + + /* Create the dataset */ + sid = H5Screate_simple(1, dims, dims); + CHECK(sid, FAIL, "H5Screate_simple"); + + did1 = H5Dcreate2(fid1, DSET_VL, ftid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(did1, FAIL, "H5Dcreate"); + + /* Write to the dataset */ + ret = H5Dwrite(did1, mtid, H5S_ALL, H5S_ALL, H5P_DEFAULT, &written); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Close the dataset */ + ret = H5Dclose(did1); + CHECK(ret, FAIL, "H5Dclose"); + + ret = H5Tclose(mtid); + CHECK(ret, FAIL, "H5Tclose"); + ret = H5Tclose(ftid); + CHECK(ret, FAIL, "H5Tclose"); + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close the file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + + /* First open of the file */ + fid1 = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); + CHECK(fid1, FAIL, "H5Fopen"); + + /* First open of the dataset */ + did1 = H5Dopen2(fid1, DSET_VL, H5P_DEFAULT); + CHECK(did1, FAIL, "H5Dopen"); + + /* Close the file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + /* Second open of the file */ + fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); + CHECK(fid2, FAIL, "H5Fopen"); + + /* Second open of the dataset */ + did2 = H5Dopen2(fid2, DSET_VL, H5P_DEFAULT); + CHECK(did2, FAIL, "H5Dopen"); + + /* Close the file */ + ret = H5Fclose(fid2); + CHECK(ret, FAIL, "H5Fclose"); + + /* Read from the dataset (first open) */ + CheckRead(did1); + /* Read from the dataset (second open) */ + CheckRead(did2); + + /* Close the dataset from first open */ + ret = H5Dclose(did1); + CHECK(ret, FAIL, "H5Dclose"); + + /* Read from the dataset (second open) */ + CheckRead(did2); + + /* Close the dataset from second open */ + ret = H5Dclose(did2); + CHECK(ret, FAIL, "H5Dclose"); + +} /* end test_open2x_vlen() */ + +/**************************************************************** +** ** test_file_double_datatype_open(): low-level file test routine. ** This test checks whether opening the same named datatype from two ** different files works correctly. @@ -2963,6 +3120,7 @@ test_file(void) test_file_double_group_open(); /* Test opening same group from two files works properly */ test_file_double_dataset_open(); /* Test opening same dataset from two files works properly */ test_file_double_datatype_open(); /* Test opening same named datatype from two files works properly */ + test_open2x_vlen(); /* Test opening file and variable length dataset twice and closing 1 dataset */ test_userblock_file_size(); /* Tests that files created with a userblock have the correct size */ test_cached_stab_info(); /* Tests that files are created with cached stab info in the superblock */ test_rw_noupdate(); /* Test to ensure that RW permissions don't write the file unless dirtied */ -- cgit v0.12