diff options
Diffstat (limited to 'test/ttsafe_attr_vlen.c')
-rw-r--r-- | test/ttsafe_attr_vlen.c | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/test/ttsafe_attr_vlen.c b/test/ttsafe_attr_vlen.c new file mode 100644 index 0000000..ecd0aa6 --- /dev/null +++ b/test/ttsafe_attr_vlen.c @@ -0,0 +1,176 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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://www.hdfgroup.org/licenses. * + * 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*/ |