hdf5/test/ttsafe_attr_vlen.c
Dana Robinson 7f1e49206d
Renamed COPYING to LICENSE (#4978)
This is where most people will expect to find license information. The
COPYING_LBNL_HDF5 file has also been renamed to LICENSE_LBNL_HDF5.
The licenses are unchanged.
2024-10-18 21:13:04 -07:00

191 lines
7.0 KiB
C

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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 LICENSE 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
H5TS_THREAD_RETURN_TYPE tts_attr_vlen_thread(void *);
void
tts_attr_vlen(const void H5_ATTR_UNUSED *params)
{
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++)
if (H5TS_thread_create(&threads[i], tts_attr_vlen_thread, NULL) < 0)
TestErrPrintf("thread # %d did not start", i);
/* Wait for the threads to end */
for (i = 0; i < NUM_THREADS; i++)
if (H5TS_thread_join(threads[i], NULL) < 0)
TestErrPrintf("thread %d failed to join", i);
} /* end tts_attr_vlen() */
/* Start execution for each thread */
H5TS_THREAD_RETURN_TYPE
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 asid = H5I_INVALID_HID; /* Dataspace ID for the attribute */
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 attribute */
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");
/* Get the dataspace for the attribute */
asid = H5Aget_space(aid);
CHECK(asid, H5I_INVALID_HID, "H5Aget_space");
/* 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");
/* Free the attribute data */
ret = H5Treclaim(atid, asid, H5P_DEFAULT, &string_attr_check);
CHECK(ret, FAIL, "H5Dvlen_reclaim");
/* Close IDs */
ret = H5Aclose(aid);
CHECK(ret, FAIL, "H5Aclose");
ret = H5Sclose(asid);
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 (H5TS_thread_ret_t)0;
} /* end tts_attr_vlen_thread() */
void
cleanup_attr_vlen(void H5_ATTR_UNUSED *params)
{
if (GetTestCleanup()) {
HDunlink(FILENAME);
}
}
#endif /*H5_HAVE_THREADSAFE*/