summaryrefslogtreecommitdiffstats
path: root/test/ttsafe_attr_vlen.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/ttsafe_attr_vlen.c')
-rw-r--r--test/ttsafe_attr_vlen.c176
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..b07e362
--- /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://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)
+{
+ pthread_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 */
+ 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++)
+ pthread_create(&threads[i], NULL, tts_attr_vlen_thread, NULL);
+
+ /* Wait for the threads to end */
+ for(i = 0; i < NUM_THREADS; i++)
+ pthread_join(threads[i], NULL);
+
+} /* end tts_attr_vlen() */
+
+/* Start execution for each thread */
+void *
+tts_attr_vlen_thread(void *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 */
+ 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*/
+