hdf5/test/ttsafe_error_stacks.c

113 lines
3.6 KiB
C
Raw Normal View History

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* 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 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. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "ttsafe.h"
#ifdef H5_HAVE_THREADSAFE
#define ERR_CLS_NAME "Custom error class"
#define ERR_CLS_LIB_NAME "example_lib"
#define ERR_CLS_LIB_VERSION "0.1"
#define ERR_MAJOR_MSG "Okay, Houston, we've had a problem here"
#define ERR_MINOR_MSG "Oops!"
H5TS_THREAD_RETURN_TYPE generate_hdf5_error(void *arg);
H5TS_THREAD_RETURN_TYPE generate_user_error(void *arg);
hid_t err_cls_id = H5I_INVALID_HID;
/* Helper routine to generate an HDF5 library error */
H5TS_THREAD_RETURN_TYPE
generate_hdf5_error(void H5_ATTR_UNUSED *arg)
{
H5TS_thread_ret_t ret_value = 0;
ssize_t nobjs = 0;
H5E_BEGIN_TRY
{
nobjs = H5Fget_obj_count(H5I_INVALID_HID, H5F_OBJ_ALL);
}
H5E_END_TRY
/* Expect call to fail */
VERIFY(nobjs, FAIL, "H5Fget_obj_count");
return ret_value;
}
/* Helper routine to generate a user-defined error */
H5TS_THREAD_RETURN_TYPE
generate_user_error(void H5_ATTR_UNUSED *arg)
{
H5TS_thread_ret_t ret_value = 0;
hid_t major = H5I_INVALID_HID;
hid_t minor = H5I_INVALID_HID;
herr_t status = FAIL;
err_cls_id = H5Eregister_class(ERR_CLS_NAME, ERR_CLS_LIB_NAME, ERR_CLS_LIB_VERSION);
CHECK(err_cls_id, H5I_INVALID_HID, "H5Eregister_class");
major = H5Ecreate_msg(err_cls_id, H5E_MAJOR, ERR_MAJOR_MSG);
CHECK(major, H5I_INVALID_HID, "H5Ecreate_msg");
minor = H5Ecreate_msg(err_cls_id, H5E_MINOR, ERR_MINOR_MSG);
CHECK(minor, H5I_INVALID_HID, "H5Ecreate_msg");
status = H5Epush2(H5E_DEFAULT, __FILE__, __func__, __LINE__, err_cls_id, major, minor, "Hello, error\n");
CHECK(status, FAIL, "H5Epush2");
return ret_value;
}
/*
**********************************************************************
* tts_error_stacks
*
* Test that error stacks with user-defined error classes and messages
* in secondary threads are properly cleaned up at library shutdown time.
**********************************************************************
*/
void
tts_error_stacks(const void H5_ATTR_UNUSED *params)
{
H5TS_thread_t threads[2];
herr_t status = FAIL;
/* Open library */
H5open();
status = H5TS_thread_create(&threads[0], generate_hdf5_error, NULL);
CHECK(status, FAIL, "H5TS_thread_create");
status = H5TS_thread_join(threads[0], NULL);
CHECK(status, FAIL, "H5TS_thread_join");
status = H5TS_thread_create(&threads[1], generate_user_error, NULL);
CHECK(status, FAIL, "H5TS_thread_create");
status = H5TS_thread_join(threads[1], NULL);
CHECK(status, FAIL, "H5TS_thread_join");
if (err_cls_id <= 0) {
TestErrPrintf("Failed to set up user error\n");
return;
}
status = H5Eunregister_class(err_cls_id);
CHECK(status, FAIL, "H5Eunregister_class");
/* Close library */
H5close();
}
#endif