diff options
author | Vailin Choi <vchoi@hdfgroup.org> | 2015-08-07 03:03:43 (GMT) |
---|---|---|
committer | Vailin Choi <vchoi@hdfgroup.org> | 2015-08-07 03:03:43 (GMT) |
commit | 53b4670997cd563c5b26bcbddd0f479b4c8ce247 (patch) | |
tree | b42f02b3fb0517db503300cc897e92455bbd4689 | |
parent | 1c57b2f174e62dcfe58c0338651f35fced09087d (diff) | |
download | hdf5-53b4670997cd563c5b26bcbddd0f479b4c8ce247.zip hdf5-53b4670997cd563c5b26bcbddd0f479b4c8ce247.tar.gz hdf5-53b4670997cd563c5b26bcbddd0f479b4c8ce247.tar.bz2 |
[svn-r27476] Fixes:
1. Fix for SWMR-88: move the 4 tests for file locking from tfile.c to swmr.c
2. H5SMcache.c: restore a line that got removed from previous merges.
3. H5Dproxy.c: delete; not needed
4. Refactor coding in H5C.c: H5C_make space_in_cache() and H5C_evict_tagged_entries()
Tested on jam, koala, ostrich, platypus, moohan, quail.
-rw-r--r-- | src/H5C.c | 268 | ||||
-rw-r--r-- | src/H5Dproxy.c | 612 | ||||
-rw-r--r-- | src/H5Oflush.c | 60 | ||||
-rw-r--r-- | src/H5Oprivate.h | 1 | ||||
-rw-r--r-- | src/H5SMcache.c | 3 | ||||
-rw-r--r-- | test/swmr.c | 1461 | ||||
-rw-r--r-- | test/tfile.c | 1415 |
7 files changed, 1605 insertions, 2215 deletions
@@ -9224,21 +9224,17 @@ H5C_make_space_in_cache(H5F_t * f, prev_is_dirty = prev_ptr->is_dirty; } - if ( (entry_ptr->type)->id == H5C__EPOCH_MARKER_TYPE) { - /* Skip epoch markers. Set result to SUCCEED to avoid - * triggering the error code below. - */ - didnt_flush_entry = TRUE; - result = SUCCEED; - } else if (entry_ptr->is_corked && entry_ptr->is_dirty) { + if (entry_ptr->is_corked && entry_ptr->is_dirty) { + /* Skip "dirty" corked entries. Set result to SUCCEED to avoid * triggering the error code below. */ ++num_corked_entries; didnt_flush_entry = TRUE; result = SUCCEED; - } else { + + } else if ( (entry_ptr->type)->id != H5C__EPOCH_MARKER_TYPE) { didnt_flush_entry = FALSE; @@ -9294,7 +9290,14 @@ H5C_make_space_in_cache(H5F_t * f, total_entries_scanned++; #endif /* H5C_COLLECT_CACHE_STATS */ - } + } else { + + /* Skip epoch markers. Set result to SUCCEED to avoid + * triggering the error code below. + */ + didnt_flush_entry = TRUE; + result = SUCCEED; + } if ( result < 0 ) { @@ -10120,9 +10123,9 @@ done: /*------------------------------------------------------------------------- * - * Function: H5C_flush_tagged_entries + * Function: H5C_evict_tagged_entries * - * Purpose: Flushes all entries with the specified tag to disk. + * Purpose: Evicts all entries with the specified tag from cache * * Return: FAIL if error is detected, SUCCEED otherwise. * @@ -10132,13 +10135,21 @@ done: *------------------------------------------------------------------------- */ herr_t -H5C_flush_tagged_entries(H5F_t * f, hid_t primary_dxpl_id, hid_t secondary_dxpl_id, haddr_t tag) +H5C_evict_tagged_entries(H5F_t * f, hid_t primary_dxpl_id, hid_t secondary_dxpl_id, haddr_t tag) { /* Variable Declarations */ + herr_t status; + H5C_cache_entry_t * entry_ptr = NULL; + H5C_cache_entry_t * next_entry_ptr = NULL; + int i; + hbool_t evicted_entries_last_pass; + hbool_t pinned_entries_need_evicted; + hbool_t first_flush = TRUE; + H5C_t *cache_ptr = NULL; - herr_t result; - herr_t ret_value = SUCCEED; + herr_t ret_value = SUCCEED; + /* Function Enter Macro */ FUNC_ENTER_NOAPI(FAIL) /* Assertions */ @@ -10148,65 +10159,84 @@ H5C_flush_tagged_entries(H5F_t * f, hid_t primary_dxpl_id, hid_t secondary_dxpl_ /* Get cache pointer */ cache_ptr = f->shared->cache; - /* Mark all entries with specified tag */ - if ( (result = H5C_mark_tagged_entries(cache_ptr, tag, FALSE)) < 0 ) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't mark tagged entries") + HDassert( cache_ptr != NULL ); + HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC ); - /* Flush all marked entries */ - if(H5C_flush_marked_entries(f, primary_dxpl_id, secondary_dxpl_id, cache_ptr) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush marked entries") + /* Start evicting entries */ + do { -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5C_flush_tagged_entries */ + /* Reset pinned/evicted trackers */ + pinned_entries_need_evicted = FALSE; + evicted_entries_last_pass = FALSE; - -/*------------------------------------------------------------------------- - * - * Function: H5C_evict_tagged_entries - * - * Purpose: Evicts all entries with the specified tag to disk. - * - * Return: FAIL if error is detected, SUCCEED otherwise. - * - * Programmer: Mike McGreevy - * August 19, 2010 - * - *------------------------------------------------------------------------- - */ -herr_t -H5C_evict_tagged_entries(H5F_t * f, hid_t primary_dxpl_id, hid_t secondary_dxpl_id, haddr_t tag) -{ - /* Variables */ - H5C_t *cache_ptr = NULL; - herr_t result; - herr_t ret_value = SUCCEED; + /* Iterate through entries in the index. */ + for (i = 0; i < H5C__HASH_TABLE_LEN; i++) { - /* Function Enter Macro */ - FUNC_ENTER_NOAPI(FAIL) + next_entry_ptr = cache_ptr->index[i]; - /* Assertions */ - HDassert(f); - HDassert(f->shared); + while ( next_entry_ptr != NULL ) { - /* Get cache pointer */ - cache_ptr = f->shared->cache; + entry_ptr = next_entry_ptr; + next_entry_ptr = entry_ptr->ht_next; - /* Mark all entries with specified tag */ - if ( (result = H5C_mark_tagged_entries(cache_ptr, tag, TRUE)) < 0 ) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't mark tagged entries") + if(( entry_ptr->tag == tag ) || + ( entry_ptr->globality == H5C_GLOBALITY_MAJOR)) { - /* Evict all marked entries */ - if ( (result = H5C_evict_marked_entries(f, - primary_dxpl_id, - secondary_dxpl_id, - cache_ptr)) < 0 ) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't evict marked entries") + /* This entry will need to be evicted */ + + if ( entry_ptr->is_protected ) { + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Cannot evict protected entry"); + } else if (entry_ptr->is_dirty) { + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Cannot evict dirty entry"); + } else if (entry_ptr->is_pinned) { + + /* Can't evict at this time, but let's note that we hit a pinned + entry and we'll loop back around again (as evicting other + entries will hopefully unpin this entry) */ + + pinned_entries_need_evicted = TRUE; + + } else { + + /* Evict the Entry */ + + status = H5C_flush_single_entry(f, + primary_dxpl_id, + secondary_dxpl_id, + entry_ptr->type, + entry_ptr->addr, + H5C__FLUSH_INVALIDATE_FLAG | H5C__FLUSH_CLEAR_ONLY_FLAG, + &first_flush, + TRUE); + + if ( status < 0 ) { + + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \ + "Entry eviction failed.") + + } + + evicted_entries_last_pass = TRUE; + + } /* end if */ + + } /* end if */ + + } /* end while */ + + } /* end for */ + + /* Keep doing this until we have stopped evicted entries */ + } while ((evicted_entries_last_pass == TRUE)); + + /* If we stop evicting entries and pinned entries still need evicted, + then we have a problem. */ + if (pinned_entries_need_evicted) { + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Pinned entries still need evicted?!"); + } /* end if */ done: - - /* Function Leave Macro */ - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI(ret_value); } /* H5C_evict_tagged_entries */ @@ -10307,113 +10337,45 @@ done: /*------------------------------------------------------------------------- * - * Function: H5C_evict_marked_entries + * Function: H5C_flush_tagged_entries * - * Purpose: Evicts all marked entries in the cache. + * Purpose: Flushes all entries with the specified tag to disk. * * Return: FAIL if error is detected, SUCCEED otherwise. * * Programmer: Mike McGreevy - * July 16, 2010 + * August 19, 2010 * *------------------------------------------------------------------------- */ -static herr_t -H5C_evict_marked_entries(H5F_t * f, hid_t primary_dxpl_id, hid_t secondary_dxpl_id, H5C_t * cache_ptr) -{ +herr_t +H5C_flush_tagged_entries(H5F_t * f, hid_t primary_dxpl_id, hid_t secondary_dxpl_id, haddr_t tag) +{ /* Variable Declarations */ - herr_t status; - herr_t ret_value = SUCCEED; - H5C_cache_entry_t * entry_ptr = NULL; - H5C_cache_entry_t * next_entry_ptr = NULL; - int i; - hbool_t evicted_entries_last_pass; - hbool_t pinned_entries_need_evicted; - hbool_t first_flush = TRUE; + H5C_t *cache_ptr = NULL; + herr_t result; + herr_t ret_value = SUCCEED; - /* Function Enter Macro */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_NOAPI(FAIL) /* Assertions */ - HDassert( cache_ptr != NULL ); - HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC ); - - /* Start evicting entries */ - do { - - /* Reset pinned/evicted trackers */ - pinned_entries_need_evicted = FALSE; - evicted_entries_last_pass = FALSE; - - /* Iterate through entries in the index. */ - for (i = 0; i < H5C__HASH_TABLE_LEN; i++) { - - next_entry_ptr = cache_ptr->index[i]; - - while ( next_entry_ptr != NULL ) { - - entry_ptr = next_entry_ptr; - next_entry_ptr = entry_ptr->ht_next; - - if ( entry_ptr->flush_marker == TRUE ) { - - /* This entry will need to be evicted */ - - if ( entry_ptr->is_protected ) { - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Cannot evict protected entry"); - } else if (entry_ptr->is_dirty) { - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Cannot evict dirty entry"); - } else if (entry_ptr->is_pinned) { - - /* Can't evict at this time, but let's note that we hit a pinned - entry and we'll loop back around again (as evicting other - entries will hopefully unpin this entry) */ - - pinned_entries_need_evicted = TRUE; - - } else { - - /* Evict the Entry */ - - status = H5C_flush_single_entry(f, - primary_dxpl_id, - secondary_dxpl_id, - entry_ptr->type, - entry_ptr->addr, - H5C__FLUSH_INVALIDATE_FLAG | H5C__FLUSH_CLEAR_ONLY_FLAG, - &first_flush, - TRUE); - - if ( status < 0 ) { - - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \ - "Entry eviction failed.") - - } - - evicted_entries_last_pass = TRUE; - - } /* end if */ - - } /* end if */ - - } /* end while */ + HDassert(f); + HDassert(f->shared); - } /* end for */ + /* Get cache pointer */ + cache_ptr = f->shared->cache; - /* Keep doing this until we have stopped evicted entries */ - } while ((evicted_entries_last_pass == TRUE)); + /* Mark all entries with specified tag */ + if((result = H5C_mark_tagged_entries(cache_ptr, tag, FALSE)) < 0 ) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't mark tagged entries") - /* If we stop evicting entries and pinned entries still need evicted, - then we have a problem. */ - if (pinned_entries_need_evicted) { - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Pinned entries still need evicted?!"); - } /* end if */ + /* Flush all marked entries */ + if(H5C_flush_marked_entries(f, primary_dxpl_id, secondary_dxpl_id, cache_ptr) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush marked entries") done: - FUNC_LEAVE_NOAPI(ret_value); - -} /* H5C_evict_marked_entries */ + FUNC_LEAVE_NOAPI(ret_value) +} /* H5C_flush_tagged_entries */ /*------------------------------------------------------------------------- diff --git a/src/H5Dproxy.c b/src/H5Dproxy.c deleted file mode 100644 index 3db3cb7..0000000 --- a/src/H5Dproxy.c +++ /dev/null @@ -1,612 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * Copyright by the Board of Trustees of the University of Illinois. * - * All rights reserved. * - * * - * This file is part of HDF5. The full HDF5 copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the files COPYING and Copyright.html. COPYING can be found at the root * - * of the source code distribution tree; Copyright.html can be found at the * - * root level of an installed copy of the electronic HDF5 document set and * - * is linked from the top-level documents page. It can also be found at * - * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * - * access to either file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/*------------------------------------------------------------------------- - * - * Created: H5Dproxy.c - * May 19 2009 - * Quincey Koziol <koziol@hdfgroup.org> - * - * Purpose: Implement dataset's metadata cache proxy cache methods. - * - * Note: Chunk proxies exist only to make integrating the chunk - * cache with the metadata cache's flush dependencies - * easier and less coupled than directly tying them - * together. - * - * Chunk proxies never exist on disk (hence their lack of - * a 'load' callback) and their 'flush' callback just - * triggers a flush of the chunk it's a a proxy for. - * - *------------------------------------------------------------------------- - */ - -/****************/ -/* Module Setup */ -/****************/ - -#define H5D_PACKAGE /*suppress error about including H5Dpkg */ - - -/***********/ -/* Headers */ -/***********/ -#include "H5private.h" /* Generic Functions */ -#include "H5Dpkg.h" /* Dataset functions */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5FLprivate.h" /* Free Lists */ -#include "H5MFprivate.h" /* File memory management */ - - -/****************/ -/* Local Macros */ -/****************/ - - -/******************/ -/* Local Typedefs */ -/******************/ - - -/********************/ -/* Package Typedefs */ -/********************/ - - -/********************/ -/* Local Prototypes */ -/********************/ - -/* Local routines */ -static herr_t H5D__chunk_proxy_destroy(H5D_chunk_proxy_t *proxy); - -/* Metadata cache (H5AC) callbacks */ -static H5D_chunk_proxy_t *H5D__cache_proxy_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata); -static herr_t H5D__cache_proxy_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5D_chunk_proxy_t *proxy, unsigned UNUSED * flags_ptr); -static herr_t H5D__cache_proxy_dest(H5F_t *f, H5D_chunk_proxy_t *proxy); -static herr_t H5D__cache_proxy_clear(H5F_t *f, H5D_chunk_proxy_t *proxy, hbool_t destroy); -static herr_t H5D__cache_proxy_size(const H5F_t *f, const H5D_chunk_proxy_t *proxy, size_t *size_ptr); - - -/*********************/ -/* Package Variables */ -/*********************/ - -/* H5D chunk proxy inherits cache-like properties from H5AC */ -const H5AC_class_t H5AC_CHUNK_PROXY[1] = {{ - H5AC_CHUNK_PROXY_ID, - (H5AC_load_func_t)H5D__cache_proxy_load, - (H5AC_flush_func_t)H5D__cache_proxy_flush, - (H5AC_dest_func_t)H5D__cache_proxy_dest, - (H5AC_clear_func_t)H5D__cache_proxy_clear, - (H5AC_notify_func_t)NULL, - (H5AC_size_func_t)H5D__cache_proxy_size, -}}; - - -/*****************************/ -/* Library Private Variables */ -/*****************************/ - - -/*******************/ -/* Local Variables */ -/*******************/ - -/* Declare a free list to manage H5D_chunk_proxy_t objects */ -H5FL_DEFINE_STATIC(H5D_chunk_proxy_t); - - - -/*------------------------------------------------------------------------- - * Function: H5D__cache_proxy_load - * - * Purpose: Loads a chunk proxy from the disk. - * - * Note: This routine should never be invoked - * - * Return: Success: Pointer to a new chunk proxy - * Failure: NULL - * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * May 21 2009 - * - *------------------------------------------------------------------------- - */ -static H5D_chunk_proxy_t * -H5D__cache_proxy_load(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, haddr_t UNUSED addr, - const void UNUSED *udata) -{ - H5D_chunk_proxy_t *ret_value; /* Return value */ - - FUNC_ENTER_STATIC - - /* This routine should never be invoked! */ - HDassert(0 && "H5D__cache_proxy_load called!?!"); - HGOTO_ERROR(H5E_DATASET, H5E_CANTLOAD, NULL, "unable to load chunk proxy") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5D__cache_proxy_load() */ - - -/*------------------------------------------------------------------------- - * Function: H5D__cache_proxy_flush - * - * Purpose: Proxy for flushing a chunk in chunk cache under control - * of the metadata cache. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * May 19 2009 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5D__cache_proxy_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, - H5D_chunk_proxy_t *proxy, unsigned UNUSED * flags_ptr) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_STATIC -#ifdef QAK -HDfprintf(stderr, "%s: Flushing chunk proxy, addr = %a, destroy = %u\n", FUNC, addr, (unsigned)destroy); -#endif /* QAK */ - - /* check arguments */ - HDassert(f); - HDassert(H5F_addr_defined(addr)); - HDassert(proxy); - - if(proxy->cache_info.is_dirty) { - H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */ - H5D_dxpl_cache_t *dxpl_cache = &_dxpl_cache; /* Data transfer property cache */ - - /* Fill the DXPL cache values for later use */ - if(H5D__get_dxpl_cache(dxpl_id, &dxpl_cache) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't fill dxpl cache") - - /* Flush the chunk for the proxy */ - /* (This must be safe from actually performing I/O when the chunk is - * clean - QAK, 5/21/2009) - */ - if(H5D__chunk_flush_entry(proxy->dset, dxpl_id, dxpl_cache, proxy->ent, FALSE) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "can't flush chunk via proxy") - - /* Mark the chunk proxy as clean now */ - proxy->cache_info.is_dirty = FALSE; - } /* end if */ - - if(destroy) - if(H5D__cache_proxy_dest(f, proxy) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to destroy chunk proxy") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5D__cache_proxy_flush() */ - - -/*------------------------------------------------------------------------- - * Function: H5D__cache_proxy_dest - * - * Purpose: Destroys a chunk proxy in memory. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * May 19 2009 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5D__cache_proxy_dest(H5F_t UNUSED *f, H5D_chunk_proxy_t *proxy) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_STATIC - - /* - * Check arguments. - */ - HDassert(proxy); - - /* Free the chunk proxy itself */ - if(H5D__chunk_proxy_destroy(proxy) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to destroy chunk proxy") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__cache_proxy_dest() */ - - -/*------------------------------------------------------------------------- - * Function: H5D__cache_proxy_clear - * - * Purpose: Mark a chunk proxy in memory as non-dirty. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * May 19 2009 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5D__cache_proxy_clear(H5F_t *f, H5D_chunk_proxy_t *proxy, hbool_t destroy) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_STATIC - - /* - * Check arguments. - */ - HDassert(proxy); - - /* Reset the dirty flag. */ - proxy->cache_info.is_dirty = FALSE; - - if(destroy) - if(H5D__cache_proxy_dest(f, proxy) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to destroy chunk proxy") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__cache_proxy_clear() */ - - -/*------------------------------------------------------------------------- - * Function: H5D__cache_proxy_size - * - * Purpose: Compute the size in bytes of a chunk proxy - * on disk, and return it in *size_ptr. On failure, - * the value of *size_ptr is undefined. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * May 19 2009 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5D__cache_proxy_size(const H5F_t UNUSED *f, const H5D_chunk_proxy_t UNUSED *proxy, - size_t *size_ptr) -{ - FUNC_ENTER_STATIC_NOERR - - /* check arguments */ - HDassert(f); - HDassert(proxy); - HDassert(size_ptr); - - /* Chunk proxies are represented as 1 byte in cache */ - /* (would be 0 bytes, but cache won't allow it currently -QAK, 5/19/09) */ - *size_ptr = 1; - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5D__cache_proxy_size() */ - - -/*------------------------------------------------------------------------- - * Function: H5D__chunk_proxy_create - * - * Purpose: Create a proxy for the chunk and insert it into the metadata cache. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Tuesday, May 19, 2009 - * - *------------------------------------------------------------------------- - */ -herr_t -H5D__chunk_proxy_create(H5D_t *dset, hid_t dxpl_id, H5D_chunk_ud_t *udata, - H5D_rdcc_ent_t *ent) -{ - H5D_chunk_proxy_t *proxy = NULL; /* Chunk proxy */ - H5D_chk_idx_info_t idx_info; /* Chunked index info */ - htri_t supported; /* Return value from "support" callback */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - - HDassert(dset); - HDassert(ent); - HDassert(dset->shared->layout.storage.u.chunk.ops->support); - - /* Get a temp. address for chunk proxy */ - if(HADDR_UNDEF == (ent->proxy_addr = H5MF_alloc_tmp(dset->oloc.file, (hsize_t)1))) - HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "file allocation failed for chunk proxy") -#ifdef QAK -HDfprintf(stderr, "%s: ent->proxy_addr = %a\n", FUNC, ent->proxy_addr); -#endif /* QAK */ - - /* Create chunk proxy object & initialize fields to zero */ - if(NULL == (proxy = H5FL_CALLOC(H5D_chunk_proxy_t))) - HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "can't allocate chunk proxy") - ent->proxy = proxy; - - /* Point chunk proxy to chunk cache entry it's representing and dataset - * it's related to - */ - proxy->dset = dset; - proxy->ent = ent; - - /* Insert chunk proxy into metadata cache, pinned */ - if(H5AC_insert_entry(dset->oloc.file, dxpl_id, H5AC_CHUNK_PROXY, ent->proxy_addr, proxy, H5AC__PIN_ENTRY_FLAG) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't add chunk proxy to cache") - - /* Compose chunked index info struct */ - idx_info.f = dset->oloc.file; - idx_info.dxpl_id = dxpl_id; - idx_info.pline = &(dset->shared->dcpl_cache.pline); - idx_info.layout = &(dset->shared->layout.u.chunk); - idx_info.storage = &(dset->shared->layout.storage.u.chunk); - - /* Create a flush dependency between the proxy (as the child) and the - * metadata object in the index (as the parent). - */ - if((supported = (dset->shared->layout.storage.u.chunk.ops->support)(&idx_info, (H5D_chunk_ud_t *)udata, (H5AC_info_t *)proxy)) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTDEPEND, FAIL, "unable to create flush dependency for chunk proxy") - proxy->supported = (hbool_t)supported; - -done: - if(ret_value < 0) { - if(proxy) - proxy = H5FL_FREE(H5D_chunk_proxy_t, proxy); - ent->proxy_addr = HADDR_UNDEF; - ent->proxy = NULL; - } /* end if */ - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__chunk_proxy_create() */ - - -/*------------------------------------------------------------------------- - * Function: H5D__chunk_proxy_remove - * - * Purpose: Remove a proxy for the chunk from the metadata cache. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Tuesday, May 19, 2009 - * - *------------------------------------------------------------------------- - */ -herr_t -H5D__chunk_proxy_remove(const H5D_t *dset, hid_t dxpl_id, H5D_rdcc_ent_t *ent) -{ - H5D_chk_idx_info_t idx_info; /* Chunked index info */ - H5D_chunk_ud_t udata; /* User-data for chunk */ - H5D_chunk_proxy_t *proxy = NULL; /* Chunk proxy */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - - HDassert(dset); - HDassert(ent); - HDassert(dset->shared->layout.storage.u.chunk.ops->unsupport); -#ifdef QAK -HDfprintf(stderr, "%s: ent->proxy_addr = %a\n", FUNC, ent->proxy_addr); -#endif /* QAK */ - - /* Protect the chunk proxy */ - if(NULL == (proxy = (H5D_chunk_proxy_t *)H5AC_protect(dset->oloc.file, dxpl_id, H5AC_CHUNK_PROXY, ent->proxy_addr, NULL, H5AC_WRITE))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTPROTECT, FAIL, "unable to protect chunk proxy"); - - /* Compose chunked index info struct */ - idx_info.f = dset->oloc.file; - idx_info.dxpl_id = dxpl_id; - idx_info.pline = &(dset->shared->dcpl_cache.pline); - idx_info.layout = &(dset->shared->layout.u.chunk); - idx_info.storage = &(dset->shared->layout.storage.u.chunk); - - /* Compose user-data for chunk */ - udata.common.layout = &(dset->shared->layout.u.chunk); - udata.common.storage = &(dset->shared->layout.storage.u.chunk); - udata.common.offset = ent->offset; - udata.common.rdcc = &(dset->shared->cache.chunk); - /* Non-"common" data is not actually needed, except to provide a space to - * store this information if it is to be filled in as a side-effect of the - * unsupport callback (i.e. in H5D_btree_found) */ - - /* Remove flush dependency between the proxy (as the child) and the - * metadata object in the index (as the parent). - */ - if(proxy->supported) { - if((dset->shared->layout.storage.u.chunk.ops->unsupport)(&idx_info, &udata, (H5AC_info_t *)proxy) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTDEPEND, FAIL, "unable to remove flush dependency for chunk proxy") - proxy->supported = FALSE; - } /* end if */ - - /* Unpin & delete chunk proxy from metadata cache, taking ownership of it */ - if(H5AC_unprotect(dset->oloc.file, dxpl_id, H5AC_CHUNK_PROXY, ent->proxy_addr, proxy, (H5AC__UNPIN_ENTRY_FLAG | H5AC__DELETED_FLAG | H5AC__TAKE_OWNERSHIP_FLAG)) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTUNPROTECT, FAIL, "unable to release chunk proxy"); - - /* Reset information in chunk cache entry */ - ent->proxy_addr = HADDR_UNDEF; - ent->proxy = NULL; - - /* Release the chunk proxy object */ - if(H5D__chunk_proxy_destroy(proxy) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to destroy chunk proxy") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__chunk_proxy_remove() */ - - -/*------------------------------------------------------------------------- - * Function: H5D__chunk_proxy_mark - * - * Purpose: Mark a proxy for the chunk in the metadata cache as clean or - * dirty. - * - * Note: Currently, this code does not mark a chunk proxy as clean in - * the metadata cache. Doing so would require that this routine - * be invoked collectively when operating in parallel I/O mode - * and it's possible that this routine can be invoked during - * indepedent raw data I/O. - * - * So, the chunk proxy's dirty state in the metadata cache may - * be out of sync with the chunk itself, but only in the direction - * of being dirty when the chunk itself is clean. We'll call - * call the 'flush' callback for the chunk proxies more often - * than necessary, but as long as the chunk entry flushing - * routine doesn't actually flush the chunk when it's clean, - * there won't be too much overhead. - QAK, 5/21/2009 - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Tuesday, May 19, 2009 - * - *------------------------------------------------------------------------- - */ -herr_t -H5D__chunk_proxy_mark(H5D_rdcc_ent_t *ent, hbool_t dirty) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - - HDassert(ent); -#ifdef QAK -HDfprintf(stderr, "%s: ent->proxy_addr = %a, dirty = %t\n", FUNC, ent->proxy_addr, dirty); -#endif /* QAK */ - - /* Check whether to mark the proxy as dirty */ - if(dirty) { - if(H5AC_mark_entry_dirty(ent->proxy) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTMARKDIRTY, FAIL, "can't mark chunk proxy entry in metadata cache as dirty") - } /* end if */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__chunk_proxy_mark() */ - - -/*------------------------------------------------------------------------- - * Function: H5D__chunk_proxy_destroy - * - * Purpose: Destroy a chunk proxy object - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Thursday, May 21, 2009 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5D__chunk_proxy_destroy(H5D_chunk_proxy_t *proxy) -{ - FUNC_ENTER_STATIC_NOERR - - HDassert(proxy); - - /* Free the chunk proxy object */ - proxy->dset = NULL; - proxy->ent = NULL; - proxy = H5FL_FREE(H5D_chunk_proxy_t, proxy); - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5D__chunk_proxy_destroy() */ - - -/*------------------------------------------------------------------------- - * Function: H5D__chunk_proxy_create_flush_dep - * - * Purpose: Creates a flush dependency between the specified chunk - * (child) and parent, if not already present. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Neil Fortner - * 21 Sept 2010 - * - *------------------------------------------------------------------------- - */ -herr_t -H5D__chunk_proxy_create_flush_dep(H5D_rdcc_ent_t *ent, void *parent) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - - HDassert(ent); - HDassert(parent); - - /* If the proxy already has a parent, do nothing. */ - if(!(ent->proxy->supported)) { - /* Create the flush dependency */ - if(H5AC_create_flush_dependency(parent, ent->proxy) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTDEPEND, FAIL, "unable to create flush dependency") - ent->proxy->supported = TRUE; - } /* end else */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__chunk_proxy_create_flush_dep() */ - - -/*------------------------------------------------------------------------- - * Function: H5D__chunk_proxy_update_flush_dep - * - * Purpose: Updates the flush dependency of the specified chunk from - * old_parent to new_parent, if the dependency exists. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Neil Fortner - * 7 Sept 2010 - * - *------------------------------------------------------------------------- - */ -herr_t -H5D__chunk_proxy_update_flush_dep(H5D_rdcc_ent_t *ent, void *old_parent, - void *new_parent) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - - HDassert(ent); - HDassert(old_parent); - HDassert(new_parent); - - /* It is guaranteed that the proxy has a parent, because the dependency - * should always be present if the parent object exists in the index, and - * this should only be called when updating the parent object */ - HDassert(ent->proxy->supported); - - /* Update the flush dependencies */ - if(H5AC_destroy_flush_dependency(old_parent, ent->proxy) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTUNDEPEND, FAIL, "unable to destroy flush dependency") - if(H5AC_create_flush_dependency(new_parent, ent->proxy) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTDEPEND, FAIL, "unable to create flush dependency") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__chunk_proxy_update_flush_dep() */ - diff --git a/src/H5Oflush.c b/src/H5Oflush.c index 20e9c2d..3b6a3e6 100644 --- a/src/H5Oflush.c +++ b/src/H5Oflush.c @@ -42,6 +42,11 @@ #include "H5Iprivate.h" /* IDs */ #include "H5Opkg.h" /* Objects */ +/********************/ +/* Local Prototypes */ +/********************/ +static herr_t H5O_oh_tag(const H5O_loc_t *oloc, hid_t dxpl_id, haddr_t *tag); + /*************/ /* Functions */ /*************/ @@ -109,14 +114,18 @@ done: herr_t H5O_flush_common(H5O_loc_t *oloc, hid_t obj_id) { + haddr_t tag = 0; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) - /* Private function */ - if(H5O_flush_metadata(oloc, H5AC_dxpl_id) < 0) + if(H5O_oh_tag(oloc, H5AC_dxpl_id, &tag) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to flush object metadata") + /* Flush metadata based on tag value of the object */ + if(H5F_flush_tagged_metadata(oloc->file, tag, H5AC_dxpl_id)<0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush tagged metadata") + /* Check to invoke callback */ if(H5F_object_flush_cb(oloc->file, obj_id) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to do object flush callback") @@ -126,24 +135,23 @@ done: /*------------------------------------------------------------------------- - * Function: H5O_flush_metadata + * Function: H5O_oh_tag * - * Purpose: Flush any metadata associated with this object. + * Purpose: Get object header's address--tag value for the object * - * Return: Success: Non-negative - * Failure: Negative + * Return: Success: Non-negative + * Failure: Negative * * Programmer: Mike McGreevy * May 19, 2010 * *------------------------------------------------------------------------- */ -herr_t -H5O_flush_metadata(const H5O_loc_t *oloc, hid_t dxpl_id) +static herr_t +H5O_oh_tag(const H5O_loc_t *oloc, hid_t dxpl_id, haddr_t *tag) { H5O_t *oh = NULL; /* Object header */ herr_t ret_value = SUCCEED; /* Return value */ - haddr_t tag = 0; FUNC_ENTER_NOAPI(FAIL) @@ -155,7 +163,7 @@ H5O_flush_metadata(const H5O_loc_t *oloc, hid_t dxpl_id) HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to protect object's object header") /* Get object header's address (i.e. the tag value for this object) */ - if (HADDR_UNDEF == (tag = H5O_OH_GET_ADDR(oh))) + if (HADDR_UNDEF == (*tag = H5O_OH_GET_ADDR(oh))) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to get address of object header") /* Unprotect object header before attempting to flush it */ @@ -165,17 +173,13 @@ H5O_flush_metadata(const H5O_loc_t *oloc, hid_t dxpl_id) /* Reset object header pointer */ oh = NULL; - /* Flush metadata based on tag value of the object */ - if (H5F_flush_tagged_metadata(oloc->file, tag, dxpl_id)<0) - HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush tagged metadata") - done: /* Unprotect object header on failure */ if(oh && H5O_unprotect(oloc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value) -} /* end H5O_flush_metadata() */ +} /* end H5O_oh_tag() */ /*------------------------------------------------------------------------- @@ -245,10 +249,10 @@ H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc, hid_t dxpl_id) obj_loc.path = &obj_path; H5G_loc_reset(&obj_loc); - if((H5O_refresh_metadata_close(oid, oloc, &obj_loc, H5AC_dxpl_id)) < 0) + if((H5O_refresh_metadata_close(oid, oloc, &obj_loc, dxpl_id)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to refresh object") - if((H5O_refresh_metadata_reopen(oid, &obj_loc, H5AC_dxpl_id)) < 0) + if((H5O_refresh_metadata_reopen(oid, &obj_loc, dxpl_id)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to refresh object") done: @@ -285,24 +289,12 @@ H5O_refresh_metadata_close(hid_t oid, H5O_loc_t oloc, H5G_loc_t *obj_loc, hid_t FUNC_ENTER_NOAPI(FAIL) - /* Get the object's object header */ - if(NULL == (oh = H5O_protect(&oloc, dxpl_id, H5AC_READ))) - HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to protect object's object header") - /* Make deep local copy of object's location information */ H5G_loc(oid, &tmp_loc); H5G_loc_copy(obj_loc, &tmp_loc, H5_COPY_DEEP); - /* Get object header's address (i.e. the tag value for this object) */ - if(HADDR_UNDEF == (tag = H5O_OH_GET_ADDR(oh))) - HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to get address of object header") - - /* Unprotect object header before attempting to flush it */ - if(oh && H5O_unprotect(&oloc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") - - /* Reset object header pointer */ - oh = NULL; + if(H5O_oh_tag(&oloc, dxpl_id, &tag) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "unable to get object header address") /* Get cork status of the object with tag */ if(H5AC_cork(oloc.file, tag, H5AC__GET_CORKED, &corked) < 0) @@ -312,9 +304,9 @@ H5O_refresh_metadata_close(hid_t oid, H5O_loc_t oloc, H5G_loc_t *obj_loc, hid_t if(H5I_dec_ref(oid) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to close object") - /* Flush the object's metadata before evicting it */ - if(H5O_flush_metadata(&oloc, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "unable to flush object's metadata") + /* Flush metadata based on tag value of the object */ + if(H5F_flush_tagged_metadata(oloc.file, tag, dxpl_id)<0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush tagged metadata") /* Evict the object's tagged metadata */ if(H5F_evict_tagged_metadata(oloc.file, tag, dxpl_id)<0) diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 2c4f7ac..1d79ab5 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -832,7 +832,6 @@ H5_DLL herr_t H5O_msg_lock(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id H5_DLL herr_t H5O_msg_unlock(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id); /* Object metadata flush/evict routines */ -H5_DLL herr_t H5O_flush_metadata(const H5O_loc_t *oloc, hid_t dxpl_id); H5_DLL herr_t H5O_flush_common(H5O_loc_t *oloc, hid_t obj_id); H5_DLL herr_t H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc, hid_t dxpl_id); diff --git a/src/H5SMcache.c b/src/H5SMcache.c index d4052ef..0a8921a 100644 --- a/src/H5SMcache.c +++ b/src/H5SMcache.c @@ -214,7 +214,8 @@ H5SM_table_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void H5_ATTR_UNUSED *udat /* Address of the index's heap */ H5F_addr_decode(f, &p, &(table->indexes[u].heap_addr)); - /* Compute the size of a list index for this SOHM index */ + /* Compute the size of a list index for this SOHM index */ + table->indexes[u].list_size = H5SM_LIST_SIZE(f, table->indexes[u].list_max); } /* end for */ /* Already decoded and compared stored checksum earlier, when reading */ diff --git a/test/swmr.c b/test/swmr.c index 4d5ad5a..61fabc2 100644 --- a/test/swmr.c +++ b/test/swmr.c @@ -15,7 +15,7 @@ /*********************************************************** * -* Test program: test_swmr +* Test program: swmr * * To test new public routines from SWMR project: * H5Pget/set_metadata_read_attempts() @@ -46,10 +46,12 @@ const char *FILENAME[] = { - "test_swmr", /* 0 */ + "swmr0", /* 0 */ + "swmr1", /* 1 */ NULL }; + #define NAME_BUF_SIZE 1024 /* Length of file name */ /* Name of message file that is used by test_start_swmr_write_concur() */ @@ -76,6 +78,14 @@ static int test_append_flush_dataset_chunked(hid_t in_fapl); static int test_append_flush_dataset_fixed(hid_t in_fapl); static int test_append_flush_dataset_multiple(hid_t in_fapl); +/* Tests for file open flags/SWMR flags: single process access */ +static int test_file_lock_same(hid_t fapl); +static int test_file_lock_swmr_same(hid_t fapl); + +/* Tests for file open flags/SWMR flags: concurrent process access */ +static int test_file_lock_concur(hid_t fapl); +static int test_file_lock_swmr_concur(hid_t fapl); + /* Tests for SWMR VFD flag */ static int test_swmr_vfd_flag(); @@ -3605,6 +3615,1438 @@ error: return -1; } /* test_append_flush_dataset_multiple() */ + + +/**************************************************************** +** +** test_file_lock_same(): +** With the implementation of file locking, this test checks file +** open with different combinations of flags. +** This is for single process access. +** +*****************************************************************/ +static int +test_file_lock_same(hid_t in_fapl) +{ + hid_t fid, fid2; /* File IDs */ + hid_t fapl; /* File access property list */ + unsigned intent; /* File access flags */ + char filename[NAME_BUF_SIZE]; /* file name */ + + /* Output message about test being performed */ + TESTING("File open with different combinations of flags--single process access"); + + if((fapl = H5Pcopy(in_fapl)) < 0) + FAIL_STACK_ERROR + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[1], fapl, filename, sizeof(filename)); + + /* + * Case 1: 1) RDWR 2) RDWR : should succeed + */ + /* Create file */ + if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get and check file intent */ + if(H5Fget_intent(fid, &intent) < 0) + FAIL_STACK_ERROR + + if(intent != H5F_ACC_RDWR) + TEST_ERROR + + /* Open the same file with RDWR */ + if((fid2 = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get and check the intent */ + if(H5Fget_intent(fid2, &intent) < 0) + FAIL_STACK_ERROR + if(intent != H5F_ACC_RDWR) + TEST_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(fid2) < 0) + FAIL_STACK_ERROR + + /* + * Case 2: 1) RDWR 2) RDONLY : should succeed + */ + /* Open file with RDWR */ + if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get and check the intent */ + if(H5Fget_intent(fid, &intent) < 0) + FAIL_STACK_ERROR + if(intent != H5F_ACC_RDWR) + TEST_ERROR + + /* Open file with RDONLY */ + if((fid2 = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get and check the intent: should get intent from 1st open */ + if(H5Fget_intent(fid2, &intent) < 0) + FAIL_STACK_ERROR + if(intent != H5F_ACC_RDWR) + TEST_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(fid2) < 0) + FAIL_STACK_ERROR + + /* + * Case 3: 1) RDONLY 2) RDWR : should fail + */ + /* Open file with RDONLY */ + if((fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get and check the intent */ + if(H5Fget_intent(fid, &intent) < 0) + FAIL_STACK_ERROR + if(intent != H5F_ACC_RDONLY) + TEST_ERROR + + /* Open file with RDWR should fail */ + H5E_BEGIN_TRY { + fid2 = H5Fopen(filename, H5F_ACC_RDWR, fapl); + } H5E_END_TRY; + if(fid2 >= 0) + TEST_ERROR + + /* Close first file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* + * Case 4: 1) RDONLY 2) RDONLY : should succeed + */ + /* Open file with RDONLY */ + if((fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get and check the intent */ + if(H5Fget_intent(fid, &intent) < 0) + FAIL_STACK_ERROR + if(intent != H5F_ACC_RDONLY) + TEST_ERROR + + /* Open file with RDONLY */ + if((fid2 = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get and check the intent */ + if(H5Fget_intent(fid2, &intent) < 0) + FAIL_STACK_ERROR + if(intent != H5F_ACC_RDONLY) + TEST_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(fid2) < 0) + FAIL_STACK_ERROR + + /* Close the property list */ + if(H5Pclose(fapl) < 0) + FAIL_STACK_ERROR + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY { + H5Pclose(fapl); + H5Fclose(fid); + H5Fclose(fid2); + } H5E_END_TRY; + + return -1; +} /* end test_file_lock_same() */ + +/**************************************************************** +** +** test_file_lock_swmr_same(): +** With the implementation of file locking, this test checks file +** open with different combinations of flags + SWMR flags. +** This is for single process access. +** +*****************************************************************/ +static int +test_file_lock_swmr_same(hid_t in_fapl) +{ + hid_t fid, fid2; /* File IDs */ + hid_t fapl; /* File access property list */ + char filename[NAME_BUF_SIZE]; /* file name */ + + /* Output message about test being performed */ + TESTING("File open with different combinations of flags + SWMR flags--single process access"); + + /* Get a copy of the parameter in_fapl */ + if((fapl = H5Pcopy(in_fapl)) < 0) + FAIL_STACK_ERROR + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[1], fapl, filename, sizeof(filename)); + + /* Set to use latest library format */ + if(H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) + FAIL_STACK_ERROR + + /* Create a file */ + if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* + * Cases a, b, c, d: H5Fopen failure cases + */ + + /* + * Case a: RDWR|SWRM_READ : should fail + */ + H5E_BEGIN_TRY { + fid = H5Fopen(filename, H5F_ACC_RDWR|H5F_ACC_SWMR_READ, fapl); + } H5E_END_TRY; + if(fid >= 0) + TEST_ERROR + + /* + * Case b: RDWR|SWMM_WRTE|SWMR_READ : should fail + */ + H5E_BEGIN_TRY { + fid = H5Fopen(filename, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE|H5F_ACC_SWMR_READ, fapl); + } H5E_END_TRY; + if(fid >= 0) + TEST_ERROR + + /* + * Case c: RDONLY|SWMM_WRITE : should fail + */ + H5E_BEGIN_TRY { + fid = H5Fopen(filename, H5F_ACC_RDONLY|H5F_ACC_SWMR_WRITE, fapl); + } H5E_END_TRY; + if(fid >= 0) + TEST_ERROR + + /* + * Case d: RDONLY|SWMM_WRITE|SWMR_READ : should fail + */ + H5E_BEGIN_TRY { + fid = H5Fopen(filename, H5F_ACC_RDONLY|H5F_ACC_SWMR_WRITE|H5F_ACC_SWMR_READ, fapl); + } H5E_END_TRY; + if(fid >= 0) + TEST_ERROR + + /* + * Cases 1 - 12: combinations of different flags for 1st and 2nd opens + */ + + /* + * Case 1: 1) RDWR 2) RDWR|SWMR_WRITE : should fail + */ + if((fid = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR + + H5E_BEGIN_TRY { + fid2 = H5Fopen(filename, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl); + } H5E_END_TRY; + if(fid2 >= 0) + TEST_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* + * Case 2: 1) RDWR 2) RDONLY|SWMR_READ : should succeed + */ + if((fid = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) + TEST_ERROR + if((fid2 = H5Fopen(filename, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl)) < 0) + TEST_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + if(H5Fclose(fid2) < 0) + FAIL_STACK_ERROR + + /* + * Case 3: 1) RDWR|SWMR_WRITE 2)RDWR : should succeed + */ + if((fid = H5Fopen(filename, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl)) < 0) + FAIL_STACK_ERROR + if((fid2 = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(fid2) < 0) + FAIL_STACK_ERROR + + /* + * Case 4: 1) RDWR|SWMR_WRITE 2) RDWR|SWMR_WRITE : should succeed + */ + if((fid = H5Fopen(filename, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl)) < 0) + FAIL_STACK_ERROR + if((fid2 = H5Fopen(filename, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(fid2) < 0) + FAIL_STACK_ERROR + + /* + * Case 5: 1) RDWR|SWMR_WRITE 2) RDONLY|SWMR_READ : should succeed + */ + if((fid = H5Fopen(filename, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl)) < 0) + FAIL_STACK_ERROR + if((fid2 = H5Fopen(filename, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(fid2) < 0) + FAIL_STACK_ERROR + + /* + * Case 6: 1) RDWR|SWMR_WRITE 2) RDONLY : should succeed + */ + if((fid = H5Fopen(filename, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl)) < 0) + FAIL_STACK_ERROR + if((fid2 = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(fid2) < 0) + FAIL_STACK_ERROR + + /* + * Case 7: 1) RDONLY|SWMR_READ 2)RDWR : should fail + */ + if((fid = H5Fopen(filename, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl)) < 0) + FAIL_STACK_ERROR + + H5E_BEGIN_TRY { + fid2 = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT); + } H5E_END_TRY; + if(fid2 >= 0) + TEST_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* + * Case 8: 1) RDONLY|SWMR_READ 2) RDWR|SWMR_WRITE : should fail + */ + if((fid = H5Fopen(filename, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl)) < 0) + FAIL_STACK_ERROR + + H5E_BEGIN_TRY { + fid2 = H5Fopen(filename, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl); + } H5E_END_TRY; + if(fid2 >= 0) + TEST_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* + * Case 9: 1) RDONLY|SWMR_READ 2) RDONLY|SWMR_READ : should succeed + */ + if((fid = H5Fopen(filename, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl)) < 0) + FAIL_STACK_ERROR + if((fid2 = H5Fopen(filename, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(fid2) < 0) + FAIL_STACK_ERROR + + /* + * Case 10: 1) RDONLY|SWMR_READ 2) RDONLY : should succeed + */ + if((fid = H5Fopen(filename, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl)) < 0) + TEST_ERROR + if((fid2 = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(fid2) < 0) + FAIL_STACK_ERROR + + /* + * Case 11: 1) RDONLY 2) RDWR|SWMR_WRITE: should fail + */ + if((fid = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR + + H5E_BEGIN_TRY { + fid2 = H5Fopen(filename, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl); + } H5E_END_TRY; + if(fid2 >= 0) + TEST_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* + * Case 12: 1) RDONLY 2) RDONLY|SWMR_READ : should fail + */ + if((fid = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR + + H5E_BEGIN_TRY { + fid2 = H5Fopen(filename, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl); + } H5E_END_TRY; + if(fid2 >=0 ) + TEST_ERROR + + /* Close 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 { + H5Pclose(fapl); + H5Fclose(fid); + H5Fclose(fid2); + } H5E_END_TRY; + + return -1; +} /* end test_file_lock_swmr_same() */ + + +/**************************************************************** +** +** test_file_lock_concur(): +** With the implementation of file locking, this test checks file +** open with different combinations of flags. +** This is for concurrent access. +** +*****************************************************************/ +static int +test_file_lock_concur(hid_t in_fapl) +{ + hid_t fid; /* File ID */ + hid_t fapl; /* File access property list */ + char filename[NAME_BUF_SIZE]; /* file name */ + pid_t childpid=0; /* Child process ID */ + int child_status; /* Status passed to waitpid */ + int child_wait_option=0; /* Options passed to waitpid */ + + /* Output message about test being performed */ + TESTING("File open with different combinations of flags--concurrent access"); + +#if !(defined(H5_HAVE_FORK) && defined(H5_HAVE_WAITPID)) + + SKIPPED(); + HDputs(" Test skipped due to fork or waitpid not defined."); + return 0; + +#elif !defined(H5_HAVE_FLOCK) + + SKIPPED(); + HDputs(" Test skipped due to a lack of flock() on this system."); + +#else /* defined(H5_HAVE_FORK && defined(H5_HAVE_WAITPID) */ + + if((fapl = H5Pcopy(in_fapl)) < 0) + FAIL_STACK_ERROR + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[1], fapl, filename, sizeof(filename)); + + /* Create the test file */ + if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close the file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* + * Case 1: 1) RDWR 2) RDWR : should fail + */ + + /* Remove the message file to be sure */ + HDremove(DONE_MESSAGE); + + /* Fork child process */ + if((childpid = HDfork()) < 0) + FAIL_STACK_ERROR + + if(childpid == 0) { /* Child process */ + hid_t child_fid; /* File ID */ + + /* Wait till parent process completes the open */ + if(h5_wait_message(DONE_MESSAGE) < 0) + exit(1); + + /* Open the test file */ + H5E_BEGIN_TRY { + child_fid = H5Fopen(filename, H5F_ACC_RDWR, fapl); + } H5E_END_TRY; + + /* Should fail */ + if(child_fid == FAIL) + exit(0); + exit(1); + } + + /* 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); + + /* Wait for child process to complete */ + if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) + FAIL_STACK_ERROR + + /* Check if child terminated normally */ + if(WIFEXITED(child_status)) { + /* Check exit status of the child */ + if(WEXITSTATUS(child_status) != 0) + TEST_ERROR + } else + FAIL_STACK_ERROR + + /* Close the file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* + * Case 2: 1) RDWR 2) RDONLY : should fail + */ + /* Remove the message file just to be sure */ + HDremove(DONE_MESSAGE); + + /* Fork child process */ + if((childpid = HDfork()) < 0) + FAIL_STACK_ERROR + + if(childpid == 0) { /* Child process */ + hid_t child_fid; /* File ID */ + + /* Wait till parent process completes the open */ + if(h5_wait_message(DONE_MESSAGE) < 0) + exit(1); + + /* Opens the test file */ + H5E_BEGIN_TRY { + child_fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl); + } H5E_END_TRY; + + /* Should fail */ + if(child_fid == FAIL) + exit(0); + exit(1); + } + + /* 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); + + /* Wait for child process to complete */ + if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) + FAIL_STACK_ERROR + + /* Check if child terminated normally */ + if(WIFEXITED(child_status)) { + /* Check exit status of the child */ + if(WEXITSTATUS(child_status) != 0) + TEST_ERROR + } else + FAIL_STACK_ERROR + + /* Close the file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* + * Case 3: 1) RDONLY 2) RDWR : should fail + */ + + /* Remove the message file just to be sure */ + HDremove(DONE_MESSAGE); + + /* Fork child process */ + if((childpid = HDfork()) < 0) + FAIL_STACK_ERROR + + if(childpid == 0) { /* Child process */ + hid_t child_fid; /* File ID */ + + /* Wait till parent process completes the open */ + if(h5_wait_message(DONE_MESSAGE) < 0) + exit(1); + + /* Opens the test file */ + H5E_BEGIN_TRY { + child_fid = H5Fopen(filename, H5F_ACC_RDWR, fapl); + } H5E_END_TRY; + + /* Should fail */ + if(child_fid == FAIL) + exit(0); + exit(1); + } + + /* Opens the test 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); + + /* Wait for child process to complete */ + if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) + FAIL_STACK_ERROR + + /* Check if child terminated normally */ + if(WIFEXITED(child_status)) { + /* Check exit status of the child */ + if(WEXITSTATUS(child_status) != 0) + TEST_ERROR + } else + FAIL_STACK_ERROR + + /* Close the file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* + * Case 4: 1) RDONLY 2) RDONLY : should succeed + */ + + HDremove(DONE_MESSAGE); + + /* Fork child process */ + if((childpid = HDfork()) < 0) + FAIL_STACK_ERROR + + if(childpid == 0) { /* Child process */ + hid_t child_fid; /* File ID */ + + /* Wait till parent process completes the open */ + if(h5_wait_message(DONE_MESSAGE) < 0) + exit(1); + + /* Opens the test file */ + H5E_BEGIN_TRY { + child_fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl); + } H5E_END_TRY; + + /* Should succeed */ + if(child_fid >= 0) { + /* Close the file */ + if(H5Fclose(child_fid) < 0) + FAIL_STACK_ERROR + exit(0); + } + exit(1); + } + + /* 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); + + /* Wait for child process to complete */ + if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) + FAIL_STACK_ERROR + + /* Check if child terminated normally */ + if(WIFEXITED(child_status)) { + /* Check exit status of the child */ + if(WEXITSTATUS(child_status) != 0) + TEST_ERROR + } else + 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 { + H5Pclose(fapl); + H5Fclose(fid); + } H5E_END_TRY; + + return -1; +#endif + +} /* end test_file_lock_concur() */ + +/**************************************************************** +** +** test_file_lock_swmr_concur(): low-level file test routine. +** With the implementation of file locking, this test checks file +** open with different combinations of flags + SWMR flags. +** This is for concurrent access. +** +*****************************************************************/ +static int +test_file_lock_swmr_concur(hid_t in_fapl) +{ + hid_t fid; /* File ID */ + hid_t fapl; /* File access property list */ + char filename[NAME_BUF_SIZE]; /* file name */ + pid_t childpid=0; /* Child process ID */ + int child_status; /* Status passed to waitpid */ + int child_wait_option=0; /* Options passed to waitpid */ + + /* Output message about test being performed */ + TESTING("File open with different combintations of flags + SWMR flags--concurrent access"); + +#if !(defined(H5_HAVE_FORK) && defined(H5_HAVE_WAITPID)) + + SKIPPED(); + HDputs(" Test skipped due to fork or waitpid not defined."); + return 0; + +#else /* defined(H5_HAVE_FORK && defined(H5_HAVE_WAITPID) */ + + if((fapl = H5Pcopy(in_fapl)) < 0) + FAIL_STACK_ERROR + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[1], fapl, filename, sizeof(filename)); + + /* Set to use 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 + + /* Close the file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* + * Case 1: 1) RDWR 2) RDWR|SWMR_WRITE : should fail + */ + + /* Remove the message file to be sure */ + HDremove(DONE_MESSAGE); + + /* Fork child process */ + if((childpid = HDfork()) < 0) + FAIL_STACK_ERROR + + if(childpid == 0) { /* Child process */ + hid_t child_fid; /* File ID */ + + /* Wait till parent process completes the open */ + if(h5_wait_message(DONE_MESSAGE) < 0) + exit(1); + + /* Open the test file */ + H5E_BEGIN_TRY { + child_fid = H5Fopen(filename, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl); + } H5E_END_TRY; + + /* Should fail */ + if(child_fid == FAIL) + exit(0); + exit(1); + } + + /* 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); + + /* Wait for child process to complete */ + if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) + FAIL_STACK_ERROR + + /* Check if child terminated normally */ + if(WIFEXITED(child_status)) { + /* Check exit status of the child */ + if(WEXITSTATUS(child_status) != 0) + TEST_ERROR + } else + FAIL_STACK_ERROR + + /* Close the file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* + * Case 2: 1) RDWR 2) RDONLY|SWMR_READ: should fail + */ + + /* Remove the message file to be sure */ + HDremove(DONE_MESSAGE); + + /* Fork child process */ + if((childpid = HDfork()) < 0) + FAIL_STACK_ERROR + + if(childpid == 0) { /* Child process */ + hid_t child_fid; /* File ID */ + + /* Wait till parent process completes the open */ + if(h5_wait_message(DONE_MESSAGE) < 0) + exit(1); + + /* Open the test file */ + H5E_BEGIN_TRY { + child_fid = H5Fopen(filename, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl); + } H5E_END_TRY; + + /* Should fail */ + if(child_fid == FAIL) + exit(0); + exit(1); + } + + /* 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); + + /* Wait for child process to complete */ + if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) + FAIL_STACK_ERROR + + /* Check if child terminated normally */ + if(WIFEXITED(child_status)) { + /* Check exit status of the child */ + if(WEXITSTATUS(child_status) != 0) + TEST_ERROR + } else + FAIL_STACK_ERROR + + /* Close the file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* + * Case 3: 1) RDWR|SWMR_WRITE 2) RDWR : should fail + */ + + /* Remove the message file to be sure */ + HDremove(DONE_MESSAGE); + + /* Fork child process */ + if((childpid = HDfork()) < 0) + FAIL_STACK_ERROR + + if(childpid == 0) { /* Child process */ + hid_t child_fid; /* File ID */ + + /* Wait till parent process completes the open */ + if(h5_wait_message(DONE_MESSAGE) < 0) + exit(1); + + /* Open the test file */ + H5E_BEGIN_TRY { + child_fid = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT); + } H5E_END_TRY; + + /* Should fail */ + if(child_fid == FAIL) + exit(0); + exit(1); + } + + /* 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); + + /* Wait for child process to complete */ + if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) + FAIL_STACK_ERROR + + /* Check if child terminated normally */ + if(WIFEXITED(child_status)) { + /* Check exit status of the child */ + if(WEXITSTATUS(child_status) != 0) + TEST_ERROR + } else + FAIL_STACK_ERROR + + /* Close the file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* + * Case 4: 1) RDWR|SWMR_WRITE 2) RDWR|SWMR_WRITE : should fail + */ + + /* Remove the message file just to be sure */ + HDremove(DONE_MESSAGE); + + /* Fork child process */ + if((childpid = HDfork()) < 0) + FAIL_STACK_ERROR + + if(childpid == 0) { /* Child process */ + hid_t child_fid; /* File ID */ + + /* Wait till parent process completes the open */ + if(h5_wait_message(DONE_MESSAGE) < 0) + exit(1); + + /* Open the test file */ + H5E_BEGIN_TRY { + child_fid = H5Fopen(filename, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl); + } H5E_END_TRY; + + /* Should fail */ + if(child_fid == FAIL) + exit(0); + exit(1); + } + + /* 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); + + /* Wait for child process to complete */ + if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) + FAIL_STACK_ERROR + + /* Check if child terminated normally */ + if(WIFEXITED(child_status)) { + /* Check exit status of the child */ + if(WEXITSTATUS(child_status) != 0) + TEST_ERROR + } else + FAIL_STACK_ERROR + + /* Close the file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* + * Case 5: 1) RDWR|SWMR_WRITE 2) RDONLY|SWMR_READ : should succeed + */ + + /* Remove the message file just to be sure */ + HDremove(DONE_MESSAGE); + + /* Fork child process */ + if((childpid = HDfork()) < 0) + FAIL_STACK_ERROR + + if(childpid == 0) { /* Child process */ + hid_t child_fid; /* File ID */ + + /* Wait till parent process completes the open */ + if(h5_wait_message(DONE_MESSAGE) < 0) + exit(1); + + /* Open the test file */ + H5E_BEGIN_TRY { + child_fid = H5Fopen(filename, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl); + } H5E_END_TRY; + + /* Should succeed */ + if(child_fid >= 0) { + if(H5Fclose(child_fid) < 0) + FAIL_STACK_ERROR + exit(0); + } + exit(1); + } + + /* 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); + + /* Wait for child process to complete */ + if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) + FAIL_STACK_ERROR + + /* Check if child terminated normally */ + if(WIFEXITED(child_status)) { + /* Check exit status of the child */ + if(WEXITSTATUS(child_status) != 0) + TEST_ERROR + } else + FAIL_STACK_ERROR + + /* Close the file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* + * Case 6: 1) RDWR|SWMR_WRITE 2) RDONLY : should fail + */ + + /* Remove the message file just to be sure */ + HDremove(DONE_MESSAGE); + + /* Fork child process */ + if((childpid = HDfork()) < 0) + FAIL_STACK_ERROR + + if(childpid == 0) { /* Child process */ + hid_t child_fid; /* File ID */ + + /* Wait till parent process completes the open */ + if(h5_wait_message(DONE_MESSAGE) < 0) + exit(1); + + /* Open the test file */ + H5E_BEGIN_TRY { + child_fid = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT); + } H5E_END_TRY; + + /* Should fail */ + if(child_fid == FAIL) + exit(0); + exit(1); + } + + /* 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); + + /* Wait for child process to complete */ + if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) + FAIL_STACK_ERROR + + /* Check if child terminated normally */ + if(WIFEXITED(child_status)) { + /* Check exit status of the child */ + if(WEXITSTATUS(child_status) != 0) + TEST_ERROR + } else + FAIL_STACK_ERROR + + /* Close the file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* + * Case 7: 1) RDONLY|SWMR_READ 2) RDWR : should fail + */ + + /* Remove the message file just to be sure */ + HDremove(DONE_MESSAGE); + + /* Fork child process */ + if((childpid = HDfork()) < 0) + FAIL_STACK_ERROR + + if(childpid == 0) { /* Child process */ + hid_t child_fid; /* File ID */ + + /* Wait till parent process completes the open */ + if(h5_wait_message(DONE_MESSAGE) < 0) + exit(1); + + /* Open the test file */ + H5E_BEGIN_TRY { + child_fid = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT); + } H5E_END_TRY; + + /* Should fail */ + if(child_fid == FAIL) + exit(0); + exit(1); + } + + /* 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); + + /* Wait for child process to complete */ + if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) + FAIL_STACK_ERROR + + /* Check if child terminated normally */ + if(WIFEXITED(child_status)) { + /* Check exit status of the child */ + if(WEXITSTATUS(child_status) != 0) + TEST_ERROR + } else + FAIL_STACK_ERROR + + /* Close the file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* + * Case 8: 1) RDONLY|SWMR_READ 2) RDWR|SWMR_WRITE : should fail + */ + + /* Remove the message file just to be sure */ + HDremove(DONE_MESSAGE); + + /* Fork child process */ + if((childpid = HDfork()) < 0) + FAIL_STACK_ERROR + + if(childpid == 0) { /* Child process */ + hid_t child_fid; /* File ID */ + + /* Wait till parent process completes the open */ + if(h5_wait_message(DONE_MESSAGE) < 0) + exit(1); + + /* Open the test file */ + H5E_BEGIN_TRY { + child_fid = H5Fopen(filename, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl); + } H5E_END_TRY; + + /* Should fail */ + if(child_fid == FAIL) + exit(0); + exit(1); + } + + /* 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); + + /* Wait for child process to complete */ + if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) + FAIL_STACK_ERROR + + /* Check if child terminated normally */ + if(WIFEXITED(child_status)) { + /* Check exit status of the child */ + if(WEXITSTATUS(child_status) != 0) + TEST_ERROR + } else + FAIL_STACK_ERROR + + /* Close the file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* + * Case 9: 1) RDONLY|SWMR_READ 2) RDONLY|SWMR_READ : should succeed + */ + + /* Remove the message file just to be sure */ + HDremove(DONE_MESSAGE); + + /* Fork child process */ + if((childpid = HDfork()) < 0) + FAIL_STACK_ERROR + + if(childpid == 0) { /* Child process */ + hid_t child_fid; /* File ID */ + + /* Wait till parent process completes the open */ + if(h5_wait_message(DONE_MESSAGE) < 0) + exit(1); + + /* Open the test file */ + H5E_BEGIN_TRY { + child_fid = H5Fopen(filename, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl); + } H5E_END_TRY; + + /* Should succeed */ + if(child_fid >= 0) { + if(H5Fclose(child_fid) < 0) + FAIL_STACK_ERROR + exit(0); + } + exit(1); + } + + /* 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); + + /* Wait for child process to complete */ + if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) + FAIL_STACK_ERROR + + /* Check if child terminated normally */ + if(WIFEXITED(child_status)) { + /* Check exit status of the child */ + if(WEXITSTATUS(child_status) != 0) + TEST_ERROR + } else + FAIL_STACK_ERROR + + /* Close the file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* + * Case 10: 1) RDONLY|SWMR_READ 2) RDONLY : should succeed + */ + + /* Remove the message file just to be sure */ + HDremove(DONE_MESSAGE); + + /* Fork child process */ + if((childpid = HDfork()) < 0) + FAIL_STACK_ERROR + + if(childpid == 0) { /* Child process */ + hid_t child_fid; /* File ID */ + + /* Wait till parent process completes the open */ + if(h5_wait_message(DONE_MESSAGE) < 0) + exit(1); + + /* Open the test file */ + if((child_fid = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR + + /* Should succeed */ + if(child_fid >= 0) { + if(H5Fclose(child_fid) < 0) + FAIL_STACK_ERROR + exit(0); + } + exit(1); + } + + /* 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); + + /* Wait for child process to complete */ + if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) + FAIL_STACK_ERROR + + /* Check if child terminated normally */ + if(WIFEXITED(child_status)) { + /* Check exit status of the child */ + if(WEXITSTATUS(child_status) != 0) + TEST_ERROR + } else + FAIL_STACK_ERROR + + /* Close the file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* + * Case 11: 1) RDONLY 2) RDWR|SWMR_WRITE : should fail + */ + + /* Remove the message file just to be sure */ + HDremove(DONE_MESSAGE); + + /* Fork child process */ + if((childpid = HDfork()) < 0) + FAIL_STACK_ERROR + + if(childpid == 0) { /* Child process */ + hid_t child_fid; /* File ID */ + + /* Wait till parent process completes the open */ + if(h5_wait_message(DONE_MESSAGE) < 0) + exit(1); + + /* Open the test file */ + H5E_BEGIN_TRY { + child_fid = H5Fopen(filename, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl); + } H5E_END_TRY; + + /* Should fail */ + if(child_fid == FAIL) + exit(0); + exit(1); + } + + /* 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); + + /* Wait for child process to complete */ + if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) + FAIL_STACK_ERROR + + /* Check if child terminated normally */ + if(WIFEXITED(child_status)) { + /* Check exit status of the child */ + if(WEXITSTATUS(child_status) != 0) + TEST_ERROR + } else + FAIL_STACK_ERROR + + /* Close the file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* + * Case 12: 1) RDONLY 2) RDONLY|SWMR_READ : should succeed + */ + + /* Remove the message file just to be sure */ + HDremove(DONE_MESSAGE); + + /* Fork child process */ + if((childpid = HDfork()) < 0) + FAIL_STACK_ERROR + + if(childpid == 0) { /* Child process */ + hid_t child_fid; /* File ID */ + + /* Wait till parent process completes the open */ + if(h5_wait_message(DONE_MESSAGE) < 0) + exit(1); + + /* Open the test file */ + H5E_BEGIN_TRY { + child_fid = H5Fopen(filename, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl); + } H5E_END_TRY; + + /* Should succeed */ + if(child_fid >= 0) { + if(H5Fclose(child_fid) < 0) + FAIL_STACK_ERROR + exit(0); + } + exit(1); + } + + /* 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); + + /* Wait for child process to complete */ + if(HDwaitpid(childpid, &child_status, child_wait_option) < 0) + FAIL_STACK_ERROR + + /* Check if child terminated normally */ + if(WIFEXITED(child_status)) { + /* Check exit status of the child */ + if(WEXITSTATUS(child_status) != 0) + TEST_ERROR + } else + 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 { + H5Pclose(fapl); + H5Fclose(fid); + } H5E_END_TRY; + + return -1; + +#endif + +} /* end test_file_lock_swmr_concur() */ + static int test_swmr_vfd_flag(void) { @@ -3666,7 +5108,6 @@ error: return -1; } /* test_swmr_vfd_flag() */ - #ifdef OUT /* * This exposes a bug for H5Orefresh while handling opened objects for H5Fstart_swmr_write(). @@ -3819,6 +5260,18 @@ main(void) nerrors += test_append_flush_dataset_fixed(fapl); nerrors += test_append_flush_dataset_multiple(fapl); + /* + * Tests for: + * file open flags--single process access + * file open flags+SWMR flags--single process access + * file open flags--concurrent access + * file open flags+SWMR flags--concurrent access + */ + nerrors += test_file_lock_same(fapl); + nerrors += test_file_lock_swmr_same(fapl); + nerrors += test_file_lock_concur(fapl); + nerrors += test_file_lock_swmr_concur(fapl); + /* Tests SWMR VFD compatibility flag. * Only needs to run when the VFD is the default (sec2). */ @@ -3826,7 +5279,7 @@ main(void) nerrors += test_swmr_vfd_flag(); if(nerrors) - goto error; + goto error; printf("All tests passed.\n"); diff --git a/test/tfile.c b/test/tfile.c index 15875a7..eaae9df 100644 --- a/test/tfile.c +++ b/test/tfile.c @@ -152,11 +152,6 @@ static int cal_chksum(const char *file, uint32_t *chksum); static void test_rw_noupdate(void); -static void test_file_lock_same(void); -static void test_file_lock_swmr_same(void); -static void test_file_lock_concur(void); -static void test_file_lock_swmr_concur(void); - /**************************************************************** ** ** test_file_create(): Low-level file creation I/O test routine. @@ -2422,97 +2417,6 @@ test_rw_noupdate(void) } /* end test_rw_noupdate() */ -#ifdef OUT -/**************************************************************** -** -** test_rw_noupdate(): low-level file test routine. -** This test checks to ensure that opening and closing a file -** with read/write permissions does not write anything to the -** file if the file does not change. -** -** Programmer: Mike McGreevy -** mamcgree@hdfgroup.org -** June 29, 2009 -** -*****************************************************************/ -static void -test_rw_noupdate(void) -{ - int fd; /* File Descriptor */ - h5_stat_t sb1, sb2; /* Info from 'stat' call */ - double diff; /* Difference in modification times */ - herr_t ret; /* Generic return value */ - - /* Output message about test being performed */ - MESSAGE(5, ("Testing to verify that nothing is written if nothing is changed.\n")); - - /* First make sure the stat function behaves as we expect - the modification time - * is the time that the file was modified last time. */ - fd = HDopen(SFILE1, O_RDWR | O_CREAT | O_TRUNC, 0666); - CHECK(fd, FAIL, "HDopen"); - ret = HDclose(fd); - CHECK(ret, FAIL, "HDclose"); - - /* Determine File's Initial Timestamp */ - ret = HDstat(SFILE1, &sb1); - VERIFY(ret, 0, "HDstat"); - - /* Wait for 2 seconds */ - /* (This ensures a system time difference between the two file accesses) */ - HDsleep(2); - - fd = HDopen(SFILE1, O_RDWR, 0666); - CHECK(fd, FAIL, "HDopen"); - ret = HDclose(fd); - CHECK(ret, FAIL, "HDclose"); - - /* Determine File's New Timestamp */ - ret = HDstat(SFILE1, &sb2); - VERIFY(ret, 0, "HDstat"); - - /* Get difference between timestamps */ - diff = HDdifftime(sb2.st_mtime, sb1.st_mtime); - - /* Check That Timestamps Are Equal */ - if(diff > 0.0F) { - /* Output message about test being performed */ - MESSAGE(1, ("Testing to verify that nothing is written if nothing is changed: This test is skipped on this system because the modification time from stat is the same as the last access time (We know OpenVMS behaves in this way).\n")); - } /* end if */ - else { - hid_t file_id; /* HDF5 File ID */ - - /* Create and Close a HDF5 File */ - file_id = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); - CHECK(file_id, FAIL, "H5Fcreate"); - ret = H5Fclose(file_id); - CHECK(ret, FAIL, "H5Fclose"); - - /* Determine File's Initial Timestamp */ - ret = HDstat(FILE1, &sb1); - VERIFY(ret, 0, "HDfstat"); - - /* Wait for 2 seconds */ - /* (This ensures a system time difference between the two file accesses) */ - HDsleep(2); - - /* Open and Close File With Read/Write Permission */ - file_id = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); - CHECK(file_id, FAIL, "H5Fopen"); - ret = H5Fclose(file_id); - CHECK(ret, FAIL, "H5Fclose"); - - /* Determine File's New Timestamp */ - ret = HDstat(FILE1, &sb2); - VERIFY(ret, 0, "HDstat"); - - /* Ensure That Timestamps Are Equal */ - diff = HDdifftime(sb2.st_mtime, sb1.st_mtime); - ret = (diff > 0.0F); - VERIFY(ret, 0, "Timestamp"); - } /* end else */ -} /* end test_rw_noupdate() */ -#endif - /**************************************************************** ** ** test_userblock_alignment_helper1(): helper routine for @@ -3613,1315 +3517,6 @@ test_libver_macros2(void) /**************************************************************** ** -** test_file_lock_same(): -** With the implementation of file locking, this test checks file -** open with different combinations of flags. -** This is for single process access. -** -*****************************************************************/ -static void -test_file_lock_same(void) -{ - hid_t fid, fid2; /* File IDs */ - unsigned intent; /* File access flags */ - herr_t ret; /* Generic return value */ - - /* Output message about test being performed */ - MESSAGE(5, ("Testing file open with different combinations of flags--single process access\n")); - - /* - * Case 1: 1) RDWR 2) RDWR : should succeed - */ - /* Create file */ - fid = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); - CHECK(fid, FAIL, "H5Fcreate"); - - /* Get and check file intent */ - ret = H5Fget_intent(fid, &intent); - CHECK(ret, FAIL, "H5Fget_intent"); - VERIFY(intent, H5F_ACC_RDWR, "H5Fget_intent"); - - /* Open the same file with RDWR */ - fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); - - /* Get and check the intent */ - ret = H5Fget_intent(fid2, &intent); - CHECK(ret, FAIL, "H5Fget_intent"); - VERIFY(intent, H5F_ACC_RDWR, "H5Fget_intent"); - - /* Close file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - /* Close file */ - ret = H5Fclose(fid2); - CHECK(ret, FAIL, "H5Fclose"); - - /* - * Case 2: 1) RDWR 2) RDONLY : should succeed - */ - /* Open file with RDWR */ - fid = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); - CHECK(fid, FAIL, "H5Fcreate"); - - /* Get and check the intent */ - ret = H5Fget_intent(fid, &intent); - CHECK(ret, FAIL, "H5Fget_intent"); - VERIFY(intent, H5F_ACC_RDWR, "H5Fget_intent"); - - /* Open file with RDONLY */ - fid2 = H5Fopen(FILE1, H5F_ACC_RDONLY, H5P_DEFAULT); - - /* Get and check the intent: should get intent from 1st open */ - ret = H5Fget_intent(fid2, &intent); - CHECK(ret, FAIL, "H5Fget_intent"); - VERIFY(intent, H5F_ACC_RDWR, "H5Fget_intent"); - - /* Close file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - /* Close file */ - ret = H5Fclose(fid2); - CHECK(ret, FAIL, "H5Fclose"); - - /* - * Case 3: 1) RDONLY 2) RDWR : should fail - */ - /* Open file with RDONLY */ - fid = H5Fopen(FILE1, H5F_ACC_RDONLY, H5P_DEFAULT); - CHECK(fid, FAIL, "H5Fcreate"); - - /* Get and check the intent */ - ret = H5Fget_intent(fid, &intent); - CHECK(ret, FAIL, "H5Fget_intent"); - VERIFY(intent, H5F_ACC_RDONLY, "H5Fget_intent"); - - /* Open file with RDWR should fail */ - H5E_BEGIN_TRY { - fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); - } H5E_END_TRY; - VERIFY(fid2, FAIL, "H5Fopen"); - - /* Close first file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - /* - * Case 4: 1) RDONLY 2) RDONLY : should succeed - */ - /* Open file with RDONLY */ - fid = H5Fopen(FILE1, H5F_ACC_RDONLY, H5P_DEFAULT); - CHECK(fid, FAIL, "H5Fcreate"); - - /* Get and check the intent */ - ret = H5Fget_intent(fid, &intent); - CHECK(ret, FAIL, "H5Fget_intent"); - VERIFY(intent, H5F_ACC_RDONLY, "H5Fget_intent"); - - /* Open file with RDONLY */ - fid2 = H5Fopen(FILE1, H5F_ACC_RDONLY, H5P_DEFAULT); - - /* Get and check the intent */ - ret = H5Fget_intent(fid2, &intent); - CHECK(ret, FAIL, "H5Fget_intent"); - VERIFY(intent, H5F_ACC_RDONLY, "H5Fget_intent"); - - /* Close file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - /* Close file */ - ret = H5Fclose(fid2); - CHECK(ret, FAIL, "H5Fclose"); - -} /* end test_file_lock_same() */ - -/**************************************************************** -** -** test_file_lock_swmr_same(): -** With the implementation of file locking, this test checks file -** open with different combinations of flags + SWMR flags. -** This is for single process access. -** -*****************************************************************/ -static void -test_file_lock_swmr_same(void) -{ - hid_t fid, fid2; /* File IDs */ - hid_t fapl; /* File access property list */ - herr_t ret; /* Generic return value */ - - /* Output message about test being performed */ - MESSAGE(5, ("Testing file open with different combinations of flags + SWMR flags--single process access\n")); - - /* Create a file access property list */ - fapl = H5Pcreate(H5P_FILE_ACCESS); - CHECK(fapl, FAIL, "H5Pcreate"); - - /* Set to use latest library format */ - ret = H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST); - CHECK(ret, FAIL, "H5Pset_libver_bounds"); - - /* Create a file */ - fid = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); - CHECK(fid, FAIL, "H5Fcreate"); - - /* Close file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - /* - * Cases a, b, c, d: H5Fopen failure cases - */ - - /* - * Case a: RDWR|SWRM_READ : should fail - */ - H5E_BEGIN_TRY { - fid = H5Fopen(FILE1, H5F_ACC_RDWR|H5F_ACC_SWMR_READ, fapl); - } H5E_END_TRY; - VERIFY(fid, FAIL, "H5Fopen"); - - /* - * Case b: RDWR|SWMM_WRTE|SWMR_READ : should fail - */ - H5E_BEGIN_TRY { - fid = H5Fopen(FILE1, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE|H5F_ACC_SWMR_READ, fapl); - } H5E_END_TRY; - VERIFY(fid, FAIL, "H5Fopen"); - - /* - * Case c: RDONLY|SWMM_WRITE : should fail - */ - H5E_BEGIN_TRY { - fid = H5Fopen(FILE1, H5F_ACC_RDONLY|H5F_ACC_SWMR_WRITE, fapl); - } H5E_END_TRY; - VERIFY(fid, FAIL, "H5Fopen"); - - /* - * Case d: RDONLY|SWMM_WRITE|SWMR_READ : should fail - */ - H5E_BEGIN_TRY { - fid = H5Fopen(FILE1, H5F_ACC_RDONLY|H5F_ACC_SWMR_WRITE|H5F_ACC_SWMR_READ, fapl); - } H5E_END_TRY; - VERIFY(fid, FAIL, "H5Fopen"); - - /* - * Cases 1 - 12: combinations of different flags for 1st and 2nd opens - */ - - /* - * Case 1: 1) RDWR 2) RDWR|SWMR_WRITE : should fail - */ - fid = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); - CHECK(fid, FAIL, "H5Fopen"); - - H5E_BEGIN_TRY { - fid2 = H5Fopen(FILE1, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl); - } H5E_END_TRY; - VERIFY(fid2, FAIL, "H5Fopen"); - - /* Close file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - /* - * Case 2: 1) RDWR 2) RDONLY|SWMR_READ : should succeed - */ - fid = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); - CHECK(fid, FAIL, "H5Fopen"); - fid2 = H5Fopen(FILE1, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl); - CHECK(fid2, FAIL, "H5Fopen"); - - /* Close file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - ret = H5Fclose(fid2); - CHECK(ret, FAIL, "H5Fclose"); - - /* - * Case 3: 1) RDWR|SWMR_WRITE 2)RDWR : should succeed - */ - fid = H5Fopen(FILE1, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl); - CHECK(fid, FAIL, "H5Fopen"); - fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); - CHECK(fid2, FAIL, "H5Fopen"); - - /* Close file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - /* Close file */ - ret = H5Fclose(fid2); - CHECK(ret, FAIL, "H5Fclose"); - - /* - * Case 4: 1) RDWR|SWMR_WRITE 2) RDWR|SWMR_WRITE : should succeed - */ - fid = H5Fopen(FILE1, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl); - CHECK(fid, FAIL, "H5Fopen"); - fid2 = H5Fopen(FILE1, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl); - CHECK(fid2, FAIL, "H5Fopen"); - - /* Close file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - /* Close file */ - ret = H5Fclose(fid2); - CHECK(ret, FAIL, "H5Fclose"); - - /* - * Case 5: 1) RDWR|SWMR_WRITE 2) RDONLY|SWMR_READ : should succeed - */ - fid = H5Fopen(FILE1, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl); - CHECK(fid, FAIL, "H5Fopen"); - fid2 = H5Fopen(FILE1, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl); - CHECK(fid2, FAIL, "H5Fopen"); - - /* Close file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - /* Close file */ - ret = H5Fclose(fid2); - CHECK(ret, FAIL, "H5Fclose"); - - /* - * Case 6: 1) RDWR|SWMR_WRITE 2) RDONLY : should succeed - */ - fid = H5Fopen(FILE1, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl); - CHECK(fid, FAIL, "H5Fopen"); - fid2 = H5Fopen(FILE1, H5F_ACC_RDONLY, H5P_DEFAULT); - CHECK(fid2, FAIL, "H5Fopen"); - - /* Close file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - /* Close file */ - ret = H5Fclose(fid2); - CHECK(ret, FAIL, "H5Fclose"); - - /* - * Case 7: 1) RDONLY|SWMR_READ 2)RDWR : should fail - */ - fid = H5Fopen(FILE1, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl); - CHECK(fid, FAIL, "H5Fopen"); - - H5E_BEGIN_TRY { - fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); - } H5E_END_TRY; - VERIFY(fid2, FAIL, "H5Fopen"); - - /* Close file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - /* - * Case 8: 1) RDONLY|SWMR_READ 2) RDWR|SWMR_WRITE : should fail - */ - fid = H5Fopen(FILE1, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl); - CHECK(fid, FAIL, "H5Fopen"); - - H5E_BEGIN_TRY { - fid2 = H5Fopen(FILE1, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl); - } H5E_END_TRY; - VERIFY(fid2, FAIL, "H5Fopen"); - - /* Close file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - /* - * Case 9: 1) RDONLY|SWMR_READ 2) RDONLY|SWMR_READ : should succeed - */ - fid = H5Fopen(FILE1, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl); - CHECK(fid, FAIL, "H5Fopen"); - fid2 = H5Fopen(FILE1, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl); - CHECK(fid2, FAIL, "H5Fopen"); - - /* Close file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - /* Close file */ - ret = H5Fclose(fid2); - CHECK(ret, FAIL, "H5Fclose"); - - /* - * Case 10: 1) RDONLY|SWMR_READ 2) RDONLY : should succeed - */ - fid = H5Fopen(FILE1, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl); - CHECK(fid, FAIL, "H5Fopen"); - fid2 = H5Fopen(FILE1, H5F_ACC_RDONLY, H5P_DEFAULT); - CHECK(fid2, FAIL, "H5Fopen"); - - /* Close file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - /* Close file */ - ret = H5Fclose(fid2); - CHECK(ret, FAIL, "H5Fclose"); - - /* - * Case 11: 1) RDONLY 2) RDWR|SWMR_WRITE: should fail - */ - fid = H5Fopen(FILE1, H5F_ACC_RDONLY, H5P_DEFAULT); - CHECK(fid, FAIL, "H5Fopen"); - - H5E_BEGIN_TRY { - fid2 = H5Fopen(FILE1, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl); - } H5E_END_TRY; - VERIFY(fid2, FAIL, "H5Fopen"); - - /* Close file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - /* - * Case 12: 1) RDONLY 2) RDONLY|SWMR_READ : should fail - */ - fid = H5Fopen(FILE1, H5F_ACC_RDONLY, H5P_DEFAULT); - CHECK(fid, FAIL, "H5Fopen"); - - H5E_BEGIN_TRY { - fid2 = H5Fopen(FILE1, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl); - } H5E_END_TRY; - VERIFY(fid2, FAIL, "H5Fopen"); - - /* Close file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - /* Close the property list */ - ret=H5Pclose(fapl); - CHECK(ret, FAIL, "H5Pclose"); - -} /* end test_file_lock_swmr_same() */ - - -/**************************************************************** -** -** test_file_lock_concur(): -** With the implementation of file locking, this test checks file -** open with different combinations of flags. -** This is for concurrent access. -** -*****************************************************************/ -static void -test_file_lock_concur(void) -{ - hid_t fid; /* File ID */ - herr_t ret; /* Generic return value */ - 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_ret_value; /* Exit status of the child */ - - /* Output message about test being performed */ - MESSAGE(5, ("Testing file open with different combinations of flags--concurrent access\n")); - -#if !(defined(H5_HAVE_FORK) && defined(H5_HAVE_WAITPID)) - - SKIPPED(); - HDputs(" Test skipped due to fork or waitpid not defined."); - -#elif !defined(H5_HAVE_FLOCK) - - SKIPPED(); - HDputs(" Test skipped due to a lack of flock() on this system."); - -#else /* defined(H5_HAVE_FORK && defined(H5_HAVE_WAITPID) */ - - /* Create the test file */ - fid = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); - CHECK(fid, FAIL, "H5Fopen"); - - /* Close the file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - /* - * Case 1: 1) RDWR 2) RDWR : should fail - */ - - /* Remove the message file to be sure */ - HDremove(DONE_MESSAGE); - - /* Fork child process */ - childpid = HDfork(); - CHECK(childpid, FAIL, "fork"); - - if(childpid == 0) { /* Child process */ - hid_t child_fid; /* File ID */ - - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) - exit(1); - - /* Open the test file */ - child_fid = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); - - /* Should fail */ - if(child_fid == FAIL) - exit(0); - exit(1); - } - - /* Open the test file */ - fid = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); - CHECK(fid, FAIL, "H5Fopen"); - - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); - - /* Wait for child process to complete */ - tmppid = HDwaitpid(childpid, &child_status, child_wait_option); - CHECK(tmppid, FAIL, "waitpid"); - - /* Check if child terminated normally */ - ret = WIFEXITED(child_status); - CHECK(ret, FAIL, "child process terminated abnormally"); - - /* Check exit status of the child */ - child_ret_value = WEXITSTATUS(child_status); - VERIFY(child_ret_value, 0, "child process exited with non-zero code"); - - /* Close the file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - /* - * Case 2: 1) RDWR 2) RDONLY : should fail - */ - /* Remove the message file just to be sure */ - HDremove(DONE_MESSAGE); - - /* Fork child process */ - childpid = HDfork(); - CHECK(childpid, FAIL, "fork"); - - if(childpid == 0) { /* Child process */ - hid_t child_fid; /* File ID */ - - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) - exit(1); - - /* Opens the test file */ - child_fid = H5Fopen(FILE1, H5F_ACC_RDONLY, H5P_DEFAULT); - - /* Should fail */ - if(child_fid == FAIL) - exit(0); - exit(1); - } - - /* Opens the test file */ - fid = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); - CHECK(fid, FAIL, "H5Fopen"); - - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); - - /* Wait for child process to complete */ - tmppid = HDwaitpid(childpid, &child_status, child_wait_option); - CHECK(tmppid, FAIL, "waitpid"); - - /* Check if child terminated normally */ - ret = WIFEXITED(child_status); - CHECK(ret, FAIL, "child process terminated abnormally"); - - /* Check exit status of the child */ - child_ret_value = WEXITSTATUS(child_status); - VERIFY(child_ret_value, 0, "child process exited with non-zero code"); - - /* Close the file */ - H5Fclose(fid); - - /* - * Case 3: 1) RDONLY 2) RDWR : should fail - */ - - /* Remove the message file just to be sure */ - HDremove(DONE_MESSAGE); - - /* Fork child process */ - childpid = HDfork(); - CHECK(childpid, FAIL, "fork"); - - if(childpid == 0) { /* Child process */ - hid_t child_fid; /* File ID */ - - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) - exit(1); - - /* Opens the test file */ - child_fid = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); - - /* Should fail */ - if(child_fid == FAIL) - exit(0); - exit(1); - } - - /* Opens the test file */ - fid = H5Fopen(FILE1, H5F_ACC_RDONLY, H5P_DEFAULT); - CHECK(fid, FAIL, "H5Fopen"); - - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); - - /* Wait for child process to complete */ - tmppid = HDwaitpid(childpid, &child_status, child_wait_option); - CHECK(tmppid, FAIL, "waitpid"); - - /* Check if child terminated normally */ - ret = WIFEXITED(child_status); - CHECK(ret, FAIL, "child process terminated abnormally"); - - /* Check exit status of child process */ - child_ret_value = WEXITSTATUS(child_status); - VERIFY(child_ret_value, 0, "child process exited with non-zero code"); - - /* Close the file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - /* - * Case 4: 1) RDONLY 2) RDONLY : should succeed - */ - - HDremove(DONE_MESSAGE); - - /* Fork child process */ - childpid = HDfork(); - CHECK(childpid, FAIL, "fork"); - - if(childpid == 0) { /* Child process */ - hid_t child_fid; /* File ID */ - herr_t child_ret; /* Return value */ - - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) - exit(1); - - /* Opens the test file */ - child_fid = H5Fopen(FILE1, H5F_ACC_RDONLY, H5P_DEFAULT); - - /* Should succeed */ - if(child_fid >= 0) { - /* Close the file */ - child_ret = H5Fclose(child_fid); - CHECK(child_ret, FAIL, "H5Fclose"); - exit(0); - } - exit(1); - } - /* Create file */ - fid = H5Fopen(FILE1, H5F_ACC_RDONLY, H5P_DEFAULT); - CHECK(fid, FAIL, "H5Fopen"); - - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); - - /* Wait for child process to complete */ - tmppid = HDwaitpid(childpid, &child_status, child_wait_option); - CHECK(tmppid, FAIL, "waitpid"); - - /* Check if child terminated normally */ - ret = WIFEXITED(child_status); - CHECK(ret, FAIL, "child process terminated abnormally"); - - /* Check exit status of child process */ - child_ret_value = WEXITSTATUS(child_status); - VERIFY(child_ret_value, 0, "child process exited with non-zero code"); - - /* Close the file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - -#endif - -} /* end test_file_lock_concur() */ - -/**************************************************************** -** -** test_file_lock_swmr_concur(): low-level file test routine. -** With the implementation of file locking, this test checks file -** open with different combinations of flags + SWMR flags. -** This is for concurrent access. -** -*****************************************************************/ -static void -test_file_lock_swmr_concur(void) -{ - hid_t fid; /* File ID */ - hid_t fapl; /* File access property list */ - herr_t ret; /* Generic return value */ - 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_ret_value; /* Exit status of the child */ - - /* Output message about test being performed */ - MESSAGE(5, ("Testing file open with different combintations of flags + SWMR flags--concurrent access\n")); - -#if !(defined(H5_HAVE_FORK) && defined(H5_HAVE_WAITPID)) - - SKIPPED(); - HDputs(" Test skipped due to fork or waitpid not defined."); - -#elif !defined(H5_HAVE_FLOCK) - - SKIPPED(); - HDputs(" Test skipped due to a lack of flock() on this system."); - -#else /* defined(H5_HAVE_FORK && defined(H5_HAVE_WAITPID) */ - - /* Create a file access property list */ - fapl = H5Pcreate(H5P_FILE_ACCESS); - CHECK(fapl, FAIL, "H5Pcreate"); - - /* Set to use latest library format */ - ret = H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST); - CHECK(ret, FAIL, "H5Pset_libver_bounds"); - - /* Create the test file */ - fid = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); - CHECK(fid, FAIL, "H5Fopen"); - - /* Close the file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - /* - * Case 1: 1) RDWR 2) RDWR|SWMR_WRITE : should fail - */ - - /* Remove the message file to be sure */ - HDremove(DONE_MESSAGE); - - /* Fork child process */ - childpid = HDfork(); - CHECK(childpid, FAIL, "fork"); - - if(childpid == 0) { /* Child process */ - hid_t child_fid; /* File ID */ - - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) - exit(1); - - /* Open the test file */ - child_fid = H5Fopen(FILE1, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl); - - /* Should fail */ - if(child_fid == FAIL) - exit(0); - exit(1); - } - - /* Open the test file */ - fid = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); - CHECK(fid, FAIL, "H5Fopen"); - - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); - - /* Wait for child process to complete */ - tmppid = HDwaitpid(childpid, &child_status, child_wait_option); - CHECK(tmppid, FAIL, "waitpid"); - - /* Check if child terminated normally */ - ret = WIFEXITED(child_status); - CHECK(ret, FAIL, "child process terminated abnormally"); - - /* Check exit status of child process */ - child_ret_value = WEXITSTATUS(child_status); - VERIFY(child_ret_value, 0, "child process exited with non-zero code"); - - /* Close the file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - /* - * Case 2: 1) RDWR 2) RDONLY|SWMR_READ: should fail - */ - - /* Remove the message file to be sure */ - HDremove(DONE_MESSAGE); - - /* Fork child process */ - childpid = HDfork(); - CHECK(childpid, FAIL, "fork"); - - if(childpid == 0) { /* Child process */ - hid_t child_fid; /* File ID */ - - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) - exit(1); - - /* Open the test file */ - child_fid = H5Fopen(FILE1, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl); - - /* Should fail */ - if(child_fid == FAIL) - exit(0); - exit(1); - } - - /* Open the test file */ - fid = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); - CHECK(fid, FAIL, "H5Fopen"); - - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); - - /* Wait for child process to complete */ - tmppid = HDwaitpid(childpid, &child_status, child_wait_option); - CHECK(tmppid, FAIL, "waitpid"); - - /* Check if child terminated normally */ - ret = WIFEXITED(child_status); - CHECK(ret, FAIL, "child process terminated abnormally"); - - /* Check exit status of child process */ - child_ret_value = WEXITSTATUS(child_status); - VERIFY(child_ret_value, 0, "child process exited with non-zero code"); - - /* Close the file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - /* - * Case 3: 1) RDWR|SWMR_WRITE 2) RDWR : should fail - */ - - /* Remove the message file to be sure */ - HDremove(DONE_MESSAGE); - - /* Fork child process */ - childpid = HDfork(); - CHECK(childpid, FAIL, "fork"); - - if(childpid == 0) { /* Child process */ - hid_t child_fid; /* File ID */ - - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) - exit(1); - - /* Open the test file */ - child_fid = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); - - /* Should fail */ - if(child_fid == FAIL) - exit(0); - exit(1); - } - - /* Open the test file */ - fid = H5Fopen(FILE1, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl); - CHECK(fid, FAIL, "H5Fopen"); - - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); - - /* Wait for child process to complete */ - tmppid = HDwaitpid(childpid, &child_status, child_wait_option); - CHECK(tmppid, FAIL, "waitpid"); - - /* Check if child terminated normally */ - ret = WIFEXITED(child_status); - CHECK(ret, FAIL, "child process terminated abnormally"); - - /* Check exit status of child process */ - child_ret_value = WEXITSTATUS(child_status); - VERIFY(child_ret_value, 0, "child process exited with non-zero code"); - - /* Close the file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - /* - * Case 4: 1) RDWR|SWMR_WRITE 2) RDWR|SWMR_WRITE : should fail - */ - - /* Remove the message file just to be sure */ - HDremove(DONE_MESSAGE); - - /* Fork child process */ - childpid = HDfork(); - CHECK(childpid, FAIL, "fork"); - - if(childpid == 0) { /* Child process */ - hid_t child_fid; /* File ID */ - - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) - exit(1); - - /* Open the test file */ - child_fid = H5Fopen(FILE1, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl); - - /* Should fail */ - if(child_fid == FAIL) - exit(0); - exit(1); - } - - /* Open the test file */ - fid = H5Fopen(FILE1, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl); - CHECK(fid, FAIL, "H5Fopen"); - - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); - - /* Wait for child process to complete */ - tmppid = HDwaitpid(childpid, &child_status, child_wait_option); - CHECK(tmppid, FAIL, "waitpid"); - - /* Check if child terminated normally */ - ret = WIFEXITED(child_status); - CHECK(ret, FAIL, "child process terminated abnormally"); - - /* Check exit status of child process */ - child_ret_value = WEXITSTATUS(child_status); - VERIFY(child_ret_value, 0, "child process exited with non-zero code"); - - /* Close the file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - /* - * Case 5: 1) RDWR|SWMR_WRITE 2) RDONLY|SWMR_READ : should succeed - */ - - /* Remove the message file just to be sure */ - HDremove(DONE_MESSAGE); - - /* Fork child process */ - childpid = HDfork(); - CHECK(childpid, FAIL, "fork"); - - if(childpid == 0) { /* Child process */ - hid_t child_fid; /* File ID */ - herr_t child_ret; /* Return value */ - - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) - exit(1); - - /* Open the test file */ - child_fid = H5Fopen(FILE1, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl); - - /* Should succeed */ - if(child_fid >= 0) { - child_ret = H5Fclose(child_fid); - CHECK(child_ret, FAIL, "H5Fclose"); - exit(0); - } - exit(1); - } - - /* Open the test file */ - fid = H5Fopen(FILE1, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl); - CHECK(fid, FAIL, "H5Fopen"); - - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); - - /* Wait for child process to complete */ - tmppid = HDwaitpid(childpid, &child_status, child_wait_option); - CHECK(tmppid, FAIL, "waitpid"); - - /* Check if child terminated normally */ - ret = WIFEXITED(child_status); - CHECK(ret, FAIL, "child process terminated abnormally"); - - /* Check exit status of child process */ - child_ret_value = WEXITSTATUS(child_status); - VERIFY(child_ret_value, 0, "child process exited with non-zero code"); - - /* Close the file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - /* - * Case 6: 1) RDWR|SWMR_WRITE 2) RDONLY : should fail - */ - - /* Remove the message file just to be sure */ - HDremove(DONE_MESSAGE); - - /* Fork child process */ - childpid = HDfork(); - CHECK(childpid, FAIL, "fork"); - - if(childpid == 0) { /* Child process */ - hid_t child_fid; /* File ID */ - - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) - exit(1); - - /* Open the test file */ - child_fid = H5Fopen(FILE1, H5F_ACC_RDONLY, H5P_DEFAULT); - /* Should fail */ - if(child_fid == FAIL) - exit(0); - exit(1); - } - - /* Open the test file */ - fid = H5Fopen(FILE1, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl); - CHECK(fid, FAIL, "H5Fopen"); - - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); - - /* Wait for child process to complete */ - tmppid = HDwaitpid(childpid, &child_status, child_wait_option); - CHECK(tmppid, FAIL, "waitpid"); - - /* Check if child terminated normally */ - ret = WIFEXITED(child_status); - CHECK(ret, FAIL, "child process terminated abnormally"); - - /* Check exit status of child process */ - child_ret_value = WEXITSTATUS(child_status); - VERIFY(child_ret_value, 0, "child process exited with non-zero code"); - - /* Close the file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - /* - * Case 7: 1) RDONLY|SWMR_READ 2) RDWR : should fail - */ - - /* Remove the message file just to be sure */ - HDremove(DONE_MESSAGE); - - /* Fork child process */ - childpid = HDfork(); - CHECK(childpid, FAIL, "fork"); - - if(childpid == 0) { /* Child process */ - hid_t child_fid; /* File ID */ - - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) - exit(1); - - /* Open the test file */ - child_fid = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); - /* Should fail */ - if(child_fid == FAIL) - exit(0); - exit(1); - } - - /* Open the test file */ - fid = H5Fopen(FILE1, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl); - CHECK(fid, FAIL, "H5Fopen"); - - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); - - /* Wait for child process to complete */ - tmppid = HDwaitpid(childpid, &child_status, child_wait_option); - CHECK(tmppid, FAIL, "waitpid"); - - /* Check if child terminated normally */ - ret = WIFEXITED(child_status); - CHECK(ret, FAIL, "child process terminated abnormally"); - - /* Check exit status of child process */ - child_ret_value = WEXITSTATUS(child_status); - VERIFY(child_ret_value, 0, "child process exited with non-zero code"); - - /* Close the file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - /* - * Case 8: 1) RDONLY|SWMR_READ 2) RDWR|SWMR_WRITE : should fail - */ - - /* Remove the message file just to be sure */ - HDremove(DONE_MESSAGE); - - /* Fork child process */ - childpid = HDfork(); - CHECK(childpid, FAIL, "fork"); - - if(childpid == 0) { /* Child process */ - hid_t child_fid; /* File ID */ - - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) - exit(1); - - /* Open the test file */ - child_fid = H5Fopen(FILE1, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl); - /* Should fail */ - if(child_fid == FAIL) - exit(0); - exit(1); - } - - /* Open the test file */ - fid = H5Fopen(FILE1, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl); - CHECK(fid, FAIL, "H5Fopen"); - - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); - - /* Wait for child process to complete */ - tmppid = HDwaitpid(childpid, &child_status, child_wait_option); - CHECK(tmppid, FAIL, "waitpid"); - - /* Check if child terminated normally */ - ret = WIFEXITED(child_status); - CHECK(ret, FAIL, "child process terminated abnormally"); - - /* Check exit status of child process */ - child_ret_value = WEXITSTATUS(child_status); - VERIFY(child_ret_value, 0, "child process exited with non-zero code"); - - /* Close the file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - - /* - * Case 9: 1) RDONLY|SWMR_READ 2) RDONLY|SWMR_READ : should succeed - */ - - /* Remove the message file just to be sure */ - HDremove(DONE_MESSAGE); - - /* Fork child process */ - childpid = HDfork(); - CHECK(childpid, FAIL, "fork"); - - if(childpid == 0) { /* Child process */ - hid_t child_fid; /* File ID */ - herr_t child_ret; /* Return value */ - - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) - exit(1); - - /* Open the test file */ - child_fid = H5Fopen(FILE1, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl); - - /* Should succeed */ - if(child_fid >= 0) { - child_ret = H5Fclose(child_fid); - CHECK(child_ret, FAIL, "H5Fclose"); - exit(0); - } - exit(1); - } - - /* Open the test file */ - fid = H5Fopen(FILE1, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl); - CHECK(fid, FAIL, "H5Fopen"); - - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); - - /* Wait for child process to complete */ - tmppid = HDwaitpid(childpid, &child_status, child_wait_option); - CHECK(tmppid, FAIL, "waitpid"); - - /* Check if child terminated normally */ - ret = WIFEXITED(child_status); - CHECK(ret, FAIL, "child process terminated abnormally"); - - /* Check exit status of child process */ - child_ret_value = WEXITSTATUS(child_status); - VERIFY(child_ret_value, 0, "child process exited with non-zero code"); - - /* Close the file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - /* - * Case 10: 1) RDONLY|SWMR_READ 2) RDONLY : should succeed - */ - - /* Remove the message file just to be sure */ - HDremove(DONE_MESSAGE); - - /* Fork child process */ - childpid = HDfork(); - CHECK(childpid, FAIL, "fork"); - - if(childpid == 0) { /* Child process */ - hid_t child_fid; /* File ID */ - herr_t child_ret; /* Return value */ - - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) - exit(1); - - /* Open the test file */ - child_fid = H5Fopen(FILE1, H5F_ACC_RDONLY, H5P_DEFAULT); - - /* Should succeed */ - if(child_fid >= 0) { - child_ret = H5Fclose(child_fid); - CHECK(child_ret, FAIL, "H5Fclose"); - exit(0); - } - exit(1); - } - - /* Open the test file */ - fid = H5Fopen(FILE1, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl); - CHECK(fid, FAIL, "H5Fopen"); - - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); - - /* Wait for child process to complete */ - tmppid = HDwaitpid(childpid, &child_status, child_wait_option); - CHECK(tmppid, FAIL, "waitpid"); - - /* Check if child terminated normally */ - ret = WIFEXITED(child_status); - CHECK(ret, FAIL, "child process terminated abnormally"); - - /* Check exit status of child process */ - child_ret_value = WEXITSTATUS(child_status); - VERIFY(child_ret_value, 0, "child process exited with non-zero code"); - - /* Close the file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - - /* - * Case 11: 1) RDONLY 2) RDWR|SWMR_WRITE : should fail - */ - - /* Remove the message file just to be sure */ - HDremove(DONE_MESSAGE); - - /* Fork child process */ - childpid = HDfork(); - CHECK(childpid, FAIL, "fork"); - - if(childpid == 0) { /* Child process */ - hid_t child_fid; /* File ID */ - - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) - exit(1); - - /* Open the test file */ - child_fid = H5Fopen(FILE1, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl); - /* Should fail */ - if(child_fid == FAIL) - exit(0); - exit(1); - } - /* Open the test file */ - fid = H5Fopen(FILE1, H5F_ACC_RDONLY, H5P_DEFAULT); - CHECK(fid, FAIL, "H5Fopen"); - - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); - - /* Wait for child process to complete */ - tmppid = HDwaitpid(childpid, &child_status, child_wait_option); - CHECK(tmppid, FAIL, "waitpid"); - - /* Check if child terminated normally */ - ret = WIFEXITED(child_status); - CHECK(ret, FAIL, "child process terminated abnormally"); - - /* Check exit status of child process */ - child_ret_value = WEXITSTATUS(child_status); - VERIFY(child_ret_value, 0, "child process exited with non-zero code"); - - /* Close the file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - /* - * Case 12: 1) RDONLY 2) RDONLY|SWMR_READ : should succeed - */ - - /* Remove the message file just to be sure */ - HDremove(DONE_MESSAGE); - - /* Fork child process */ - childpid = HDfork(); - CHECK(childpid, FAIL, "fork"); - - if(childpid == 0) { /* Child process */ - hid_t child_fid; /* File ID */ - herr_t child_ret; /* Return value */ - - /* Wait till parent process completes the open */ - if(h5_wait_message(DONE_MESSAGE) < 0) - exit(1); - - /* Open the test file */ - child_fid = H5Fopen(FILE1, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, fapl); - - /* Should succeed */ - if(child_fid >= 0) { - child_ret = H5Fclose(child_fid); - CHECK(child_ret, FAIL, "H5Fclose"); - exit(0); - } - exit(1); - } - - /* Open the test file */ - fid = H5Fopen(FILE1, H5F_ACC_RDONLY, H5P_DEFAULT); - CHECK(fid, FAIL, "H5Fopen"); - - /* Send the message that the open completes */ - h5_send_message(DONE_MESSAGE); - - /* Wait for child process to complete */ - tmppid = HDwaitpid(childpid, &child_status, child_wait_option); - CHECK(tmppid, FAIL, "waitpid"); - - /* Check if child terminated normally */ - ret = WIFEXITED(child_status); - CHECK(ret, FAIL, "child process terminated abnormally"); - - /* Check exit status of child process */ - child_ret_value = WEXITSTATUS(child_status); - VERIFY(child_ret_value, 0, "child process exited with non-zero code"); - - /* Close the file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - - /* Close the property list */ - ret=H5Pclose(fapl); - CHECK(ret, FAIL, "H5Pclose"); -#endif - -} /* end test_file_lock_swmr_concur() */ -/**************************************************************** -** ** test_deprec(): ** Test deprecated functionality. ** @@ -5104,12 +3699,12 @@ test_file(void) test_libver_macros2(); /* Test the macros for library version comparison */ /* * The two tests: test_swmr_write() and test_swmr_read() are removed. - * They are covered by the following new tests. + * They are covered by the following tests in swmr.c: + * test_file_lock_same(); + * test_file_lock_swmr_same(); + * test_file_lock_concur(); + * test_file_lock_swmr_concur(); */ - test_file_lock_same(); /* Tests for file open flags--single process access */ - test_file_lock_swmr_same(); /* Tests for file open flags+SWMR flags--single process access */ - test_file_lock_concur(); /* Tests for file open flags--concurrent access */ - test_file_lock_swmr_concur(); /* Tests for file open flags+SWMR flags--concurrent access */ #ifndef H5_NO_DEPRECATED_SYMBOLS test_deprec(); /* Test deprecated routines */ #endif /* H5_NO_DEPRECATED_SYMBOLS */ |