mirror of
https://github.com/HDFGroup/hdf5.git
synced 2024-12-21 07:51:46 +08:00
178 lines
6.3 KiB
C
178 lines
6.3 KiB
C
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* 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 COPYING file, which can be found at the root of the source code *
|
|
* distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
|
|
* If you do not have access to either file, you may request a copy from *
|
|
* help@hdfgroup.org. *
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
/********************************************************************
|
|
*
|
|
* Testing for thread safety in H5A library operations.
|
|
* ------------------------------------------------------------------
|
|
*
|
|
* Purpose: Verify that the segmentation fault described in HDFFV-11080
|
|
* is fixed.
|
|
*
|
|
* This test simulates what the user did to trigger the error:
|
|
* --Create an HDF5 file
|
|
* --Create an attribute with variable length string datatype
|
|
* --Attach the attribute to a group
|
|
* --Write data to the attribute
|
|
* --Close the file
|
|
* --Create NUM_THREADS threads
|
|
* --For each thread:
|
|
* --Open the test file
|
|
* --Open and read the attribute for each opened file
|
|
*
|
|
* The cause of the problem in this jira issue is due to the file pointer
|
|
* that is set in the variable length string datatype for the attribute.
|
|
* That file pointer is already closed and therefore needs to be set to
|
|
* the current opened file pointer when the attribute is accessed.
|
|
* Similar patch up was done before when reading dataset in H5D__read()
|
|
* in src/H5Aint.c.
|
|
* Hopefully this kind of patch can go away when we resolve the
|
|
* shared file pointer issue.
|
|
*
|
|
********************************************************************/
|
|
|
|
#include "ttsafe.h"
|
|
|
|
#ifdef H5_HAVE_THREADSAFE
|
|
|
|
#define FILENAME "ttsafe_attr_vlen.h5"
|
|
#define ATTR_NAME "root_attr"
|
|
#define NUM_THREADS 32
|
|
|
|
void *tts_attr_vlen_thread(void *);
|
|
|
|
void
|
|
tts_attr_vlen(void)
|
|
{
|
|
H5TS_thread_t threads[NUM_THREADS] = {0}; /* Thread declaration */
|
|
hid_t fid = H5I_INVALID_HID; /* File ID */
|
|
hid_t gid = H5I_INVALID_HID; /* Group ID */
|
|
hid_t atid = H5I_INVALID_HID; /* Datatype ID for attribute */
|
|
hid_t asid = H5I_INVALID_HID; /* Dataspace ID for attribute */
|
|
hid_t aid = H5I_INVALID_HID; /* The attribute ID */
|
|
const char *string_attr = "2.0"; /* The attribute data */
|
|
int ret; /* Return value */
|
|
int i; /* Local index variable */
|
|
|
|
/* Create the HDF5 test file */
|
|
fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
|
|
CHECK(fid, H5I_INVALID_HID, "H5Fcreate");
|
|
|
|
/* Create variable length string type for attribute */
|
|
atid = H5Tcopy(H5T_C_S1);
|
|
CHECK(atid, H5I_INVALID_HID, "H5Tcopy");
|
|
H5Tset_size(atid, H5T_VARIABLE);
|
|
|
|
/* Create dataspace for attribute */
|
|
asid = H5Screate(H5S_SCALAR);
|
|
CHECK(asid, H5I_INVALID_HID, "H5Screate");
|
|
|
|
/* Open the root group */
|
|
gid = H5Gopen2(fid, "/", H5P_DEFAULT);
|
|
CHECK(gid, H5I_INVALID_HID, "H5Gopen2");
|
|
|
|
/* Attach the attribute to the root group */
|
|
aid = H5Acreate2(gid, ATTR_NAME, atid, asid, H5P_DEFAULT, H5P_DEFAULT);
|
|
CHECK(aid, H5I_INVALID_HID, "H5Acreate2");
|
|
|
|
/* Write data to the attribute */
|
|
ret = H5Awrite(aid, atid, &string_attr);
|
|
CHECK(ret, H5I_INVALID_HID, "H5Awrite");
|
|
|
|
/* Close IDs */
|
|
ret = H5Sclose(asid);
|
|
CHECK(ret, H5I_INVALID_HID, "H5Sclose");
|
|
|
|
ret = H5Aclose(aid);
|
|
CHECK(ret, H5I_INVALID_HID, "H5Aclose");
|
|
|
|
ret = H5Gclose(gid);
|
|
CHECK(ret, H5I_INVALID_HID, "H5Gclose");
|
|
|
|
ret = H5Fclose(fid);
|
|
CHECK(ret, H5I_INVALID_HID, "H5Fclose");
|
|
|
|
ret = H5Tclose(atid);
|
|
CHECK(ret, H5I_INVALID_HID, "H5Tclose");
|
|
|
|
/* Start multiple threads and execute tts_attr_vlen_thread() for each thread */
|
|
for(i = 0; i < NUM_THREADS; i++) {
|
|
threads[i] = H5TS_create_thread(tts_attr_vlen_thread, NULL, NULL);
|
|
}
|
|
|
|
/* Wait for the threads to end */
|
|
for(i = 0; i < NUM_THREADS; i++)
|
|
H5TS_wait_for_thread(threads[i]);
|
|
|
|
} /* end tts_attr_vlen() */
|
|
|
|
/* Start execution for each thread */
|
|
void *
|
|
tts_attr_vlen_thread(void H5_ATTR_UNUSED *client_data)
|
|
{
|
|
hid_t fid = H5I_INVALID_HID; /* File ID */
|
|
hid_t gid = H5I_INVALID_HID; /* Group ID */
|
|
hid_t aid = H5I_INVALID_HID; /* Attribute ID */
|
|
hid_t atid = H5I_INVALID_HID; /* Datatype ID for the attribute */
|
|
char *string_attr_check; /* The attribute data being read */
|
|
const char *string_attr = "2.0"; /* The expected attribute data */
|
|
herr_t ret; /* Return value */
|
|
|
|
/* Open the test file */
|
|
fid = H5Fopen(FILENAME, H5F_ACC_RDONLY, H5P_DEFAULT);
|
|
CHECK(fid, H5I_INVALID_HID, "H5Fopen");
|
|
|
|
/* Open the group */
|
|
gid = H5Gopen2(fid, "/", H5P_DEFAULT);
|
|
CHECK(gid, H5I_INVALID_HID, "H5Gopen");
|
|
|
|
/* Open the attribte */
|
|
aid = H5Aopen(gid, "root_attr", H5P_DEFAULT);
|
|
CHECK(aid, H5I_INVALID_HID, "H5Aopen");
|
|
|
|
/* Get the attribute datatype */
|
|
atid = H5Aget_type(aid);
|
|
CHECK(atid, H5I_INVALID_HID, "H5Aget_type");
|
|
|
|
/* Read the attribute */
|
|
ret = H5Aread(aid, atid, &string_attr_check);
|
|
CHECK(ret, FAIL, "H5Aclose");
|
|
|
|
/* Verify the attribute data is as expected */
|
|
VERIFY_STR(string_attr_check, string_attr, "H5Aread");
|
|
|
|
/* Close IDs */
|
|
ret = H5Aclose(aid);
|
|
CHECK(ret, FAIL, "H5Aclose");
|
|
|
|
ret = H5Gclose(gid);
|
|
CHECK(ret, FAIL, "H5Aclose");
|
|
|
|
ret = H5Fclose(fid);
|
|
CHECK(ret, FAIL, "H5Aclose");
|
|
|
|
ret = H5Tclose(atid);
|
|
CHECK(ret, FAIL, "H5Aclose");
|
|
|
|
return NULL;
|
|
} /* end tts_attr_vlen_thread() */
|
|
|
|
void
|
|
cleanup_attr_vlen(void)
|
|
{
|
|
HDunlink(FILENAME);
|
|
}
|
|
|
|
#endif /*H5_HAVE_THREADSAFE*/
|
|
|