From 805c29431c73880991e5823f2ba82bbeca02201e Mon Sep 17 00:00:00 2001 From: Vailin Choi Date: Sat, 26 Dec 2015 16:06:38 -0500 Subject: [svn-r28728] Fix for H5Drefresh() problem from DLS with multiple opens of a dataset. Fix for H5Ffstart_swmr_write() with multiple opens of files and datasets. Tested on jam, osx1010test, moohan, ostrich, emu, platypus, kite, quail. --- src/H5Dint.c | 135 +++++ src/H5Dprivate.h | 2 + src/H5F.c | 29 +- src/H5Gpublic.h | 4 +- src/H5Oflush.c | 32 +- src/H5Oprivate.h | 2 +- test/swmr.c | 1664 ++++++++++++++++++++++++++++++++++++++++++++++++------ 7 files changed, 1668 insertions(+), 200 deletions(-) diff --git a/src/H5Dint.c b/src/H5Dint.c index 8073d9d..ed0e63e 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -1940,6 +1940,141 @@ done: /*------------------------------------------------------------------------- + * Function: H5D_mult_refresh_close + * + * Purpose: Closing down the needed information when the dataset has + * multiple opens. (From H5O_refresh_metadata_close()) + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi; 12/24/15 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D_mult_refresh_close(hid_t dset_id, hid_t dxpl_id) +{ + H5D_t *dataset; /* Dataset to refresh */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_NOAPI(FAIL) + + if(NULL == (dataset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") + + /* check args */ + HDassert(dataset && dataset->oloc.file && dataset->shared); + HDassert(dataset->shared->fo_count > 0); + + if(dataset->shared->fo_count > 1) { + /* Free cached information for each kind of dataset */ + switch(dataset->shared->layout.type) { + case H5D_CONTIGUOUS: + /* Free the data sieve buffer, if it's been allocated */ + if(dataset->shared->cache.contig.sieve_buf) + dataset->shared->cache.contig.sieve_buf = (unsigned char *)H5FL_BLK_FREE(sieve_buf,dataset->shared->cache.contig.sieve_buf); + break; + + case H5D_CHUNKED: + /* Check for skip list for iterating over chunks during I/O to close */ + if(dataset->shared->cache.chunk.sel_chunks) { + HDassert(H5SL_count(dataset->shared->cache.chunk.sel_chunks) == 0); + H5SL_close(dataset->shared->cache.chunk.sel_chunks); + dataset->shared->cache.chunk.sel_chunks = NULL; + } /* end if */ + + /* Check for cached single chunk dataspace */ + if(dataset->shared->cache.chunk.single_space) { + (void)H5S_close(dataset->shared->cache.chunk.single_space); + dataset->shared->cache.chunk.single_space = NULL; + } /* end if */ + + /* Check for cached single element chunk info */ + if(dataset->shared->cache.chunk.single_chunk_info) { + dataset->shared->cache.chunk.single_chunk_info = H5FL_FREE(H5D_chunk_info_t, dataset->shared->cache.chunk.single_chunk_info); + dataset->shared->cache.chunk.single_chunk_info = NULL; + } /* end if */ + break; + + case H5D_COMPACT: + /* Nothing special to do (info freed in the layout destroy) */ + break; + + case H5D_VIRTUAL: + break; + + case H5D_LAYOUT_ERROR: + case H5D_NLAYOUTS: + default: + HDassert("not implemented yet" && 0); +#ifdef NDEBUG + HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unsupported storage layout") +#endif /* NDEBUG */ + } /* end switch */ /*lint !e788 All appropriate cases are covered */ + + /* Destroy any cached layout information for the dataset */ + if(dataset->shared->layout.ops->dest && (dataset->shared->layout.ops->dest)(dataset, dxpl_id) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "unable to destroy layout info") + + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_mult_refresh_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_mult_refresh_reopen + * + * Purpose: Re-initialize the needed info when the dataset has multiple + * opens. (From H5O_refresh_metadata_reopen()) + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi; 12/24/15 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D_mult_refresh_reopen(H5D_t *dataset, hid_t dxpl_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* check args */ + HDassert(dataset && dataset->oloc.file && dataset->shared); + HDassert(dataset->shared->fo_count > 0); + + if(dataset->shared->fo_count > 1) { + + /* Release dataspace info */ + if(H5S_close(dataset->shared->space) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "unable to release dataspace") + + /* Re-load dataspace info */ + if(NULL == (dataset->shared->space = H5S_read(&(dataset->oloc), dxpl_id))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to load dataspace info from dataset header") + + /* Cache the dataset's dataspace info */ + if(H5D__cache_dataspace_info(dataset) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't cache dataspace info") + + if(H5O_msg_reset(H5O_LAYOUT_ID, &dataset->shared->layout) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTRESET, NULL, "unable to reset layout info") + + /* Re-load layout message info */ + if(NULL == H5O_msg_read(&(dataset->oloc), H5O_LAYOUT_ID, &(dataset->shared->layout), dxpl_id)) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to read data layout message") + } + +done: + FUNC_LEAVE_NOAPI(ret_value) + +} /* H5D_mult_refresh_reopen() */ + + +/*------------------------------------------------------------------------- * Function: H5D_oloc * * Purpose: Returns a pointer to the object location for a dataset. diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h index cb04f2e..4c5f914 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -173,6 +173,8 @@ typedef struct H5D_append_flush_t { H5_DLL herr_t H5D_init(void); H5_DLL H5D_t *H5D_open(const H5G_loc_t *loc, hid_t dapl_id, hid_t dxpl_id); H5_DLL herr_t H5D_close(H5D_t *dataset); +H5_DLL herr_t H5D_mult_refresh_close(hid_t dset_id, hid_t dxpl_id); +H5_DLL herr_t H5D_mult_refresh_reopen(H5D_t *dataset, hid_t dxpl_id); H5_DLL H5O_loc_t *H5D_oloc(H5D_t *dataset); H5_DLL H5G_name_t *H5D_nameof(H5D_t *dataset); H5_DLL H5T_t *H5D_typeof(const H5D_t *dset); diff --git a/src/H5F.c b/src/H5F.c index 09765cb..948eb7a 100644 --- a/src/H5F.c +++ b/src/H5F.c @@ -760,13 +760,6 @@ H5Fclose(hid_t file_id) if((nref = H5I_get_ref(file_id, FALSE)) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get ID ref count") if(nref == 1) { - if(f->shared->sblock) { /* Clear status_flags */ - f->shared->sblock->status_flags &= ~H5F_SUPER_WRITE_ACCESS; - f->shared->sblock->status_flags &= ~H5F_SUPER_SWMR_WRITE_ACCESS; - /* Mark superblock dirty in cache, so change will get encoded */ - if(H5F_super_dirty(f) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTMARKDIRTY, FAIL, "unable to mark superblock as dirty") - } if(H5F_flush(f, H5AC_dxpl_id, FALSE) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache") } @@ -1640,13 +1633,13 @@ H5Fstart_swmr_write(hid_t file_id) HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file's cached information") /* Get the # of opened named datatypes and attributes */ - if(H5F_get_obj_count(file, H5F_OBJ_LOCAL|H5F_OBJ_DATATYPE|H5F_OBJ_ATTR, FALSE, &nt_attr_count) < 0) + if(H5F_get_obj_count(file, H5F_OBJ_DATATYPE|H5F_OBJ_ATTR, FALSE, &nt_attr_count) < 0) HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_obj_count failed") if(nt_attr_count) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "named datatypes and/or attributes opened in the file") /* Get the # of opened datasets and groups */ - if(H5F_get_obj_count(file, H5F_OBJ_LOCAL|H5F_OBJ_GROUP|H5F_OBJ_DATASET, FALSE, &grp_dset_count) < 0) + if(H5F_get_obj_count(file, H5F_OBJ_GROUP|H5F_OBJ_DATASET, FALSE, &grp_dset_count) < 0) HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_obj_count failed") if(grp_dset_count) { @@ -1661,13 +1654,13 @@ H5Fstart_swmr_write(hid_t file_id) HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate buffer for H5G_name_t") /* Get the list of opened object ids (groups & datasets) */ - if(H5F_get_obj_ids(file, H5F_OBJ_LOCAL|H5F_OBJ_GROUP|H5F_OBJ_DATASET, grp_dset_count, obj_ids, FALSE, &grp_dset_count) < 0) + if(H5F_get_obj_ids(file, H5F_OBJ_GROUP|H5F_OBJ_DATASET, grp_dset_count, obj_ids, FALSE, &grp_dset_count) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "H5F_get_obj_ids failed") /* Refresh opened objects (groups, datasets) in the file */ for(u = 0; u < grp_dset_count; u++) { H5O_loc_t *oloc; /* object location */ - + H5G_loc_t tmp_loc; /* Set up the id's group location */ obj_glocs[u].oloc = &obj_olocs[u]; obj_glocs[u].path = &obj_paths[u]; @@ -1677,9 +1670,13 @@ H5Fstart_swmr_write(hid_t file_id) if((oloc = H5O_get_loc(obj_ids[u])) == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an object") - /* Refresh (part 1) */ - if(H5O_refresh_metadata_close(obj_ids[u], *oloc, &obj_glocs[u], H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't refresh-close object") + /* Make deep local copy of object's location information */ + H5G_loc(obj_ids[u], &tmp_loc); + H5G_loc_copy(&obj_glocs[u], &tmp_loc, H5_COPY_DEEP); + + /* Close the object */ + if(H5I_dec_ref(obj_ids[u]) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTCLOSEOBJ, FAIL, "decrementing object ID failed") } /* end for */ } /* end if */ @@ -1724,9 +1721,9 @@ H5Fstart_swmr_write(hid_t file_id) if(H5F_evict_cache_entries(file, H5AC_dxpl_id) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to evict file's cached information") - /* Refresh (part 2: reopen) the objects (groups & datasets) in the file */ + /* Refresh (reopen) the objects (groups & datasets) in the file */ for(u = 0; u < grp_dset_count; u++) { - if(H5O_refresh_metadata_reopen(obj_ids[u], &obj_glocs[u], H5AC_dxpl_id) < 0) + if(H5O_refresh_metadata_reopen(obj_ids[u], &obj_glocs[u], H5AC_dxpl_id, TRUE) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't refresh-close object") } diff --git a/src/H5Gpublic.h b/src/H5Gpublic.h index 10b07c0..9d8ade5 100644 --- a/src/H5Gpublic.h +++ b/src/H5Gpublic.h @@ -84,6 +84,8 @@ H5_DLL herr_t H5Gget_info_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5G_info_t *ginfo, hid_t lapl_id); H5_DLL herr_t H5Gclose(hid_t group_id); +H5_DLL herr_t H5Gflush(hid_t group_id); +H5_DLL herr_t H5Grefresh(hid_t group_id); /* Symbols defined for compatibility with previous versions of the HDF5 API. * @@ -167,8 +169,6 @@ H5_DLL herr_t H5Gget_objinfo(hid_t loc_id, const char *name, hbool_t follow_link, H5G_stat_t *statbuf/*out*/); H5_DLL ssize_t H5Gget_objname_by_idx(hid_t loc_id, hsize_t idx, char* name, size_t size); -H5_DLL herr_t H5Gflush(hid_t group_id); -H5_DLL herr_t H5Grefresh(hid_t group_id); H5_DLL H5G_obj_t H5Gget_objtype_by_idx(hid_t loc_id, hsize_t idx); #endif /* H5_NO_DEPRECATED_SYMBOLS */ diff --git a/src/H5Oflush.c b/src/H5Oflush.c index 68f47fd..00fa937 100644 --- a/src/H5Oflush.c +++ b/src/H5Oflush.c @@ -218,10 +218,11 @@ done: * * Note: This is based on the original H5O_refresh_metadata() but * is split into 2 routines. - * (This is done so that H5Fstart_swmr_write() can use these + * This is done so that H5Fstart_swmr_write() can use these * 2 routines to refresh opened objects. This may be * restored back to the original code when H5Fstart_swmr_write() * uses a different approach to handle issues with opened objects. + * H5Fstart_swmr_write() no longer calls the 1st routine. (12/24/15) * * Return: Non-negative on success, negative on failure * @@ -241,6 +242,8 @@ H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc, hid_t dxpl_id) FUNC_ENTER_NOAPI(FAIL) + /* If the file is opened with write access, + no need to perform refresh actions. */ if(H5F_INTENT(oloc.file) & H5F_ACC_RDWR) HGOTO_DONE(SUCCEED) @@ -260,7 +263,7 @@ H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc, hid_t dxpl_id) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to refresh object") /* Re-open the object, re-fetching its metadata */ - if((H5O_refresh_metadata_reopen(oid, &obj_loc, dxpl_id)) < 0) + if((H5O_refresh_metadata_reopen(oid, &obj_loc, dxpl_id, FALSE)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to refresh object") done: @@ -276,10 +279,11 @@ done: * * Purpose: This is the first part of the original routine H5O_refresh_metadata(). * (1) Save object location information. - * (2) Get object cork status - * (3) Close the object - * (4) Flush and evict object metadata - * (5) Re-cork the object if needed + * (2) Handle multiple dataset opens + * (3) Get object cork status + * (4) Close the object + * (5) Flush and evict object metadata + * (6) Re-cork the object if needed * * Return: Success: Non-negative * Failure: Negative @@ -306,6 +310,12 @@ H5O_refresh_metadata_close(hid_t oid, H5O_loc_t oloc, H5G_loc_t *obj_loc, hid_t H5G_loc_copy(obj_loc, &tmp_loc, H5_COPY_DEEP); } /* end if */ + /* Get object's type */ + if(H5I_get_type(oid) == H5I_DATASET) { + if(H5D_mult_refresh_close(oid, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to prepare refresh for dataset") + } + /* Retrieve tag for object */ if(H5O_oh_tag(&oloc, dxpl_id, &tag) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "unable to get object header address") @@ -340,8 +350,8 @@ done: * Function: H5O_refresh_metadata_reopen * * Purpose: This is the second part of the original routine H5O_refresh_metadata(). - * (1) Re-open object with the saved object location information. - * (2) Re-register object ID with the re-opened object. + * (1) Re-open object with the saved object location information. + * (2) Re-register object ID with the re-opened object. * * Return: SUCCEED/FAIL * @@ -351,7 +361,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5O_refresh_metadata_reopen(hid_t oid, H5G_loc_t *obj_loc, hid_t dxpl_id) +H5O_refresh_metadata_reopen(hid_t oid, H5G_loc_t *obj_loc, hid_t dxpl_id, hbool_t start_swmr) { void *object = NULL; /* Dataset for this operation */ H5I_type_t type; @@ -382,6 +392,10 @@ H5O_refresh_metadata_reopen(hid_t oid, H5G_loc_t *obj_loc, hid_t dxpl_id) /* Re-open the dataset */ if(NULL == (object = H5D_open(obj_loc, H5P_DATASET_ACCESS_DEFAULT, dxpl_id))) HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to open dataset") + if(!start_swmr) { /* No need to handle multiple opens when H5Fstart_swmr_write() */ + if(H5D_mult_refresh_reopen(object, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to finish refresh for dataset") + } break; case(H5I_UNINIT): diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 5a59863..3c7b78a 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -909,7 +909,7 @@ H5_DLL herr_t H5O_msg_unlock(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_ H5_DLL herr_t H5O_flush_common(H5O_loc_t *oloc, hid_t obj_id, hid_t dxpl_id); H5_DLL herr_t H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc, hid_t dxpl_id); H5_DLL herr_t H5O_refresh_metadata_close(hid_t oid, H5O_loc_t oloc, H5G_loc_t *obj_loc, hid_t dxpl_id); -H5_DLL herr_t H5O_refresh_metadata_reopen(hid_t oid, H5G_loc_t *obj_loc, hid_t dxpl_id); +H5_DLL herr_t H5O_refresh_metadata_reopen(hid_t oid, H5G_loc_t *obj_loc, hid_t dxpl_id, hbool_t start_swmr); /* Object copying routines */ H5_DLL herr_t H5O_copy_header_map(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, diff --git a/test/swmr.c b/test/swmr.c index cb7aa81..1599acd 100644 --- a/test/swmr.c +++ b/test/swmr.c @@ -38,15 +38,15 @@ #define H5F_TESTING #include "H5Fpkg.h" /* File access */ +#define H5D_FRIEND /*suppress error about including H5FDpkg */ +#define H5D_TESTING +#include "H5Dpkg.h" + /* This file needs to access the file driver testing code */ #define H5FD_FRIEND /*suppress error about including H5FDpkg */ #define H5FD_TESTING #include "H5FDpkg.h" /* File drivers */ -#define H5D_FRIEND /*suppress error about including H5Dpkg */ -#define H5D_TESTING -#include "H5Dpkg.h" - const char *FILENAME[] = { "swmr0", /* 0 */ @@ -57,9 +57,6 @@ const char *FILENAME[] = { #define NAME_BUF_SIZE 1024 /* Length of file name */ -/* Name of message file that is used by test_start_swmr_write_concur() */ -#define DONE_MESSAGE "DONE_MESSAGE" /* The message file to create */ - /* Tests for H5Pget/set_metadata_read_attempts(), H5Fget_metadata_read_retry_info */ static int test_metadata_read_attempts(hid_t in_fapl); static int test_metadata_read_retry_info(hid_t in_fapl); @@ -92,6 +89,12 @@ static int test_file_lock_swmr_concur(hid_t fapl); /* Tests for SWMR VFD flag */ static int test_swmr_vfd_flag(void); +/* Tests for H5Drefresh: concurrent access */ +static int test_refresh_concur(hid_t in_fapl, hbool_t new_format); + +/* Tests for multiple opens of files and datasets with H5Drefresh() & H5Fstart_swmr_write(): same process */ +static int test_multiple_same(hid_t in_fapl, hbool_t new_format); + /* * Tests for H5Pget/set_metadata_read_attemps(), H5Fget_metadata_read_retry_info() */ @@ -1508,28 +1511,30 @@ error: /* * test_start_swmr_write(): * - * Verify SWMR writing is enabled via H5Fstart_swmr_write(): + * Verify SWMR writing is enabled via H5Fstart_swmr_write(): * Mainly test for file created with SWMR_WRITE + with/without latest format: * --file will have v3 superblock and all latest version support enabled * - * (a) Creating a file + * (A) Creating a file * Create a file with SWMR_WRITE + non-latest-format * Create a chunked dataset "dataset1" in the file -- should be using latest chunk indexing * Should fail to enable SWMR as the file is already in SWMR writing mode * Close the file * - * (a) Opening a file + * (B) Opening a file * Open the file with write + non-latest-format * --file has v3 superblock and all latest version support enabled - * Open dataset "dataset1"--keep it open - * Create a chunked dataset "dataset2" in the file -- should be using latest chunk indexing -- keep it open + * Open dataset "dataset1" 3 times--keep it open + * Write to "dataset1" + * Create a group in the file + * Create a chunked dataset "dataset2" in the group--should be using latest chunk indexing--keep it open * Should succeed in enabling SWMR - * Should succeed in writing/reading from "dataset1" - * Close "dataset1" and "dataset2" - * Create "dataset3" -- should be using latest chunk indexing + * Should succeed in reading from multiple opens of "dataset1" + * Close multiple opens of "dataset1" + * Close "dataset2" + * Create "dataset3"--should be using latest chunk indexing * Close "dataset3" - * Close the file - * + * Close the group and file */ static int test_start_swmr_write(hid_t in_fapl, hbool_t new_format) @@ -1540,6 +1545,7 @@ test_start_swmr_write(hid_t in_fapl, hbool_t new_format) hid_t dcpl = -1; /* Dataset creation property */ hid_t file_fapl = -1; /* File access property for the file */ hid_t did1 = -1, did2 = -1, did3 = -1; /* Dataset IDs */ + hid_t did1_a = -1, did1_b = -1; hid_t sid1 = -1, sid2 = -1, sid3 = -1; /* Dataspace IDs */ hsize_t dim[1] = {1}; /* Dimension sizes */ hsize_t max_dim[1] = {H5S_UNLIMITED}; /* Maximum dimension sizes */ @@ -1690,6 +1696,14 @@ test_start_swmr_write(hid_t in_fapl, hbool_t new_format) if((did1 = H5Dopen2(fid, "dataset1", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR; + /* open "dataset1" second time */ + if((did1_a = H5Dopen2(fid, "dataset1", H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR; + + /* open "dataset1" third time */ + if((did1_b = H5Dopen2(fid, "dataset1", H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR; + /* Write to "dataset1" */ wdata = 88; if(H5Dwrite(did1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wdata) < 0) @@ -1735,16 +1749,33 @@ test_start_swmr_write(hid_t in_fapl, hbool_t new_format) if(H5Pclose(file_fapl) < 0) FAIL_STACK_ERROR; + rdata = 0; + /* Read from "dataset1" via did1_b (multiple opens) */ + if(H5Dread(did1_b, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rdata) < 0) + FAIL_STACK_ERROR; + if(wdata != rdata) + FAIL_STACK_ERROR; + if(H5Dclose(did1_b) < 0) + FAIL_STACK_ERROR; + /* Read from "dataset1" */ + rdata = 0; if(H5Dread(did1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rdata) < 0) FAIL_STACK_ERROR; if(wdata != rdata) FAIL_STACK_ERROR; - - /* Close "dataset1" */ if(H5Dclose(did1) < 0) FAIL_STACK_ERROR; + rdata = 0; + /* Read from "dataset1" via did1_a (multiple opens) */ + if(H5Dread(did1_a, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rdata) < 0) + FAIL_STACK_ERROR; + if(wdata != rdata) + FAIL_STACK_ERROR; + if(H5Dclose(did1_a) < 0) + FAIL_STACK_ERROR; + /* Close "dataset2", dataspace, dataset creation property list */ if(H5Dclose(did2) < 0) FAIL_STACK_ERROR; @@ -1801,6 +1832,8 @@ error: H5Gclose(gid); H5Pclose(dcpl); H5Dclose(did1); + H5Dclose(did1_a); + H5Dclose(did1_b); H5Dclose(did2); H5Dclose(did3); H5Sclose(sid1); @@ -1843,17 +1876,17 @@ error: * --First time succeed, second time fail * --Close the file (2) --Open the file with write + with/without latest format - * --succeed to enable SWMR writing mode - * --reopen the same file + * --Succeed to enable SWMR writing mode + * --Reopen the same file * --fail to enable SWMR writing mode for the reopened file * --Close the file (3) --Open the file with write + with/without latest format - * --open the same file again + * --Open the same file again * --succeed to enable SWMR for the first opened file * --fail to enable SWMR for the second opened file * --Close the file * - * (E) (!new_format): When opening a file which is created with write + non-latest-format: + * (D) (!new_format): When opening a file which is created with write + non-latest-format: * (1) Open the file with SWMR write+latest format * --fail to open due to superblock version not 3 * (2) Open the file with SWMR write+non-latest-format @@ -2277,12 +2310,15 @@ error: * --result in v3 superblock with latest chunk indexing types * (b) Create the file with SWMR write + non-latest-format: * --result in v3 superblock with latest chunk indexing types + * Create a chunked dataset with 1 extendible dimension in the file * * Verify concurrent access for H5Fstart_swmr_write()-- * (1) Parent: open a file with write access * Child: concurrent open of the file with read & SWMR read (fail) * (2) Parent: open a file with write access; enable SWMR writing mode - * Child: concurrent open of the file with read & SWMR read (succeed) + * Child: open the file 2 times with read & SWMR read (succeed) + * open the dataset 2 times with the 2 file opens + * verify data read from multiple opens of the dataset is correct * (3) Parent: open a file with write access; enable SWMR writing mode * Child: Concurrent open of the file with read only (fail) * (4) Parent: open a file with write access; enable SWMR writing mode @@ -2305,7 +2341,7 @@ test_start_swmr_write_concur(hid_t H5_ATTR_UNUSED in_fapl, hbool_t H5_ATTR_UNUSE static int test_start_swmr_write_concur(hid_t in_fapl, hbool_t new_format) { - hid_t fid; /* File ID */ + hid_t fid = -1, fid1 = -1, fid2 = -1; /* File IDs */ hid_t fapl; /* File access property list */ pid_t childpid=0; /* Child process ID */ pid_t tmppid; /* Child process ID returned by waitpid */ @@ -2314,15 +2350,25 @@ test_start_swmr_write_concur(hid_t in_fapl, hbool_t new_format) int child_exit_val; /* Exit status of the child */ char filename[NAME_BUF_SIZE]; /* File name */ + hid_t did = -1, did1 = -1, did2 = -1, did3 = -1; + hid_t sid = -1; + hid_t dcpl = -1; + hsize_t chunk_dims[1] = {1}; + hsize_t maxdims[1] = {H5S_UNLIMITED}; + hsize_t dims[1] = {1}; + int wdata = 0; + + int out_pdf[2]; + int in_pdf[2]; + int notify = 0; + /* Output message about test being performed */ if(new_format) { - TESTING("Testing H5Fstart_swmr_write()--concurrent access for latest format"); + TESTING("H5Fstart_swmr_write()--concurrent access for latest format"); } else { - TESTING("Testing H5Fstart_swmr_write()--concurrent access for non-latest-format"); + TESTING("H5Fstart_swmr_write()--concurrent access for non-latest-format"); } /* end if */ - - if((fapl = H5Pcopy(in_fapl)) < 0) FAIL_STACK_ERROR @@ -2343,12 +2389,29 @@ test_start_swmr_write_concur(hid_t in_fapl, hbool_t new_format) FAIL_STACK_ERROR } /* end if */ + /* Create a chunked dataset with 1 extendible dimension */ + if((sid = H5Screate_simple(1, dims, maxdims)) < 0) + FAIL_STACK_ERROR; + if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + FAIL_STACK_ERROR + if(H5Pset_chunk(dcpl, 1, chunk_dims) < 0) + FAIL_STACK_ERROR; + if((did = H5Dcreate2(fid, "dataset", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR; + + /* Close the dataset */ + if(H5Dclose(did) < 0) + FAIL_STACK_ERROR + if(H5Sclose(sid) < 0) + FAIL_STACK_ERROR + /* Close the file */ if(H5Fclose(fid) < 0) FAIL_STACK_ERROR - /* Remove the message file to be sure */ - HDremove(DONE_MESSAGE); + /* Create 1 pipe */ + if(HDpipe(out_pdf) < 0) + FAIL_STACK_ERROR /* * Case (1): @@ -2361,11 +2424,18 @@ test_start_swmr_write_concur(hid_t in_fapl, hbool_t new_format) FAIL_STACK_ERROR if(childpid == 0) { /* Child process */ + int child_notify = 0; - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) + /* Close unused write end for out_pdf */ + if(HDclose(out_pdf[1]) < 0) HDexit(EXIT_FAILURE); + /* Wait for notification from parent process */ + while(child_notify != 1) { + if(HDread(out_pdf[0], &child_notify, sizeof(int)) < 0) + HDexit(EXIT_FAILURE); + } + /* Should fail */ H5E_BEGIN_TRY { /* Open the test file */ @@ -2374,15 +2444,29 @@ test_start_swmr_write_concur(hid_t in_fapl, hbool_t new_format) if(fid >= 0) HDexit(EXIT_FAILURE); + /* Close the pipe */ + if(HDclose(out_pdf[0]) < 0) + HDexit(EXIT_FAILURE); + HDexit(EXIT_SUCCESS); } + /* close unused read end for out_pdf */ + if(HDclose(out_pdf[0]) < 0) + FAIL_STACK_ERROR + /* Open the test file */ if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); + /* Notify child process */ + notify = 1; + if(HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0) + FAIL_STACK_ERROR; + + /* Close the pipe */ + if(HDclose(out_pdf[1]) < 0) + FAIL_STACK_ERROR; /* Wait for child process to complete */ if((tmppid = HDwaitpid(childpid, &child_status, child_wait_option)) < 0) @@ -2405,38 +2489,176 @@ test_start_swmr_write_concur(hid_t in_fapl, hbool_t new_format) * will succeed with H5Fstart_swmr_write() */ - /* Remove the message file to be sure */ - HDremove(DONE_MESSAGE); + /* Create 2 pipes */ + if(HDpipe(out_pdf) < 0) + FAIL_STACK_ERROR + if(HDpipe(in_pdf) < 0) + FAIL_STACK_ERROR /* Fork child process */ if((childpid = HDfork()) < 0) FAIL_STACK_ERROR if(childpid == 0) { /* Child process */ - hid_t child_fid; /* File ID */ + hid_t child_fid1 = -1, child_fid2; /* File IDs */ + hid_t child_did1 = -1, child_did2 = -1; /* Dataset IDs */ + int child_notify = 0; + int rdata = 0; + + /* Close unused write end for out_pdf */ + if(HDclose(out_pdf[1]) < 0) + HDexit(EXIT_FAILURE); + /* close unused read end for in_pdf */ + if(HDclose(in_pdf[0]) < 0) + HDexit(EXIT_FAILURE); + + /* Wait for notification from parent process */ + while(child_notify != 1) { + if(HDread(out_pdf[0], &child_notify, sizeof(int)) < 0) + HDexit(EXIT_FAILURE); + } + + /* Should succeed in opening the test file 2 times */ + if((child_fid1 = H5Fopen(filename, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl)) < 0) + HDexit(EXIT_FAILURE); + if((child_fid2 = H5Fopen(filename, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl)) < 0) + HDexit(EXIT_FAILURE); + + /* open "dataset" 2 times */ + if((child_did1 = H5Dopen2(child_fid1, "dataset", H5P_DEFAULT)) < 0) + HDexit(EXIT_FAILURE); + if((child_did2 = H5Dopen2(child_fid2, "dataset", H5P_DEFAULT)) < 0) + HDexit(EXIT_FAILURE); + + /* Read from "dataset" via child_did1 */ + rdata = 0; + if(H5Dread(child_did1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rdata) < 0) + HDexit(EXIT_FAILURE); + if(rdata != 88) + HDexit(EXIT_FAILURE); + + /* Notify parent process */ + child_notify = 2; + if(HDwrite(in_pdf[1], &child_notify, sizeof(int)) < 0) + HDexit(EXIT_FAILURE); + + /* Wait for notification from parent process */ + while(child_notify != 3) { + if(HDread(out_pdf[0], &child_notify, sizeof(int)) < 0) + HDexit(EXIT_FAILURE); + } + + /* Refresh "dataset" via child_did2 */ + if(H5Drefresh(child_did2) < 0) + HDexit(EXIT_FAILURE); + + /* Read from "dataset" child_did2 */ + rdata = 0; + if(H5Dread(child_did2, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rdata) < 0) + HDexit(EXIT_FAILURE); + if(rdata != 99) + HDexit(EXIT_FAILURE); + + /* Read from "dataset" child_did1 */ + rdata = 0; + if(H5Dread(child_did1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rdata) < 0) + HDexit(EXIT_FAILURE); + if(rdata != 99) + HDexit(EXIT_FAILURE); - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) + /* Close the dataset */ + if(H5Dclose(child_did1)) + HDexit(EXIT_FAILURE); + if(H5Dclose(child_did2)) HDexit(EXIT_FAILURE); - /* Should succeed in opening the test file */ - if((child_fid = H5Fopen(filename, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl)) < 0) + /* Close the file */ + if(H5Fclose(child_fid1) < 0) HDexit(EXIT_FAILURE); - if(H5Fclose(child_fid) < 0) + if(H5Fclose(child_fid2) < 0) HDexit(EXIT_FAILURE); + + /* Close the pipe */ + if(HDclose(out_pdf[0]) < 0) + HDexit(EXIT_FAILURE); + if(HDclose(in_pdf[1]) < 0) + HDexit(EXIT_FAILURE); + HDexit(EXIT_SUCCESS); } + /* close unused read end for out_pdf */ + if(HDclose(out_pdf[0]) < 0) + FAIL_STACK_ERROR + /* Close unused write end for in_pdf */ + if(HDclose(in_pdf[1]) < 0) + FAIL_STACK_ERROR + /* Open the test file */ - if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + if((fid1 = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR + if((fid2 = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* open "dataset", keep it open */ + if((did1 = H5Dopen2(fid1, "dataset", H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR; + if((did2 = H5Dopen2(fid2, "dataset", H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR; + if((did3 = H5Dopen2(fid1, "dataset", H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR; + + /* Write to "dataset" */ + wdata = 88; + if(H5Dwrite(did2, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wdata) < 0) + FAIL_STACK_ERROR; + + /* Flush to disk */ + if(H5Fflush(fid1, H5F_SCOPE_LOCAL) < 0) + FAIL_STACK_ERROR; /* Enable SWMR writing mode */ - if(H5Fstart_swmr_write(fid) < 0) + if(H5Fstart_swmr_write(fid1) < 0) TEST_ERROR - /* Send the message that H5Fstart_swmr_write() completes */ - h5_send_message(DONE_MESSAGE); + /* Notify child process */ + notify = 1; + if(HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0) + FAIL_STACK_ERROR; + + /* Wait for notification from child process */ + while(notify != 2) { + if(HDread(in_pdf[0], ¬ify, sizeof(int)) < 0) + FAIL_STACK_ERROR; + } + + /* Write to "dataset" */ + wdata = 99; + if(H5Dwrite(did1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wdata) < 0) + FAIL_STACK_ERROR; + + /* Flush to disk */ + if(H5Fflush(fid1, H5F_SCOPE_LOCAL) < 0) + FAIL_STACK_ERROR; + + /* Notify child process */ + notify = 3; + if(HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0) + FAIL_STACK_ERROR; + + /* Close the dataset */ + if(H5Dclose(did1) < 0) + FAIL_STACK_ERROR + if(H5Dclose(did2) < 0) + FAIL_STACK_ERROR + if(H5Dclose(did3) < 0) + FAIL_STACK_ERROR + + /* Close the pipes */ + if(HDclose(out_pdf[1]) < 0) + FAIL_STACK_ERROR; + if(HDclose(in_pdf[0]) < 0) + FAIL_STACK_ERROR; /* Wait for child process to complete */ if((tmppid = HDwaitpid(childpid, &child_status, child_wait_option)) < 0) @@ -2450,28 +2672,38 @@ test_start_swmr_write_concur(hid_t in_fapl, hbool_t new_format) TEST_ERROR /* Close the file */ - if(H5Fclose(fid) < 0) + if(H5Fclose(fid1) < 0) + FAIL_STACK_ERROR + if(H5Fclose(fid2) < 0) FAIL_STACK_ERROR + /* * Case (3): * Verify concurrent file open with H5F_ACC_RDONLY * will fail with H5Fstart_swmr_write() */ - - /* Remove the message file to be sure */ - HDremove(DONE_MESSAGE); + /* Create 1 pipe */ + if(HDpipe(out_pdf) < 0) + FAIL_STACK_ERROR /* Fork child process */ if((childpid = HDfork()) < 0) FAIL_STACK_ERROR if(childpid == 0) { /* Child process */ + int child_notify = 0; - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) + /* Close unused write end for out_pdf */ + if(HDclose(out_pdf[1]) < 0) HDexit(EXIT_FAILURE); + /* Wait for notification from parent process */ + while(child_notify != 1) { + if(HDread(out_pdf[0], &child_notify, sizeof(int)) < 0) + HDexit(EXIT_FAILURE); + } + /* Should fail in opening the test file */ H5E_BEGIN_TRY { fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl); @@ -2482,6 +2714,10 @@ test_start_swmr_write_concur(hid_t in_fapl, hbool_t new_format) HDexit(EXIT_SUCCESS); } /* end if */ + /* close unused read end for out_pdf */ + if(HDclose(out_pdf[0]) < 0) + FAIL_STACK_ERROR + /* Open the test file */ if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR @@ -2490,8 +2726,14 @@ test_start_swmr_write_concur(hid_t in_fapl, hbool_t new_format) if(H5Fstart_swmr_write(fid) < 0) TEST_ERROR - /* Send the message that H5Fstart_swmr_write() completes */ - h5_send_message(DONE_MESSAGE); + /* Notify child process */ + notify = 1; + if(HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0) + FAIL_STACK_ERROR; + + /* Close the pipe */ + if(HDclose(out_pdf[1]) < 0) + FAIL_STACK_ERROR; /* Wait for child process to complete */ if((tmppid = HDwaitpid(childpid, &child_status, child_wait_option)) < 0) @@ -2514,19 +2756,27 @@ test_start_swmr_write_concur(hid_t in_fapl, hbool_t new_format) * will fail with H5Fstart_swmr_write() */ - /* Remove the message file to be sure */ - HDremove(DONE_MESSAGE); + /* Create 1 pipe */ + if(HDpipe(out_pdf) < 0) + FAIL_STACK_ERROR /* Fork child process */ if((childpid = HDfork()) < 0) FAIL_STACK_ERROR if(childpid == 0) { /* Child process */ + int child_notify = 0; - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) + /* Close unused write end for out_pdf */ + if(HDclose(out_pdf[1]) < 0) HDexit(EXIT_FAILURE); + /* Wait for notification from parent process */ + while(child_notify != 1) { + if(HDread(out_pdf[0], &child_notify, sizeof(int)) < 0) + HDexit(EXIT_FAILURE); + } + /* Should fail in opening the test file */ H5E_BEGIN_TRY { fid = H5Fopen(filename, H5F_ACC_RDWR, fapl); @@ -2534,9 +2784,17 @@ test_start_swmr_write_concur(hid_t in_fapl, hbool_t new_format) if(fid >= 0) HDexit(EXIT_FAILURE); + /* Close the pipe */ + if(HDclose(out_pdf[0]) < 0) + HDexit(EXIT_FAILURE); + HDexit(EXIT_SUCCESS); } /* end if */ + /* close unused read end for out_pdf */ + if(HDclose(out_pdf[0]) < 0) + FAIL_STACK_ERROR + /* Open the test file */ if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR @@ -2545,8 +2803,14 @@ test_start_swmr_write_concur(hid_t in_fapl, hbool_t new_format) if(H5Fstart_swmr_write(fid) < 0) TEST_ERROR - /* Send the message that H5Fstart_swmr_write() completes */ - h5_send_message(DONE_MESSAGE); + /* Notify child process */ + notify = 1; + if(HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0) + FAIL_STACK_ERROR; + + /* Close the pipe */ + if(HDclose(out_pdf[1]) < 0) + FAIL_STACK_ERROR /* Wait for child process to complete */ if((tmppid = HDwaitpid(childpid, &child_status, child_wait_option)) < 0) @@ -2569,19 +2833,27 @@ test_start_swmr_write_concur(hid_t in_fapl, hbool_t new_format) * will fail with H5Fstart_swmr_write() */ - /* Remove the message file to be sure */ - HDremove(DONE_MESSAGE); + /* Create 1 pipe */ + if(HDpipe(out_pdf) < 0) + FAIL_STACK_ERROR /* Fork child process */ if((childpid = HDfork()) < 0) FAIL_STACK_ERROR if(childpid == 0) { /* Child process */ + int child_notify = 0; - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) + /* Close unused write end for out_pdf */ + if(HDclose(out_pdf[1]) < 0) HDexit(EXIT_FAILURE); + /* Wait for notification from parent process */ + while(child_notify != 1) { + if(HDread(out_pdf[0], &child_notify, sizeof(int)) < 0) + HDexit(EXIT_FAILURE); + } + /* Should fail in opening the test file */ H5E_BEGIN_TRY { fid = H5Fopen(filename, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl); @@ -2589,9 +2861,17 @@ test_start_swmr_write_concur(hid_t in_fapl, hbool_t new_format) if(fid >= 0) HDexit(EXIT_FAILURE); + /* Close the pipe */ + if(HDclose(out_pdf[0]) < 0) + HDexit(EXIT_FAILURE); + HDexit(EXIT_SUCCESS); } + /* close unused read end for out_pdf */ + if(HDclose(out_pdf[0]) < 0) + FAIL_STACK_ERROR + /* Open the test file */ if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR @@ -2600,8 +2880,14 @@ test_start_swmr_write_concur(hid_t in_fapl, hbool_t new_format) if(H5Fstart_swmr_write(fid) < 0) TEST_ERROR - /* Send the message that H5Fstart_swmr_write() completes */ - h5_send_message(DONE_MESSAGE); + /* Notify child process */ + notify = 1; + if(HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0) + FAIL_STACK_ERROR; + + /* Close the pipe */ + if(HDclose(out_pdf[1]) < 0) + FAIL_STACK_ERROR; /* Wait for child process to complete */ if((tmppid = HDwaitpid(childpid, &child_status, child_wait_option)) < 0) @@ -2627,6 +2913,8 @@ test_start_swmr_write_concur(hid_t in_fapl, hbool_t new_format) error: H5E_BEGIN_TRY { + H5Sclose(sid); + H5Pclose(dcpl); H5Pclose(fapl); H5Fclose(fid); } H5E_END_TRY; @@ -4243,6 +4531,8 @@ test_file_lock_concur(hid_t in_fapl) pid_t childpid=0; /* Child process ID */ int child_status; /* Status passed to waitpid */ int child_wait_option=0; /* Options passed to waitpid */ + int out_pdf[2]; + int notify = 0; /* Output message about test being performed */ TESTING("File open with different combinations of flags--concurrent access"); @@ -4265,8 +4555,9 @@ test_file_lock_concur(hid_t in_fapl) * Case 1: 1) RDWR 2) RDWR : should fail */ - /* Remove the message file to be sure */ - HDremove(DONE_MESSAGE); + /* Create 1 pipe */ + if(HDpipe(out_pdf) < 0) + FAIL_STACK_ERROR /* Fork child process */ if((childpid = HDfork()) < 0) @@ -4274,11 +4565,18 @@ test_file_lock_concur(hid_t in_fapl) if(childpid == 0) { /* Child process */ hid_t child_fid; /* File ID */ + int child_notify = 0; - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) + /* Close unused write end for out_pdf */ + if(HDclose(out_pdf[1]) < 0) HDexit(EXIT_FAILURE); + /* Wait for notification from parent process */ + while(child_notify != 1) { + if(HDread(out_pdf[0], &child_notify, sizeof(int)) < 0) + HDexit(EXIT_FAILURE); + } + /* Open the test file */ H5E_BEGIN_TRY { child_fid = H5Fopen(filename, H5F_ACC_RDWR, fapl); @@ -4287,15 +4585,30 @@ test_file_lock_concur(hid_t in_fapl) /* Should fail */ if(child_fid == FAIL) HDexit(EXIT_SUCCESS); + + /* Close the pipe */ + if(HDclose(out_pdf[0]) < 0) + HDexit(EXIT_FAILURE); + HDexit(EXIT_FAILURE); } + /* close unused read end for out_pdf */ + if(HDclose(out_pdf[0]) < 0) + FAIL_STACK_ERROR + /* Open the test file */ if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); + /* Notify child process */ + notify = 1; + if(HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0) + FAIL_STACK_ERROR; + + /* Close the pipe */ + if(HDclose(out_pdf[1]) < 0) + FAIL_STACK_ERROR; /* Wait for child process to complete */ if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) @@ -4303,9 +4616,9 @@ test_file_lock_concur(hid_t in_fapl) /* Check if child terminated normally */ if(WIFEXITED(child_status)) { - /* Check exit status of the child */ - if(WEXITSTATUS(child_status) != 0) - TEST_ERROR + /* Check exit status of the child */ + if(WEXITSTATUS(child_status) != 0) + TEST_ERROR } else FAIL_STACK_ERROR @@ -4316,8 +4629,9 @@ test_file_lock_concur(hid_t in_fapl) /* * Case 2: 1) RDWR 2) RDONLY : should fail */ - /* Remove the message file just to be sure */ - HDremove(DONE_MESSAGE); + /* Create 1 pipe */ + if(HDpipe(out_pdf) < 0) + FAIL_STACK_ERROR /* Fork child process */ if((childpid = HDfork()) < 0) @@ -4325,11 +4639,18 @@ test_file_lock_concur(hid_t in_fapl) if(childpid == 0) { /* Child process */ hid_t child_fid; /* File ID */ + int child_notify = 0; - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) + /* Close unused write end for out_pdf */ + if(HDclose(out_pdf[1]) < 0) HDexit(EXIT_FAILURE); + /* Wait for notification from parent process */ + while(child_notify != 1) { + if(HDread(out_pdf[0], &child_notify, sizeof(int)) < 0) + HDexit(EXIT_FAILURE); + } + /* Opens the test file */ H5E_BEGIN_TRY { child_fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl); @@ -4338,15 +4659,30 @@ test_file_lock_concur(hid_t in_fapl) /* Should fail */ if(child_fid == FAIL) HDexit(EXIT_SUCCESS); + + /* Close the pipe */ + if(HDclose(out_pdf[0]) < 0) + HDexit(EXIT_FAILURE); + HDexit(EXIT_FAILURE); } + /* close unused read end for out_pdf */ + if(HDclose(out_pdf[0]) < 0) + FAIL_STACK_ERROR + /* Opens the test file */ if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); + /* Notify child process */ + notify = 1; + if(HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0) + FAIL_STACK_ERROR; + + /* Close the pipe */ + if(HDclose(out_pdf[1]) < 0) + FAIL_STACK_ERROR; /* Wait for child process to complete */ if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) @@ -4368,8 +4704,9 @@ test_file_lock_concur(hid_t in_fapl) * Case 3: 1) RDONLY 2) RDWR : should fail */ - /* Remove the message file just to be sure */ - HDremove(DONE_MESSAGE); + /* Create 1 pipe */ + if(HDpipe(out_pdf) < 0) + FAIL_STACK_ERROR /* Fork child process */ if((childpid = HDfork()) < 0) @@ -4377,11 +4714,18 @@ test_file_lock_concur(hid_t in_fapl) if(childpid == 0) { /* Child process */ hid_t child_fid; /* File ID */ + int child_notify = 0; - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) + /* Close unused write end for out_pdf */ + if(HDclose(out_pdf[1]) < 0) HDexit(EXIT_FAILURE); + /* Wait for notification from parent process */ + while(child_notify != 1) { + if(HDread(out_pdf[0], &child_notify, sizeof(int)) < 0) + HDexit(EXIT_FAILURE); + } + /* Opens the test file */ H5E_BEGIN_TRY { child_fid = H5Fopen(filename, H5F_ACC_RDWR, fapl); @@ -4390,15 +4734,30 @@ test_file_lock_concur(hid_t in_fapl) /* Should fail */ if(child_fid == FAIL) HDexit(EXIT_SUCCESS); + + /* Close the pipe */ + if(HDclose(out_pdf[0]) < 0) + HDexit(EXIT_FAILURE); + HDexit(EXIT_FAILURE); } /* end if */ + /* close unused read end for out_pdf */ + if(HDclose(out_pdf[0]) < 0) + FAIL_STACK_ERROR + /* Opens the test file */ if((fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) FAIL_STACK_ERROR + + /* Notify child process */ + notify = 1; + if(HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0) + FAIL_STACK_ERROR; - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); + /* Close the pipe */ + if(HDclose(out_pdf[1]) < 0) + FAIL_STACK_ERROR; /* Wait for child process to complete */ if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) @@ -4420,7 +4779,9 @@ test_file_lock_concur(hid_t in_fapl) * Case 4: 1) RDONLY 2) RDONLY : should succeed */ - HDremove(DONE_MESSAGE); + /* Create 1 pipe */ + if(HDpipe(out_pdf) < 0) + FAIL_STACK_ERROR /* Fork child process */ if((childpid = HDfork()) < 0) @@ -4428,11 +4789,18 @@ test_file_lock_concur(hid_t in_fapl) if(childpid == 0) { /* Child process */ hid_t child_fid; /* File ID */ + int child_notify = 0; - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) + /* Close unused write end for out_pdf */ + if(HDclose(out_pdf[1]) < 0) HDexit(EXIT_FAILURE); + /* Wait for notification from parent process */ + while(child_notify != 1) { + if(HDread(out_pdf[0], &child_notify, sizeof(int)) < 0) + HDexit(EXIT_FAILURE); + } + /* Opens the test file */ H5E_BEGIN_TRY { child_fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl); @@ -4442,19 +4810,34 @@ test_file_lock_concur(hid_t in_fapl) if(child_fid >= 0) { /* Close the file */ if(H5Fclose(child_fid) < 0) - FAIL_STACK_ERROR + HDexit(EXIT_FAILURE); + + /* Close the pipe */ + if(HDclose(out_pdf[0]) < 0) + HDexit(EXIT_FAILURE); + HDexit(EXIT_SUCCESS); } /* end if */ HDexit(EXIT_FAILURE); } /* end if */ + /* close unused read end for out_pdf */ + if(HDclose(out_pdf[0]) < 0) + FAIL_STACK_ERROR + /* Create file */ if((fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) FAIL_STACK_ERROR - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); + /* Notify child process */ + notify = 1; + if(HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0) + FAIL_STACK_ERROR; + + /* Close the pipe */ + if(HDclose(out_pdf[1]) < 0) + FAIL_STACK_ERROR; /* Wait for child process to complete */ if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) @@ -4524,6 +4907,8 @@ test_file_lock_swmr_concur(hid_t in_fapl) pid_t childpid=0; /* Child process ID */ int child_status; /* Status passed to waitpid */ int child_wait_option=0; /* Options passed to waitpid */ + int out_pdf[2]; + int notify = 0; /* Output message about test being performed */ TESTING("File open with different combintations of flags + SWMR flags--concurrent access"); @@ -4550,8 +4935,9 @@ test_file_lock_swmr_concur(hid_t in_fapl) * Case 1: 1) RDWR 2) RDWR|SWMR_WRITE : should fail */ - /* Remove the message file to be sure */ - HDremove(DONE_MESSAGE); + /* Create 1 pipe */ + if(HDpipe(out_pdf) < 0) + FAIL_STACK_ERROR /* Fork child process */ if((childpid = HDfork()) < 0) @@ -4559,11 +4945,18 @@ test_file_lock_swmr_concur(hid_t in_fapl) if(childpid == 0) { /* Child process */ hid_t child_fid; /* File ID */ + int child_notify = 0; - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) + /* Close unused write end for out_pdf */ + if(HDclose(out_pdf[1]) < 0) HDexit(EXIT_FAILURE); + /* Wait for notification from parent process */ + while(child_notify != 1) { + if(HDread(out_pdf[0], &child_notify, sizeof(int)) < 0) + HDexit(EXIT_FAILURE); + } + /* Open the test file */ H5E_BEGIN_TRY { child_fid = H5Fopen(filename, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl); @@ -4572,15 +4965,30 @@ test_file_lock_swmr_concur(hid_t in_fapl) /* Should fail */ if(child_fid == FAIL) HDexit(EXIT_SUCCESS); + + /* Close the pipe */ + if(HDclose(out_pdf[0]) < 0) + HDexit(EXIT_FAILURE); + HDexit(EXIT_FAILURE); } + /* close unused read end for out_pdf */ + if(HDclose(out_pdf[0]) < 0) + FAIL_STACK_ERROR + /* Open the test file */ if((fid = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); + /* Notify child process */ + notify = 1; + if(HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0) + FAIL_STACK_ERROR; + + /* Close the pipe */ + if(HDclose(out_pdf[1]) < 0) + FAIL_STACK_ERROR; /* Wait for child process to complete */ if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) @@ -4602,20 +5010,28 @@ test_file_lock_swmr_concur(hid_t in_fapl) * Case 2: 1) RDWR 2) RDONLY|SWMR_READ: should fail */ - /* Remove the message file to be sure */ - HDremove(DONE_MESSAGE); + /* Create 1 pipe */ + if(HDpipe(out_pdf) < 0) + FAIL_STACK_ERROR /* Fork child process */ if((childpid = HDfork()) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR if(childpid == 0) { /* Child process */ hid_t child_fid; /* File ID */ + int child_notify = 0; - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) + /* Close unused write end for out_pdf */ + if(HDclose(out_pdf[1]) < 0) HDexit(EXIT_FAILURE); + /* Wait for notification from parent process */ + while(child_notify != 1) { + if(HDread(out_pdf[0], &child_notify, sizeof(int)) < 0) + HDexit(EXIT_FAILURE); + } + /* Open the test file */ H5E_BEGIN_TRY { child_fid = H5Fopen(filename, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl); @@ -4624,19 +5040,34 @@ test_file_lock_swmr_concur(hid_t in_fapl) /* Should fail */ if(child_fid == FAIL) HDexit(EXIT_SUCCESS); + + /* Close the pipe */ + if(HDclose(out_pdf[0]) < 0) + HDexit(EXIT_FAILURE); + HDexit(EXIT_FAILURE); } + /* close unused read end for out_pdf */ + if(HDclose(out_pdf[0]) < 0) + FAIL_STACK_ERROR + /* Open the test file */ if((fid = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); + /* Notify child process */ + notify = 1; + if(HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0) + FAIL_STACK_ERROR; + + /* Close the pipe */ + if(HDclose(out_pdf[1]) < 0) + FAIL_STACK_ERROR; /* Wait for child process to complete */ if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR /* Check if child terminated normally */ if(WIFEXITED(child_status)) { @@ -4654,8 +5085,9 @@ test_file_lock_swmr_concur(hid_t in_fapl) * Case 3: 1) RDWR|SWMR_WRITE 2) RDWR : should fail */ - /* Remove the message file to be sure */ - HDremove(DONE_MESSAGE); + /* Create 1 pipe */ + if(HDpipe(out_pdf) < 0) + FAIL_STACK_ERROR /* Fork child process */ if((childpid = HDfork()) < 0) @@ -4663,11 +5095,18 @@ test_file_lock_swmr_concur(hid_t in_fapl) if(childpid == 0) { /* Child process */ hid_t child_fid; /* File ID */ + int child_notify = 0; - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) + /* Close unused write end for out_pdf */ + if(HDclose(out_pdf[1]) < 0) HDexit(EXIT_FAILURE); + /* Wait for notification from parent process */ + while(child_notify != 1) { + if(HDread(out_pdf[0], &child_notify, sizeof(int)) < 0) + HDexit(EXIT_FAILURE); + } + /* Open the test file */ H5E_BEGIN_TRY { child_fid = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT); @@ -4676,15 +5115,30 @@ test_file_lock_swmr_concur(hid_t in_fapl) /* Should fail */ if(child_fid == FAIL) HDexit(EXIT_SUCCESS); + + /* Close the pipe */ + if(HDclose(out_pdf[0]) < 0) + HDexit(EXIT_FAILURE); + HDexit(EXIT_FAILURE); } + /* close unused read end for out_pdf */ + if(HDclose(out_pdf[0]) < 0) + FAIL_STACK_ERROR + /* Open the test file */ if((fid = H5Fopen(filename, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl)) < 0) FAIL_STACK_ERROR - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); + /* Notify child process */ + notify = 1; + if(HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0) + FAIL_STACK_ERROR; + + /* Close the pipe */ + if(HDclose(out_pdf[1]) < 0) + FAIL_STACK_ERROR; /* Wait for child process to complete */ if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) @@ -4706,8 +5160,8 @@ test_file_lock_swmr_concur(hid_t in_fapl) * Case 4: 1) RDWR|SWMR_WRITE 2) RDWR|SWMR_WRITE : should fail */ - /* Remove the message file just to be sure */ - HDremove(DONE_MESSAGE); + if(HDpipe(out_pdf) < 0) + FAIL_STACK_ERROR /* Fork child process */ if((childpid = HDfork()) < 0) @@ -4715,11 +5169,18 @@ test_file_lock_swmr_concur(hid_t in_fapl) if(childpid == 0) { /* Child process */ hid_t child_fid; /* File ID */ + int child_notify = 0; - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) + /* Close unused write end for out_pdf */ + if(HDclose(out_pdf[1]) < 0) HDexit(EXIT_FAILURE); + /* Wait for notification from parent process */ + while(child_notify != 1) { + if(HDread(out_pdf[0], &child_notify, sizeof(int)) < 0) + HDexit(EXIT_FAILURE); + } + /* Open the test file */ H5E_BEGIN_TRY { child_fid = H5Fopen(filename, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl); @@ -4728,15 +5189,30 @@ test_file_lock_swmr_concur(hid_t in_fapl) /* Should fail */ if(child_fid == FAIL) HDexit(EXIT_SUCCESS); + + /* Close the pipe */ + if(HDclose(out_pdf[0]) < 0) + HDexit(EXIT_FAILURE); + HDexit(EXIT_FAILURE); } + /* close unused read end for out_pdf */ + if(HDclose(out_pdf[0]) < 0) + FAIL_STACK_ERROR + /* Open the test file */ if((fid = H5Fopen(filename, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl)) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); + /* Notify child process */ + notify = 1; + if(HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0) + FAIL_STACK_ERROR; + + /* Close the pipe */ + if(HDclose(out_pdf[1]) < 0) + FAIL_STACK_ERROR; /* Wait for child process to complete */ if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) @@ -4758,20 +5234,27 @@ test_file_lock_swmr_concur(hid_t in_fapl) * Case 5: 1) RDWR|SWMR_WRITE 2) RDONLY|SWMR_READ : should succeed */ - /* Remove the message file just to be sure */ - HDremove(DONE_MESSAGE); + if(HDpipe(out_pdf) < 0) + FAIL_STACK_ERROR /* Fork child process */ if((childpid = HDfork()) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR if(childpid == 0) { /* Child process */ hid_t child_fid; /* File ID */ + int child_notify = 0; - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) + /* Close unused write end for out_pdf */ + if(HDclose(out_pdf[1]) < 0) HDexit(EXIT_FAILURE); + /* Wait for notification from parent process */ + while(child_notify != 1) { + if(HDread(out_pdf[0], &child_notify, sizeof(int)) < 0) + HDexit(EXIT_FAILURE); + } + /* Open the test file */ H5E_BEGIN_TRY { child_fid = H5Fopen(filename, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl); @@ -4783,15 +5266,30 @@ test_file_lock_swmr_concur(hid_t in_fapl) FAIL_STACK_ERROR HDexit(EXIT_SUCCESS); } + + /* Close the pipe */ + if(HDclose(out_pdf[0]) < 0) + HDexit(EXIT_FAILURE); + HDexit(EXIT_FAILURE); } + /* close unused read end for out_pdf */ + if(HDclose(out_pdf[0]) < 0) + FAIL_STACK_ERROR + /* Open the test file */ if((fid = H5Fopen(filename, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl)) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR + + /* Notify child process */ + notify = 1; + if(HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0) + FAIL_STACK_ERROR; - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); + /* Close the pipe */ + if(HDclose(out_pdf[1]) < 0) + FAIL_STACK_ERROR; /* Wait for child process to complete */ if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) @@ -4813,8 +5311,8 @@ test_file_lock_swmr_concur(hid_t in_fapl) * Case 6: 1) RDWR|SWMR_WRITE 2) RDONLY : should fail */ - /* Remove the message file just to be sure */ - HDremove(DONE_MESSAGE); + if(HDpipe(out_pdf) < 0) + FAIL_STACK_ERROR /* Fork child process */ if((childpid = HDfork()) < 0) @@ -4822,11 +5320,18 @@ test_file_lock_swmr_concur(hid_t in_fapl) if(childpid == 0) { /* Child process */ hid_t child_fid; /* File ID */ + int child_notify = 0; - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) + /* Close unused write end for out_pdf */ + if(HDclose(out_pdf[1]) < 0) HDexit(EXIT_FAILURE); + /* Wait for notification from parent process */ + while(child_notify != 1) { + if(HDread(out_pdf[0], &child_notify, sizeof(int)) < 0) + HDexit(EXIT_FAILURE); + } + /* Open the test file */ H5E_BEGIN_TRY { child_fid = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT); @@ -4835,15 +5340,30 @@ test_file_lock_swmr_concur(hid_t in_fapl) /* Should fail */ if(child_fid == FAIL) HDexit(EXIT_SUCCESS); + + /* Close the pipe */ + if(HDclose(out_pdf[0]) < 0) + HDexit(EXIT_FAILURE); + HDexit(EXIT_FAILURE); } + /* close unused read end for out_pdf */ + if(HDclose(out_pdf[0]) < 0) + FAIL_STACK_ERROR + /* Open the test file */ if((fid = H5Fopen(filename, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl)) < 0) FAIL_STACK_ERROR - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); + /* Notify child process */ + notify = 1; + if(HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0) + FAIL_STACK_ERROR; + + /* Close the pipe */ + if(HDclose(out_pdf[1]) < 0) + FAIL_STACK_ERROR; /* Wait for child process to complete */ if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) @@ -4865,8 +5385,9 @@ test_file_lock_swmr_concur(hid_t in_fapl) * Case 7: 1) RDONLY|SWMR_READ 2) RDWR : should fail */ - /* Remove the message file just to be sure */ - HDremove(DONE_MESSAGE); + /* Create 1 pipe */ + if(HDpipe(out_pdf) < 0) + FAIL_STACK_ERROR /* Fork child process */ if((childpid = HDfork()) < 0) @@ -4874,11 +5395,18 @@ test_file_lock_swmr_concur(hid_t in_fapl) if(childpid == 0) { /* Child process */ hid_t child_fid; /* File ID */ + int child_notify = 0; - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) + /* Close unused write end for out_pdf */ + if(HDclose(out_pdf[1]) < 0) HDexit(EXIT_FAILURE); + /* Wait for notification from parent process */ + while(child_notify != 1) { + if(HDread(out_pdf[0], &child_notify, sizeof(int)) < 0) + HDexit(EXIT_FAILURE); + } + /* Open the test file */ H5E_BEGIN_TRY { child_fid = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT); @@ -4887,15 +5415,30 @@ test_file_lock_swmr_concur(hid_t in_fapl) /* Should fail */ if(child_fid == FAIL) HDexit(EXIT_SUCCESS); + + /* Close the pipe */ + if(HDclose(out_pdf[0]) < 0) + HDexit(EXIT_FAILURE); + HDexit(EXIT_FAILURE); } + /* close unused read end for out_pdf */ + if(HDclose(out_pdf[0]) < 0) + FAIL_STACK_ERROR + /* Open the test file */ if((fid = H5Fopen(filename, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl)) < 0) FAIL_STACK_ERROR - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); + /* Notify child process */ + notify = 1; + if(HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0) + FAIL_STACK_ERROR; + + /* Close the pipe */ + if(HDclose(out_pdf[1]) < 0) + FAIL_STACK_ERROR; /* Wait for child process to complete */ if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) @@ -4917,8 +5460,9 @@ test_file_lock_swmr_concur(hid_t in_fapl) * Case 8: 1) RDONLY|SWMR_READ 2) RDWR|SWMR_WRITE : should fail */ - /* Remove the message file just to be sure */ - HDremove(DONE_MESSAGE); + /* Create 1 pipe */ + if(HDpipe(out_pdf) < 0) + FAIL_STACK_ERROR /* Fork child process */ if((childpid = HDfork()) < 0) @@ -4926,11 +5470,18 @@ test_file_lock_swmr_concur(hid_t in_fapl) if(childpid == 0) { /* Child process */ hid_t child_fid; /* File ID */ + int child_notify = 0; - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) + /* Close unused write end for out_pdf */ + if(HDclose(out_pdf[1]) < 0) HDexit(EXIT_FAILURE); + /* Wait for notification from parent process */ + while(child_notify != 1) { + if(HDread(out_pdf[0], &child_notify, sizeof(int)) < 0) + HDexit(EXIT_FAILURE); + } + /* Open the test file */ H5E_BEGIN_TRY { child_fid = H5Fopen(filename, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl); @@ -4939,15 +5490,30 @@ test_file_lock_swmr_concur(hid_t in_fapl) /* Should fail */ if(child_fid == FAIL) HDexit(EXIT_SUCCESS); + + /* Close the pipe */ + if(HDclose(out_pdf[0]) < 0) + HDexit(EXIT_FAILURE); + HDexit(EXIT_FAILURE); } + /* close unused read end for out_pdf */ + if(HDclose(out_pdf[0]) < 0) + FAIL_STACK_ERROR + /* Open the test file */ if((fid = H5Fopen(filename, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl)) < 0) FAIL_STACK_ERROR - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); + /* Notify child process */ + notify = 1; + if(HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0) + FAIL_STACK_ERROR; + + /* Close the pipe */ + if(HDclose(out_pdf[1]) < 0) + FAIL_STACK_ERROR; /* Wait for child process to complete */ if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) @@ -4969,8 +5535,9 @@ test_file_lock_swmr_concur(hid_t in_fapl) * Case 9: 1) RDONLY|SWMR_READ 2) RDONLY|SWMR_READ : should succeed */ - /* Remove the message file just to be sure */ - HDremove(DONE_MESSAGE); + /* Create 1 pipe */ + if(HDpipe(out_pdf) < 0) + FAIL_STACK_ERROR /* Fork child process */ if((childpid = HDfork()) < 0) @@ -4978,11 +5545,18 @@ test_file_lock_swmr_concur(hid_t in_fapl) if(childpid == 0) { /* Child process */ hid_t child_fid; /* File ID */ + int child_notify = 0; - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) + /* Close unused write end for out_pdf */ + if(HDclose(out_pdf[1]) < 0) HDexit(EXIT_FAILURE); + /* Wait for notification from parent process */ + while(child_notify != 1) { + if(HDread(out_pdf[0], &child_notify, sizeof(int)) < 0) + HDexit(EXIT_FAILURE); + } + /* Open the test file */ H5E_BEGIN_TRY { child_fid = H5Fopen(filename, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl); @@ -4994,15 +5568,30 @@ test_file_lock_swmr_concur(hid_t in_fapl) FAIL_STACK_ERROR HDexit(EXIT_SUCCESS); } + + /* Close the pipe */ + if(HDclose(out_pdf[0]) < 0) + HDexit(EXIT_FAILURE); + HDexit(EXIT_FAILURE); } + /* close unused read end for out_pdf */ + if(HDclose(out_pdf[0]) < 0) + FAIL_STACK_ERROR + /* Open the test file */ if((fid = H5Fopen(filename, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl)) < 0) FAIL_STACK_ERROR - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); + /* Notify child process */ + notify = 1; + if(HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0) + FAIL_STACK_ERROR; + + /* Close the pipe */ + if(HDclose(out_pdf[1]) < 0) + FAIL_STACK_ERROR; /* Wait for child process to complete */ if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) @@ -5024,8 +5613,9 @@ test_file_lock_swmr_concur(hid_t in_fapl) * Case 10: 1) RDONLY|SWMR_READ 2) RDONLY : should succeed */ - /* Remove the message file just to be sure */ - HDremove(DONE_MESSAGE); + /* Create 1 pipe */ + if(HDpipe(out_pdf) < 0) + FAIL_STACK_ERROR /* Fork child process */ if((childpid = HDfork()) < 0) @@ -5033,11 +5623,18 @@ test_file_lock_swmr_concur(hid_t in_fapl) if(childpid == 0) { /* Child process */ hid_t child_fid; /* File ID */ + int child_notify = 0; - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) + /* Close unused write end for out_pdf */ + if(HDclose(out_pdf[1]) < 0) HDexit(EXIT_FAILURE); + /* Wait for notification from parent process */ + while(child_notify != 1) { + if(HDread(out_pdf[0], &child_notify, sizeof(int)) < 0) + HDexit(EXIT_FAILURE); + } + /* Open the test file */ if((child_fid = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR @@ -5048,15 +5645,30 @@ test_file_lock_swmr_concur(hid_t in_fapl) FAIL_STACK_ERROR HDexit(EXIT_SUCCESS); } + + /* Close the pipe */ + if(HDclose(out_pdf[0]) < 0) + HDexit(EXIT_FAILURE); + HDexit(EXIT_FAILURE); } + /* close unused read end for out_pdf */ + if(HDclose(out_pdf[0]) < 0) + FAIL_STACK_ERROR + /* Open the test file */ if((fid = H5Fopen(filename, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl)) < 0) FAIL_STACK_ERROR - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); + /* Notify child process */ + notify = 1; + if(HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0) + FAIL_STACK_ERROR; + + /* Close the pipe */ + if(HDclose(out_pdf[1]) < 0) + FAIL_STACK_ERROR; /* Wait for child process to complete */ if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) @@ -5078,8 +5690,9 @@ test_file_lock_swmr_concur(hid_t in_fapl) * Case 11: 1) RDONLY 2) RDWR|SWMR_WRITE : should fail */ - /* Remove the message file just to be sure */ - HDremove(DONE_MESSAGE); + /* Create 1 pipe */ + if(HDpipe(out_pdf) < 0) + FAIL_STACK_ERROR /* Fork child process */ if((childpid = HDfork()) < 0) @@ -5087,11 +5700,18 @@ test_file_lock_swmr_concur(hid_t in_fapl) if(childpid == 0) { /* Child process */ hid_t child_fid; /* File ID */ + int child_notify = 0; - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) + /* Close unused write end for out_pdf */ + if(HDclose(out_pdf[1]) < 0) HDexit(EXIT_FAILURE); + /* Wait for notification from parent process */ + while(child_notify != 1) { + if(HDread(out_pdf[0], &child_notify, sizeof(int)) < 0) + HDexit(EXIT_FAILURE); + } + /* Open the test file */ H5E_BEGIN_TRY { child_fid = H5Fopen(filename, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl); @@ -5100,15 +5720,30 @@ test_file_lock_swmr_concur(hid_t in_fapl) /* Should fail */ if(child_fid == FAIL) HDexit(EXIT_SUCCESS); + + /* Close the pipe */ + if(HDclose(out_pdf[0]) < 0) + HDexit(EXIT_FAILURE); + HDexit(EXIT_FAILURE); } + /* Close unused read end for out_pdf */ + if(HDclose(out_pdf[0]) < 0) + FAIL_STACK_ERROR + /* Open the test file */ if((fid = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); + /* Notify child process */ + notify = 1; + if(HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0) + FAIL_STACK_ERROR; + + /* Close the pipe */ + if(HDclose(out_pdf[1]) < 0) + FAIL_STACK_ERROR; /* Wait for child process to complete */ if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) @@ -5130,8 +5765,9 @@ test_file_lock_swmr_concur(hid_t in_fapl) * Case 12: 1) RDONLY 2) RDONLY|SWMR_READ : should succeed */ - /* Remove the message file just to be sure */ - HDremove(DONE_MESSAGE); + /* Create 1 pipe */ + if(HDpipe(out_pdf) < 0) + FAIL_STACK_ERROR /* Fork child process */ if((childpid = HDfork()) < 0) @@ -5139,11 +5775,18 @@ test_file_lock_swmr_concur(hid_t in_fapl) if(childpid == 0) { /* Child process */ hid_t child_fid; /* File ID */ + int child_notify = 0; - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) + /* Close unused write end for out_pdf */ + if(HDclose(out_pdf[1]) < 0) HDexit(EXIT_FAILURE); + /* Wait for notification from parent process */ + while(child_notify != 1) { + if(HDread(out_pdf[0], &child_notify, sizeof(int)) < 0) + HDexit(EXIT_FAILURE); + } + /* Open the test file */ H5E_BEGIN_TRY { child_fid = H5Fopen(filename, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl); @@ -5155,15 +5798,30 @@ test_file_lock_swmr_concur(hid_t in_fapl) FAIL_STACK_ERROR HDexit(EXIT_SUCCESS); } + + /* Close the pipe */ + if(HDclose(out_pdf[0]) < 0) + HDexit(EXIT_FAILURE); + HDexit(EXIT_FAILURE); } + /* close unused read end for out_pdf */ + if(HDclose(out_pdf[0]) < 0) + FAIL_STACK_ERROR + /* Open the test file */ if((fid = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); + /* Notify child process */ + notify = 1; + if(HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0) + FAIL_STACK_ERROR; + + /* Close the pipe */ + if(HDclose(out_pdf[1]) < 0) + FAIL_STACK_ERROR; /* Wait for child process to complete */ if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) @@ -5364,6 +6022,664 @@ error: } /* test_bug_refresh() */ #endif /* OUT */ +/* + * test_refresh_concur(): + * + * The "new_format" parameter indicates whether to create the file with latest format or not. + * To have SWMR support, can use either one of the following in creating a file: + * (a) Create the file with write + latest format: + * --result in v3 superblock with latest chunk indexing types + * (b) Create the file with SWMR write + non-latest-format: + * --result in v3 superblock with latest chunk indexing types + * + * Verify H5Drefresh() works correctly with concurrent access: + * Parent process: + * (1) Open the test file, write to the dataset + * (2) Notify child process #A + * (3) Wait for notification from child process #B + * (4) Extend the dataset, write to the dataset, flush the file + * (5) Notify child process #C + * Child process: + * (1) Wait for notification from parent process #A + * (2) Open the file 2 times + * (3) Open the dataset 2 times with the 2 files + * (4) Verify the dataset's dimension and data read are correct + * (5) Notify parent process #B + * (6) Wait for notification from parent process #C + * (7) Refresh the dataset + * (8) Verify the dataset's dimension and data are correct + */ +#if !(defined(H5_HAVE_FORK) && defined(H5_HAVE_WAITPID)) + +static int +test_refresh_concur(hid_t H5_ATTR_UNUSED in_fapl, hbool_t H5_ATTR_UNUSED new_format) +{ + SKIPPED(); + HDputs(" Test skipped due to fork or waitpid not defined."); + return 0; +} /* test_refresh_concur() */ + +#else /* defined(H5_HAVE_FORK && defined(H5_HAVE_WAITPID) */ + +static int +test_refresh_concur(hid_t in_fapl, hbool_t new_format) +{ + hid_t fid; /* File ID */ + hid_t fapl; /* File access property list */ + pid_t childpid=0; /* Child process ID */ + pid_t tmppid; /* Child process ID returned by waitpid */ + int child_status; /* Status passed to waitpid */ + int child_wait_option=0; /* Options passed to waitpid */ + int child_exit_val; /* Exit status of the child */ + char filename[NAME_BUF_SIZE]; /* File name */ + + hid_t did = -1; + hid_t sid = -1; + hid_t dcpl = -1; + hsize_t chunk_dims[1] = {1}; + hsize_t maxdims[1] = {H5S_UNLIMITED}; + hsize_t dims[1] = { 1 }; + hsize_t new_dims[1] = {2}; + + int out_pdf[2]; + int in_pdf[2]; + int notify = 0; + int wbuf[2]; + + /* Output message about test being performed */ + if(new_format) { + TESTING("H5Drefresh()--concurrent access for latest format"); + } else { + TESTING("H5Drefresh()--concurrent access for non-latest-format"); + } /* end if */ + + + if((fapl = H5Pcopy(in_fapl)) < 0) + FAIL_STACK_ERROR + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + if(new_format) { + /* Set to use the latest library format */ + if(H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) + FAIL_STACK_ERROR + + /* Create the test file */ + if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + } else { + /* Create the test file without latest format but with SWMR write */ + if((fid = H5Fcreate(filename, H5F_ACC_TRUNC|H5F_ACC_SWMR_WRITE, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + } /* end if */ + + /* Create a chunked dataset with 1 extendible dimension */ + if((sid = H5Screate_simple(1, dims, maxdims)) < 0) + FAIL_STACK_ERROR; + if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + FAIL_STACK_ERROR + if(H5Pset_chunk(dcpl, 1, chunk_dims) < 0) + FAIL_STACK_ERROR; + if((did = H5Dcreate2(fid, "dataset", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR; + + /* Closing */ + if(H5Dclose(did) < 0) + FAIL_STACK_ERROR + if(H5Sclose(sid) < 0) + FAIL_STACK_ERROR + if(H5Pclose(dcpl) < 0) + FAIL_STACK_ERROR + + /* Close the file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* Create 2 pipes */ + if(HDpipe(out_pdf) < 0) + FAIL_STACK_ERROR + if(HDpipe(in_pdf) < 0) + FAIL_STACK_ERROR + + /* Fork child process */ + if((childpid = HDfork()) < 0) + FAIL_STACK_ERROR + + if(childpid == 0) { /* Child process */ + hid_t child_fid1 = -1; /* File ID */ + hid_t child_fid2 = -1; /* File ID */ + hid_t child_did1 = -1, child_did2 = -1; + hid_t child_sid = -1; + hsize_t tdims[1]; + int rbuf[2] = {0, 0}; + int child_notify = 0; + + /* Close unused write end for out_pdf */ + if(HDclose(out_pdf[1]) < 0) + HDexit(EXIT_FAILURE); + + /* close unused read end for in_pdf */ + if(HDclose(in_pdf[0]) < 0) + HDexit(EXIT_FAILURE); + + /* Wait for notification from parent process */ + while(child_notify != 1) { + if(HDread(out_pdf[0], &child_notify, sizeof(int)) < 0) + HDexit(EXIT_FAILURE); + } + + /* Open the file 2 times */ + if((child_fid1 = H5Fopen(filename, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl)) < 0) + HDexit(EXIT_FAILURE); + + if((child_fid2 = H5Fopen(filename, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl)) < 0) + HDexit(EXIT_FAILURE); + + /* Open the dataset 2 times */ + if((child_did1 = H5Dopen2(child_fid1, "dataset", H5P_DEFAULT)) < 0) + HDexit(EXIT_FAILURE); + if((child_did2 = H5Dopen2(child_fid2, "dataset", H5P_DEFAULT)) < 0) + HDexit(EXIT_FAILURE); + + /* Get the dataset's dataspace via did1 */ + if((child_sid = H5Dget_space(child_did1)) < 0) + HDexit(EXIT_FAILURE); + if(H5Sget_simple_extent_dims(child_sid, tdims, NULL) < 0) + HDexit(EXIT_FAILURE); + if(tdims[0] != 1) + HDexit(EXIT_FAILURE); + + /* Read from the dataset via did2 */ + if(H5Dread(child_did2, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf) < 0) + HDexit(EXIT_FAILURE); + + /* Verify the data is correct */ + if(rbuf[0] != 99) + HDexit(EXIT_FAILURE); + + /* Notify parent process */ + child_notify = 2; + if(HDwrite(in_pdf[1], &child_notify, sizeof(int)) < 0) + HDexit(EXIT_FAILURE); + + /* Wait for notification from parent process */ + while(child_notify != 3) { + if(HDread(out_pdf[0], &child_notify, sizeof(int)) < 0) + HDexit(EXIT_FAILURE); + } + + /* Refresh dataset via did1 */ + if(H5Drefresh(child_did1) < 0) + HDexit(EXIT_FAILURE); + + /* Get the dataset's dataspace and verify */ + if((child_sid = H5Dget_space(child_did1)) < 0) + HDexit(EXIT_FAILURE); + if(H5Sget_simple_extent_dims(child_sid, tdims, NULL) < 0) + HDexit(EXIT_FAILURE); + + if(tdims[0] != 2) + HDexit(EXIT_FAILURE); + + /* Read from the dataset */ + if(H5Dread(child_did2, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf) < 0) + HDexit(EXIT_FAILURE); + + /* Verify the data is correct */ + if(rbuf[0] != 100 || rbuf[1] != 100) + HDexit(EXIT_FAILURE); + + /* Close the 2 datasets */ + if(H5Dclose(child_did1) < 0) + HDexit(EXIT_FAILURE); + if(H5Dclose(child_did2) < 0) + HDexit(EXIT_FAILURE); + + /* Close the 2 files */ + if(H5Fclose(child_fid1) < 0) + HDexit(EXIT_FAILURE); + if(H5Fclose(child_fid2) < 0) + HDexit(EXIT_FAILURE); + + /* Close the pipes */ + if(HDclose(out_pdf[0]) < 0) + HDexit(EXIT_FAILURE); + if(HDclose(in_pdf[1]) < 0) + HDexit(EXIT_FAILURE); + + HDexit(EXIT_SUCCESS); + } + + /* Close unused read end for out_pdf */ + if(HDclose(out_pdf[0]) < 0) + FAIL_STACK_ERROR + /* Close unused write end for in_pdf */ + if(HDclose(in_pdf[1]) < 0) + FAIL_STACK_ERROR + + /* Open the test file */ + if((fid = H5Fopen(filename, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl)) < 0) + FAIL_STACK_ERROR + + /* Open the dataset */ + if((did = H5Dopen2(fid, "dataset", H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR; + + /* Write to the dataset */ + wbuf[0] = wbuf[1] = 99; + if(H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf) < 0) + FAIL_STACK_ERROR; + + /* Flush to disk */ + if(H5Fflush(fid, H5F_SCOPE_LOCAL) < 0) + FAIL_STACK_ERROR; + + /* Notify child process */ + notify = 1; + if(HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0) + FAIL_STACK_ERROR; + + + /* Wait for notification from child process */ + while(notify != 2) { + if(HDread(in_pdf[0], ¬ify, sizeof(int)) < 0) + FAIL_STACK_ERROR; + } + + /* Extend the dataset */ + if(H5Dset_extent(did, new_dims) < 0) + FAIL_STACK_ERROR; + + /* Write to the dataset */ + wbuf[0] = wbuf[1] = 100; + if(H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf) < 0) + FAIL_STACK_ERROR; + + /* Flush to disk */ + if(H5Fflush(fid, H5F_SCOPE_LOCAL) < 0) + FAIL_STACK_ERROR; + + /* Notify child process */ + notify = 3; + if(HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0) + FAIL_STACK_ERROR; + + /* Close the pipes */ + if(HDclose(out_pdf[1]) < 0) + FAIL_STACK_ERROR; + if(HDclose(in_pdf[0]) < 0) + FAIL_STACK_ERROR; + + /* Wait for child process to complete */ + if((tmppid = HDwaitpid(childpid, &child_status, child_wait_option)) < 0) + FAIL_STACK_ERROR + + /* Check exit status of child process */ + if(WIFEXITED(child_status)) { + if((child_exit_val = WEXITSTATUS(child_status)) != 0) + TEST_ERROR + } else /* Child process terminated abnormally */ + TEST_ERROR + + /* Close the dataset */ + if(H5Dclose(did) < 0) + FAIL_STACK_ERROR + + /* Close the file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* Close the property list */ + if(H5Pclose(fapl) < 0) + FAIL_STACK_ERROR + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Dclose(did); + H5Sclose(sid); + H5Pclose(dcpl); + H5Pclose(fapl); + H5Fclose(fid); + } H5E_END_TRY; + + return -1; + +} /* test_refresh_concur() */ +#endif /* !(defined(H5_HAVE_FORK) && defined(H5_HAVE_WAITPID)) */ + +/* + * test_multiple_same(): + * + * The "new_format" parameter indicates whether to create the file with latest format or not. + * To have SWMR support, can use either one of the following in creating a file: + * (a) Create the file with write + latest format: + * --result in v3 superblock with latest chunk indexing types + * (b) Create the file with SWMR write + non-latest-format: + * --result in v3 superblock with latest chunk indexing types + * + * Verify that H5Drefresh() and H5Fstart_swmr_write() work properly with multiple + * opens of files and datasets. + */ +static int +test_multiple_same(hid_t in_fapl, hbool_t new_format) +{ + hid_t fid = -1, fid1 = -1, fid2 = -1, fid3 = -1; /* File IDs */ + hid_t fapl; /* File access property list */ + char filename[NAME_BUF_SIZE]; /* File name */ + hid_t did = -1, did1 = -1, did2 = -1, did3 = -1; + hid_t sid = -1; + hid_t dcpl = -1; + hsize_t chunk_dims[2] = {1, 2}; + hsize_t maxdims[2] = {H5S_UNLIMITED, H5S_UNLIMITED}; + hsize_t dims[2] = {1, 1}; + int rbuf = 0; + int wbuf = 0; + + /* Output message about test being performed */ + if(new_format) { + TESTING("multiple--single process access for latest format"); + } else { + TESTING("multiple--single process access for non-latest-format"); + } /* end if */ + + + if((fapl = H5Pcopy(in_fapl)) < 0) + FAIL_STACK_ERROR + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + if(new_format) { + /* Set to use the latest library format */ + if(H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) + FAIL_STACK_ERROR + + /* Create the test file */ + if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + } else { + /* Create the test file without latest format but with SWMR write */ + if((fid = H5Fcreate(filename, H5F_ACC_TRUNC|H5F_ACC_SWMR_WRITE, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + } /* end if */ + + /* Create a chunked dataset with 1 extendible dimension */ + if((sid = H5Screate_simple(2, dims, maxdims)) < 0) + FAIL_STACK_ERROR; + if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + FAIL_STACK_ERROR + if(H5Pset_chunk(dcpl, 2, chunk_dims) < 0) + FAIL_STACK_ERROR; + if((did = H5Dcreate2(fid, "dataset", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR; + + /* Closing */ + if(H5Dclose(did) < 0) + FAIL_STACK_ERROR + if(H5Sclose(sid) < 0) + FAIL_STACK_ERROR + if(H5Pclose(dcpl) < 0) + FAIL_STACK_ERROR + + /* Close the file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* Case 1 */ + + /* Open the file 3 times: SWMR-write, read-write, read-only */ + if((fid1 = H5Fopen(filename, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl)) < 0) + FAIL_STACK_ERROR + if((fid2 = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + if((fid3 = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) + FAIL_STACK_ERROR + + /* Open the dataset 3 times with fid1, fid2, fid3 */ + if((did1 = H5Dopen2(fid1, "dataset", H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR + if((did2 = H5Dopen2(fid2, "dataset", H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR + if((did3 = H5Dopen2(fid3, "dataset", H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR + + + /* Write to the dataset via did1 */ + wbuf = 88; + if(H5Dwrite(did1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wbuf) < 0) + FAIL_STACK_ERROR; + + /* Refresh via did2 */ + if(H5Drefresh(did2) < 0) + FAIL_STACK_ERROR; + + /* Read from the dataset via did2 */ + rbuf = 0; + if(H5Dread(did2, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rbuf) < 0) + FAIL_STACK_ERROR; + /* Verify the data is correct */ + if(rbuf != 88) + FAIL_STACK_ERROR; + + /* Write to the dataset via did3 */ + wbuf = 99; + if(H5Dwrite(did3, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wbuf) < 0) + FAIL_STACK_ERROR; + + /* Refresh via did1 */ + if(H5Drefresh(did1) < 0) + FAIL_STACK_ERROR; + + /* Read from the dataset via did1 */ + rbuf = 0; + if(H5Dread(did1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rbuf) < 0) + FAIL_STACK_ERROR; + /* Verify the data is correct */ + if(rbuf != 99) + FAIL_STACK_ERROR; + + /* Close datasets */ + if(H5Dclose(did1) < 0) + FAIL_STACK_ERROR; + if(H5Dclose(did2) < 0) + FAIL_STACK_ERROR; + if(H5Dclose(did3) < 0) + FAIL_STACK_ERROR; + + /* Close files */ + if(H5Fclose(fid1) < 0) + FAIL_STACK_ERROR + if(H5Fclose(fid2) < 0) + FAIL_STACK_ERROR + if(H5Fclose(fid3) < 0) + FAIL_STACK_ERROR + + /* Case 2 */ + + /* Open the file 3 times: read-write, read-only, read-write */ + if((fid1 = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + if((fid2 = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) + FAIL_STACK_ERROR + if((fid3 = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Open the dataset 3 times with fid1, fid2, fid3 */ + if((did1 = H5Dopen2(fid1, "dataset", H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR + if((did2 = H5Dopen2(fid2, "dataset", H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR + if((did3 = H5Dopen2(fid3, "dataset", H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR + + /* Write to the dataset via did1 */ + wbuf = 88; + if(H5Dwrite(did1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wbuf) < 0) + FAIL_STACK_ERROR; + + /* Refresh via did2 */ + if(H5Drefresh(did2) < 0) + FAIL_STACK_ERROR; + + /* Read from dataset via did2 */ + rbuf = 0; + if(H5Dread(did2, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rbuf) < 0) + FAIL_STACK_ERROR; + if(rbuf != wbuf) + FAIL_STACK_ERROR; + + /* Write to dataset via did3 */ + wbuf = 99; + if(H5Dwrite(did3, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wbuf) < 0) + FAIL_STACK_ERROR; + + /* Enable SWMR write */ + if(H5Fstart_swmr_write(fid1) < 0) + FAIL_STACK_ERROR; + + /* Read from dataset via did1 and verify data is correct */ + rbuf = 0; + if(H5Dread(did1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rbuf) < 0) + FAIL_STACK_ERROR; + if(rbuf != wbuf) + FAIL_STACK_ERROR; + + /* Write to dataset via did2 */ + wbuf = 100; + if(H5Dwrite(did2, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wbuf) < 0) + FAIL_STACK_ERROR; + + /* Refresh dataset via did3 */ + if(H5Drefresh(did3) < 0) + FAIL_STACK_ERROR; + + /* Read from dataset via did3 and verify data is correct */ + rbuf = 0; + if(H5Dread(did3, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rbuf) < 0) + FAIL_STACK_ERROR; + if(rbuf != wbuf) + FAIL_STACK_ERROR; + + /* Close datasets */ + if(H5Dclose(did1) < 0) + FAIL_STACK_ERROR; + if(H5Dclose(did2) < 0) + FAIL_STACK_ERROR; + if(H5Dclose(did3) < 0) + FAIL_STACK_ERROR; + + /* Close files */ + if(H5Fclose(fid1) < 0) + FAIL_STACK_ERROR + if(H5Fclose(fid2) < 0) + FAIL_STACK_ERROR; + if(H5Fclose(fid3) < 0) + FAIL_STACK_ERROR + + /* Case 3 */ + + /* Open the file 3 times: read-write, read-only, read-only */ + if((fid1 = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + if((fid2 = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) + FAIL_STACK_ERROR + if((fid3 = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) + FAIL_STACK_ERROR + + /* Open the dataset 3 times with fid1, fid2, fid3 */ + if((did1 = H5Dopen2(fid1, "dataset", H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR + if((did2 = H5Dopen2(fid2, "dataset", H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR + if((did3 = H5Dopen2(fid3, "dataset", H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR + + /* Write to the dataset via did1 */ + wbuf = 88; + if(H5Dwrite(did1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wbuf) < 0) + FAIL_STACK_ERROR; + + /* Refresh dataset via did2 */ + if(H5Drefresh(did2) < 0) + FAIL_STACK_ERROR; + + /* Read from dataset via did2 and verify data is correct */ + rbuf = 0; + if(H5Dread(did2, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rbuf) < 0) + FAIL_STACK_ERROR; + if(rbuf != wbuf) + FAIL_STACK_ERROR; + + /* Close dataset via did2 */ + if(H5Dclose(did2) < 0) + FAIL_STACK_ERROR; + + /* Close file via fid2 */ + if(H5Fclose(fid2) < 0) + FAIL_STACK_ERROR + + /* Write to dataset via did3 */ + wbuf = 99; + if(H5Dwrite(did3, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wbuf) < 0) + FAIL_STACK_ERROR; + + /* Close dataset via did3 */ + if(H5Dclose(did3) < 0) + FAIL_STACK_ERROR; + + /* Close file via fid3 */ + if(H5Fclose(fid3) < 0) + FAIL_STACK_ERROR + + /* Enable SWMR writing */ + if(H5Fstart_swmr_write(fid1) < 0) + FAIL_STACK_ERROR; + + /* Read from dataset via did1 and verify data is correct */ + rbuf = 0; + if(H5Dread(did1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rbuf) < 0) + FAIL_STACK_ERROR; + if(rbuf != wbuf) + FAIL_STACK_ERROR; + + /* Close dataset via did1 */ + if(H5Dclose(did1) < 0) + FAIL_STACK_ERROR; + + /* Close file via fid1 */ + if(H5Fclose(fid1) < 0) + FAIL_STACK_ERROR + + /* Close the property list */ + if(H5Pclose(fapl) < 0) + FAIL_STACK_ERROR + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Dclose(did); + H5Dclose(did1); + H5Dclose(did2); + H5Dclose(did3); + H5Sclose(sid); + H5Pclose(dcpl); + H5Pclose(fapl); + H5Fclose(fid); + H5Fclose(fid1); + H5Fclose(fid2); + H5Fclose(fid3); + } H5E_END_TRY; + + return -1; + +} /* test_multiple_same() */ + /**************************************************************** ** ** Tests for new public routines introduced from the SWMR project. @@ -5394,6 +6710,10 @@ main(void) #ifdef OUT nerrors += test_bug_refresh(fapl); #endif + nerrors += test_refresh_concur(fapl, TRUE); + nerrors += test_refresh_concur(fapl, FALSE); + nerrors += test_multiple_same(fapl, TRUE); + nerrors += test_multiple_same(fapl, FALSE); /* Tests on H5Pget/set_metadata_read_attempts() and H5Fget_metadata_read_retry_info() */ nerrors += test_metadata_read_attempts(fapl); @@ -5447,7 +6767,7 @@ main(void) nerrors += test_swmr_vfd_flag(); if(nerrors) - goto error; + goto error; printf("All tests passed.\n"); -- cgit v0.12