From 35fe1e28474963868aeb46b1a8d0cbd4468cd378 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Fri, 19 May 2000 18:00:03 -0500 Subject: [svn-r2287] Changed ttsafe_* test files so that they create their own HDF5 file (they were only creating one for all of them). Also changed so that, if they got an error, it actually specifies that the tests failed on the screen instead of succeeded ;-) --- test/ttsafe.c | 531 ++++++++++++++++++++++++++------------------------ test/ttsafe_acreate.c | 240 ++++++++++++----------- test/ttsafe_cancel.c | 295 ++++++++++++++-------------- test/ttsafe_dcreate.c | 292 ++++++++++++++------------- test/ttsafe_error.c | 260 ++++++++++++------------ 5 files changed, 828 insertions(+), 790 deletions(-) diff --git a/test/ttsafe.c b/test/ttsafe.c index cf87752..a228076 100644 --- a/test/ttsafe.c +++ b/test/ttsafe.c @@ -17,26 +17,25 @@ static char RcsId[] = "@(#)$Revision$"; /* $Id$ */ /* - FILE - ttsafe.c - HDF5 threadsafe testing framework main file. - - REMARKS - General test wrapper for HDF5 library thread safety test programs - - DESIGN - Each test function should be implemented as function having no - parameters and returning void (i.e. no return value). They should be put - into the list of InitTest() calls in main() below. Functions which depend - on other functionality should be placed below the InitTest() call for the - base functionality testing. - Each test module should include ttsafe.h and define a unique set of - names for test files they create. - - BUGS/LIMITATIONS - - EXPORTED ROUTINES/VARIABLES: - Two variables are exported: num_errs, and Verbosity. - + * FILE + * ttsafe.c - HDF5 threadsafe testing framework main file. + * + * REMARKS + * General test wrapper for HDF5 library thread safety test programs + * + * DESIGN + * Each test function should be implemented as function having no + * parameters and returning void (i.e. no return value). They should be put + * into the list of InitTest() calls in main() below. Functions which depend + * on other functionality should be placed below the InitTest() call for the + * base functionality testing. + * Each test module should include ttsafe.h and define a unique set of + * names for test files they create. + * + * BUGS/LIMITATIONS + * + * EXPORTED ROUTINES/VARIABLES: + * Two variables are exported: num_errs, and Verbosity. */ #if defined __MWERKS__ @@ -45,6 +44,16 @@ static char RcsId[] = "@(#)$Revision$"; #include +#include + +#ifndef H5_HAVE_THREADSAFE +int main(void) +{ + printf("Test skipped because THREADSAFE not enabled\n"); + return 0; +} +#else + #define MAXNUMOFTESTS 50 #define HDF5_TEST_MASTER @@ -52,283 +61,291 @@ static char RcsId[] = "@(#)$Revision$"; #define NAME_OFFSET 6 /* offset for "name" */ /* Internal Variables */ -static int Index = 0; +static int Index = 0; /* Global variables */ -int num_errs = 0; -int Verbosity; - -#include +int num_errs = 0; +int Verbosity; -#ifndef H5_HAVE_THREADSAFE -int main(void) -{ - printf("Test skipped because THREADSAFE not enabled\n"); - return 0; -} -#else /* ANY new test needs to have a prototype in tproto.h */ struct TestStruct { - int NumErrors; - char Description[64]; - int SkipFlag; - char Name[16]; - void (*Call) (void); - void (*Cleanup) (void); + int NumErrors; + char Description[64]; + int SkipFlag; + char Name[16]; + void (*Call)(void); + void (*Cleanup)(void); } Test[MAXNUMOFTESTS]; -static void InitTest(const char *TheName, void (*TheCall) (void), void (*Cleanup) (void), const char *TheDescr); -static void usage(void); +static void InitTest(const char *TheName, void (*TheCall) (void), + void (*Cleanup) (void), const char *TheDescr); +static void usage(void); -static void -InitTest(const char *TheName, void (*TheCall) (void), void (*Cleanup) (void), const char *TheDescr) +static void InitTest(const char *TheName, void (*TheCall) (void), + void (*Cleanup) (void), const char *TheDescr) { - if (Index >= MAXNUMOFTESTS) { - print_func("Uh-oh, too many tests added, increase MAXNUMOFTEST!\n"); - exit(-1); - } /* end if */ - HDstrcpy(Test[Index].Description, TheDescr); - HDstrcpy(Test[Index].Name, TheName); - Test[Index].Call = TheCall; - Test[Index].Cleanup = Cleanup; - Test[Index].NumErrors = -1; - Test[Index].SkipFlag = 0; - Index++; + if (Index >= MAXNUMOFTESTS) { + print_func("Uh-oh, too many tests added, increase MAXNUMOFTEST!\n"); + exit(-1); + } + + HDstrcpy(Test[Index].Description, TheDescr); + HDstrcpy(Test[Index].Name, TheName); + Test[Index].Call = TheCall; + Test[Index].Cleanup = Cleanup; + Test[Index].NumErrors = -1; + Test[Index].SkipFlag = 0; + Index++; } -static void -usage(void) +static void usage(void) { - intn i; - - print_func("Usage: testhdf5 [-v[erbose] (l[ow]|m[edium]|h[igh]|0-10)] \n"); - print_func(" [-[e]x[clude] name+] \n"); - print_func(" [-o[nly] name+] \n"); - print_func(" [-b[egin] name] \n"); - print_func(" [-s[ummary]] \n"); - print_func(" [-c[leanoff]] \n"); - print_func(" [-n[ocaching]] \n"); - print_func(" [-h[elp]] \n"); - print_func("\n\n"); - print_func("verbose controls the amount of information displayed\n"); - print_func("exclude to exclude tests by name\n"); - print_func("only to name tests which should be run\n"); - print_func("begin start at the name of the test givin\n"); - print_func("summary prints a summary of test results at the end\n"); - print_func("cleanoff does not delete *.hdf files after execution of tests\n"); - print_func("nocaching do not turn on low-level DD caching\n"); - print_func("help print out this information\n"); - print_func("\n\n"); - print_func("This program currently tests the following: \n\n"); - print_func("%16s %s\n", "Name", "Description"); - print_func("%16s %s\n", "----", "-----------"); - for (i = 0; i < Index; i++) - print_func("%16s %s\n", Test[i].Name, Test[i].Description); - print_func("\n\n"); -} /* end usage() */ + intn i; + + print_func("Usage: ttsafe [-v[erbose] (l[ow]|m[edium]|h[igh]|0-10)] \n"); + print_func(" [-[e]x[clude] name+] \n"); + print_func(" [-o[nly] name+] \n"); + print_func(" [-b[egin] name] \n"); + print_func(" [-s[ummary]] \n"); + print_func(" [-c[leanoff]] \n"); + print_func(" [-n[ocaching]] \n"); + print_func(" [-h[elp]] \n"); + print_func("\n\n"); + print_func("verbose controls the amount of information displayed\n"); + print_func("exclude to exclude tests by name\n"); + print_func("only to name tests which should be run\n"); + print_func("begin start at the name of the test givin\n"); + print_func("summary prints a summary of test results at the end\n"); + print_func("cleanoff does not delete *.hdf files after execution of tests\n"); + print_func("nocaching do not turn on low-level DD caching\n"); + print_func("help print out this information\n"); + print_func("\n\n"); + print_func("This program currently tests the following: \n\n"); + print_func("%16s %s\n", "Name", "Description"); + print_func("%16s %s\n", "----", "-----------"); + + for (i = 0; i < Index; i++) + print_func("%16s %s\n", Test[i].Name, Test[i].Description); + + print_func("\n\n"); +} /* * This routine is designed to provide equivalent functionality to 'printf' * and allow easy replacement for environments which don't have stdin/stdout - * available. (i.e. Windows & the Mac) + * available. (i.e. Windows & the Mac) */ int -print_func(const char *format,...) +print_func(const char *format, ...) { - va_list arglist; - int ret_value; + va_list arglist; + int ret_value; - va_start(arglist, format); - ret_value = vprintf(format, arglist); - va_end(arglist); - return (ret_value); + va_start(arglist, format); + ret_value = vprintf(format, arglist); + va_end(arglist); + return ret_value; } -char* gen_name(int value) { - char* temp; - int i, length; +char *gen_name(int value) +{ + char *temp; + int i, length; - length = num_digits(MAX_NUM_NAME-1); - temp = (char *)malloc((NAME_OFFSET+length+1)*sizeof(char)); - temp = strcpy(temp, "attrib"); - temp[NAME_OFFSET+length] = '\0'; + length = num_digits(MAX_NUM_NAME - 1); + temp = (char *)malloc((NAME_OFFSET + length + 1) * sizeof(char)); + temp = strcpy(temp, "attrib"); + temp[NAME_OFFSET + length] = '\0'; - for (i=length-1;i>=0;i--) { - temp[NAME_OFFSET+i] = (char)((int)'0' + value%10); - value = value/10; - } + for (i = length - 1; i >= 0; i--) { + temp[NAME_OFFSET + i] = (char)((int)'0' + value % 10); + value = value / 10; + } - return temp; + return temp; } /* pre-condition: num must be a non-negative number */ -int num_digits(int num) { - int i=0; - - if (num == 0) - return 1; - while (num > 0) { - num = num/10; - i++; - } - return i; +int num_digits(int num) +{ + int i; + + if (num == 0) + return 1; + + for (i = 0; num > 0; i++) + num = num / 10; + + return i; } -int -main(int argc, char *argv[]) +int main(int argc, char *argv[]) { - int CLLoop; /* Command Line Loop */ - int Loop, Loop1; - int Summary = 0; - int CleanUp = 1; - int Cache = 1; - uintn major, minor, release; + int CLLoop; /* Command Line Loop */ + int Loop, Loop1, Summary = 0, CleanUp = 1, Cache = 1; + uintn major, minor, release; #if defined __MWERKS__ - argc = ccommand(&argv); + argc = ccommand(&argv); #endif #if !(defined MAC || defined __MWERKS__ || defined SYMANTEC_C) - /* Un-buffer the stdout and stderr */ - setbuf(stderr, NULL); - setbuf(stdout, NULL); + /* Un-buffer the stdout and stderr */ + setbuf(stderr, NULL); + setbuf(stdout, NULL); #endif - /* - * Turn off automatic error reporting since we do it ourselves. Besides, - * half the functions this test calls are private, so automatic error - * reporting wouldn't do much good since it's triggered at the API layer. - */ - H5Eset_auto (NULL, NULL); - - /* Tests are generally arranged from least to most complexity... */ - InitTest("dcreate", tts_dcreate, cleanup_dcreate, "multi-dataset creation"); - InitTest("error", tts_error, cleanup_error, "per-thread error stacks"); - InitTest("cancel", tts_cancel, cleanup_cancel, "Thread cancellation safety test"); - InitTest("acreate", tts_acreate, cleanup_acreate, "multi-attribute creation"); - - Verbosity = 4; /* Default Verbosity is Low */ - H5get_libversion(&major, &minor, &release); - - print_func("\nFor help use: testhdf5 -help\n"); - print_func("Linked with hdf5 version %u.%u release %u\n", - (unsigned)major, (unsigned)minor, (unsigned)release); - for (CLLoop = 1; CLLoop < argc; CLLoop++) { - if ((argc > CLLoop + 1) && ((HDstrcmp(argv[CLLoop], "-verbose") == 0) || - (HDstrcmp(argv[CLLoop], "-v") == 0))) { - if (argv[CLLoop + 1][0] == 'l') - Verbosity = 4; - else if (argv[CLLoop + 1][0] == 'm') - Verbosity = 6; - else if (argv[CLLoop + 1][0] == 'h') - Verbosity = 10; - else - Verbosity = atoi(argv[CLLoop + 1]); - } /* end if */ - if ((argc > CLLoop) && ((HDstrcmp(argv[CLLoop], "-summary") == 0) || - (HDstrcmp(argv[CLLoop], "-s") == 0))) - Summary = 1; - - if ((argc > CLLoop) && ((HDstrcmp(argv[CLLoop], "-help") == 0) || - (HDstrcmp(argv[CLLoop], "-h") == 0))) { - usage(); - exit(0); - } - if ((argc > CLLoop) && ((HDstrcmp(argv[CLLoop], "-cleanoff") == 0) || - (HDstrcmp(argv[CLLoop], "-c") == 0))) - CleanUp = 0; - - if ((argc > CLLoop) && ((HDstrcmp(argv[CLLoop], "-nocache") == 0) || - (HDstrcmp(argv[CLLoop], "-n") == 0))) { - Cache = 0; - printf ("Cache = %d\n", Cache); - } - - if ((argc > CLLoop + 1) && ((HDstrcmp(argv[CLLoop], "-exclude") == 0) || - (HDstrcmp(argv[CLLoop], "-x") == 0))) { - Loop = CLLoop + 1; - while ((Loop < argc) && (argv[Loop][0] != '-')) { - for (Loop1 = 0; Loop1 < Index; Loop1++) - if (HDstrcmp(argv[Loop], Test[Loop1].Name) == 0) - Test[Loop1].SkipFlag = 1; - Loop++; - } /* end while */ - } /* end if */ - if ((argc > CLLoop + 1) && ((HDstrcmp(argv[CLLoop], "-begin") == 0) || - (HDstrcmp(argv[CLLoop], "-b") == 0))) { - Loop = CLLoop + 1; - while ((Loop < argc) && (argv[Loop][0] != '-')) { - for (Loop1 = 0; Loop1 < Index; Loop1++) { - if (HDstrcmp(argv[Loop], Test[Loop1].Name) != 0) - Test[Loop1].SkipFlag = 1; - if (HDstrcmp(argv[Loop], Test[Loop1].Name) == 0) - Loop1 = Index; - } /* end for */ - Loop++; - } /* end while */ - } /* end if */ - if ((argc > CLLoop + 1) && ((HDstrcmp(argv[CLLoop], "-only") == 0) || - (HDstrcmp(argv[CLLoop], "-o") == 0))) { - for (Loop = 0; Loop < Index; Loop++) - Test[Loop].SkipFlag = 1; - Loop = CLLoop + 1; - while ((Loop < argc) && (argv[Loop][0] != '-')) { - for (Loop1 = 0; Loop1 < Index; Loop1++) - if (HDstrcmp(argv[Loop], Test[Loop1].Name) == 0) - Test[Loop1].SkipFlag = 0; - Loop++; - } /* end while */ - } /* end if */ - } /* end for */ + /* + * Turn off automatic error reporting since we do it ourselves. + * Besides, half the functions this test calls are private, so + * automatic error reporting wouldn't do much good since it's + * triggered at the API layer. + */ + H5Eset_auto (NULL, NULL); + + /* Tests are generally arranged from least to most complexity... */ + InitTest("dcreate", tts_dcreate, cleanup_dcreate, + "multi-dataset creation"); + InitTest("error", tts_error, cleanup_error, + "per-thread error stacks"); + InitTest("cancel", tts_cancel, cleanup_cancel, + "thread cancellation safety test"); + InitTest("acreate", tts_acreate, cleanup_acreate, + "multi-attribute creation"); + + Verbosity = 4; /* Default Verbosity is Low */ + H5get_libversion(&major, &minor, &release); + + print_func("\nFor help use: ttsafe -help\n"); + print_func("Linked with hdf5 version %u.%u release %u\n", + (unsigned)major, (unsigned)minor, (unsigned)release); + + for (CLLoop = 1; CLLoop < argc; CLLoop++) { + if (argc > CLLoop + 1 && + (HDstrcmp(argv[CLLoop], "-verbose") == 0 || + HDstrcmp(argv[CLLoop], "-v") == 0)) { + if (argv[CLLoop + 1][0] == 'l') + Verbosity = 4; + else if (argv[CLLoop + 1][0] == 'm') + Verbosity = 6; + else if (argv[CLLoop + 1][0] == 'h') + Verbosity = 10; + else + Verbosity = atoi(argv[CLLoop + 1]); + } /* end if */ + + if (argc > CLLoop && + (HDstrcmp(argv[CLLoop], "-summary") == 0 || + HDstrcmp(argv[CLLoop], "-s") == 0)) + Summary = 1; + + if (argc > CLLoop && + (HDstrcmp(argv[CLLoop], "-help") == 0 || + HDstrcmp(argv[CLLoop], "-h") == 0)) { + usage(); + exit(0); + } + + if (argc > CLLoop && + (HDstrcmp(argv[CLLoop], "-cleanoff") == 0 || + HDstrcmp(argv[CLLoop], "-c") == 0)) + CleanUp = 0; + + if (argc > CLLoop && + (HDstrcmp(argv[CLLoop], "-nocache") == 0 || + HDstrcmp(argv[CLLoop], "-n") == 0)) { + Cache = 0; + print_func("Cache = %d\n", Cache); + } + + if (argc > CLLoop + 1 && + (HDstrcmp(argv[CLLoop], "-exclude") == 0 || + HDstrcmp(argv[CLLoop], "-x") == 0)) + for (Loop = CLLoop + 1; Loop < argc && argv[Loop][0] != '-'; Loop++) + for (Loop1 = 0; Loop1 < Index; Loop1++) + if (HDstrcmp(argv[Loop], Test[Loop1].Name) == 0) + Test[Loop1].SkipFlag = 1; + + if (argc > CLLoop + 1 && + (HDstrcmp(argv[CLLoop], "-begin") == 0 || + HDstrcmp(argv[CLLoop], "-b") == 0)) + for (Loop = CLLoop + 1; Loop < argc && argv[Loop][0] != '-'; Loop++) + for (Loop1 = 0; Loop1 < Index; Loop1++) { + if (HDstrcmp(argv[Loop], Test[Loop1].Name) != 0) + Test[Loop1].SkipFlag = 1; + + if (HDstrcmp(argv[Loop], Test[Loop1].Name) == 0) + Loop1 = Index; + } + + if (argc > CLLoop + 1 && + (HDstrcmp(argv[CLLoop], "-only") == 0 || + HDstrcmp(argv[CLLoop], "-o") == 0)) { + for (Loop = 0; Loop < Index; Loop++) + Test[Loop].SkipFlag = 1; + + for (Loop = CLLoop + 1; Loop < argc && argv[Loop][0] != '-'; Loop++) + for (Loop1 = 0; Loop1 < Index; Loop1++) + if (HDstrcmp(argv[Loop], Test[Loop1].Name) == 0) + Test[Loop1].SkipFlag = 0; + } + } /* end for */ #ifdef NOT_YET - if (Cache) /* turn on caching, unless we were instucted not to */ - Hcache(CACHE_ALL_FILES, TRUE); + if (Cache) + /* turn on caching, unless we were instucted not to */ + Hcache(CACHE_ALL_FILES, TRUE); #endif /* NOT_YET */ - for (Loop = 0; Loop < Index; Loop++) { - if (Test[Loop].SkipFlag) { - MESSAGE(2, ("Skipping -- %s \n", Test[Loop].Description)); - } else { - MESSAGE(2, ("Testing -- %s (%s) \n", Test[Loop].Description, - Test[Loop].Name)); - MESSAGE(5, ("===============================================\n")); - Test[Loop].NumErrors = num_errs; - (*Test[Loop].Call) (); - Test[Loop].NumErrors = num_errs - Test[Loop].NumErrors; - MESSAGE(5, ("===============================================\n")); - MESSAGE(5, ("There were %d errors detected.\n\n", (int) Test[Loop].NumErrors)); - } /* end else */ - } /* end for */ - - MESSAGE(2, ("\n\n")) - if (num_errs) - print_func("!!! %d Error(s) were detected !!!\n\n", (int) num_errs); - else - print_func("All tests were successful. \n\n"); - - if (Summary) { - print_func("Summary of Test Results:\n"); - print_func("Name of Test Errors Description of Test\n"); - print_func("---------------- ------ --------------------------------------\n"); - - for (Loop = 0; Loop < Index; Loop++) { - if (Test[Loop].NumErrors == -1) - print_func("%16s %6s %s\n", Test[Loop].Name, "N/A", Test[Loop].Description); - else - print_func("%16s %6d %s\n", Test[Loop].Name, (int) Test[Loop].NumErrors, - Test[Loop].Description); - } /* end for */ - print_func("\n\n"); - } /* end if */ - if (CleanUp && !getenv("HDF5_NOCLEANUP")) { - MESSAGE(2, ("\nCleaning Up temp files...\n\n")); - - /* call individual cleanup routines in each source module */ - for (Loop = 0; Loop < Index; Loop++) - if (!Test[Loop].SkipFlag && Test[Loop].Cleanup!=NULL) - (*Test[Loop].Cleanup) (); - } - return (num_errs); -} /* end main() */ + for (Loop = 0; Loop < Index; Loop++) + if (Test[Loop].SkipFlag) { + MESSAGE(2, ("Skipping -- %s \n", Test[Loop].Description)); + } else { + MESSAGE(2, ("Testing -- %s (%s) \n", Test[Loop].Description, + Test[Loop].Name)); + MESSAGE(5, ("===============================================\n")); + Test[Loop].NumErrors = num_errs; + Test[Loop].Call(); + Test[Loop].NumErrors = num_errs - Test[Loop].NumErrors; + MESSAGE(5, ("===============================================\n")); + MESSAGE(5, ("There were %d errors detected.\n\n", + (int)Test[Loop].NumErrors)); + } + + MESSAGE(2, ("\n\n")) + + if (num_errs) + print_func("!!! %d Error(s) were detected !!!\n\n", (int) num_errs); + else + print_func("All tests were successful. \n\n"); + + if (Summary) { + print_func("Summary of Test Results:\n"); + print_func("Name of Test Errors Description of Test\n"); + print_func("---------------- ------ --------------------------------------\n"); + + for (Loop = 0; Loop < Index; Loop++) { + if (Test[Loop].NumErrors == -1) + print_func("%16s %6s %s\n", Test[Loop].Name, + "N/A", Test[Loop].Description); + else + print_func("%16s %6d %s\n", Test[Loop].Name, + (int)Test[Loop].NumErrors, + Test[Loop].Description); + } + + print_func("\n\n"); + } + + if (CleanUp && !getenv("HDF5_NOCLEANUP")) { + MESSAGE(2, ("\nCleaning Up temp files...\n\n")); + + /* call individual cleanup routines in each source module */ + for (Loop = 0; Loop < Index; Loop++) + if (!Test[Loop].SkipFlag && Test[Loop].Cleanup!=NULL) + Test[Loop].Cleanup(); + } + + return num_errs; +} /* end main() */ #endif /*H5_HAVE_THREADSAFE*/ diff --git a/test/ttsafe_acreate.c b/test/ttsafe_acreate.c index 26d9aee..7aa8bde 100644 --- a/test/ttsafe_acreate.c +++ b/test/ttsafe_acreate.c @@ -21,7 +21,13 @@ * * Modification History * -------------------- - * May 15 2000 - incorporated into library tests (Chee Wai LEE) + * + * 15 May 2000, Chee Wai LEE + * Incorporated into library tests. + * + * 19 May 2000, Bill Wendling + * Changed so that it creates its own HDF5 file and removes it at cleanup + * time. Added num_errs flag. * ********************************************************************/ @@ -34,136 +40,136 @@ static int dummy; /* just to create a non-empty object file */ #include #include -#define FILE "ttsafe.h5" -#define DATASETNAME "IntData" -#define NUM_THREADS 16 +#define FILENAME "ttsafe_acreate.h5" +#define DATASETNAME "IntData" +#define NUM_THREADS 16 + +/* Global variables */ +extern int num_errs; +extern int Verbosity; void *tts_acreate_thread(void *); typedef struct acreate_data_struct { - hid_t dataset; - hid_t datatype; - hid_t dataspace; - int current_index; + hid_t dataset; + hid_t datatype; + hid_t dataspace; + int current_index; } ttsafe_name_data_t; -void tts_acreate(void) { - - /* Pthread definitions - */ - pthread_t threads[NUM_THREADS]; - - /* HDF5 data definitions - */ - hid_t file, dataset; - hid_t dataspace, datatype; - hid_t attribute; - hsize_t dimsf[1]; /* dataset dimensions */ - - int data; /* data to write */ - int buffer, ret; - - int i; - ttsafe_name_data_t *attrib_data; - - /* create a hdf5 file using H5F_ACC_TRUNC access, - * default file creation plist and default file - * access plist - */ - file = H5Fcreate(FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); - - /* create a simple dataspace for the dataset - */ - dimsf[0] = 1; - dataspace = H5Screate_simple(1,dimsf,NULL); - - /* define datatype for the data using native little endian integers - */ - datatype = H5Tcopy(H5T_NATIVE_INT); - H5Tset_order(datatype, H5T_ORDER_LE); - - /* create a new dataset within the file - */ - dataset = H5Dcreate(file, DATASETNAME, datatype, dataspace, - H5P_DEFAULT); - - /* initialize data for dataset and write value to dataset - */ - data = NUM_THREADS; - H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, - H5P_DEFAULT, &data); - - /* simultaneously create a large number of attributes to be - associated with the dataset - */ - - for (i=0;idataset = dataset; - attrib_data->datatype = datatype; - attrib_data->dataspace = dataspace; - attrib_data->current_index = i; - pthread_create(&threads[i],NULL,tts_acreate_thread,attrib_data); - } - - for (i=0;idataset = dataset; + attrib_data->datatype = datatype; + attrib_data->dataspace = dataspace; + attrib_data->current_index = i; + pthread_create(&threads[i], NULL, tts_acreate_thread, + attrib_data); + } + + for (i = 0; i < NUM_THREADS; i++) + pthread_join(threads[i], NULL); + + /* verify the correctness of the test */ + for (i = 0; i < NUM_THREADS; i++) { + attribute = H5Aopen_name(dataset,gen_name(i)); + + if (attribute < 0) { + fprintf(stderr, + "unable to open appropriate attribute. " + "Test failed!\n"); + num_errs++; + } else { + ret = H5Aread(attribute, H5T_NATIVE_INT, &buffer); + + if (ret < 0 || buffer != i) { + fprintf(stderr, + "wrong data values. Test failed!\n"); + num_errs++; + } + + H5Aclose(attribute); + } + } + + /* close remaining resources */ + H5Sclose(dataspace); + H5Tclose(datatype); + H5Dclose(dataset); + H5Fclose(file); } -void *tts_acreate_thread(void *client_data) { +void *tts_acreate_thread(void *client_data) +{ + hid_t attribute; + char *attribute_name; + int *attribute_data; /* data for attributes */ - hid_t attribute; - hsize_t dimsf[1]; /* dataset dimensions */ + ttsafe_name_data_t *attrib_data; - char *attribute_name; - int *attribute_data; /* data for attributes */ - int i; + attrib_data = (ttsafe_name_data_t *)client_data; - ttsafe_name_data_t *attrib_data = (ttsafe_name_data_t *)client_data; + /* Create attribute */ + attribute_name = gen_name(attrib_data->current_index); + attribute = H5Acreate(attrib_data->dataset, attribute_name, + attrib_data->datatype, attrib_data->dataspace, + H5P_DEFAULT); - /* create attribute - */ - attribute_name = gen_name(attrib_data->current_index); - attribute = H5Acreate(attrib_data->dataset, - attribute_name, - attrib_data->datatype, - attrib_data->dataspace, - H5P_DEFAULT); - - /* Write data to the attribute - */ - attribute_data = malloc(sizeof(int)); - *attribute_data = attrib_data->current_index; - H5Awrite(attribute,H5T_NATIVE_INT,attribute_data); - H5Aclose(attribute); - - return NULL; + /* Write data to the attribute */ + attribute_data = malloc(sizeof(int)); + *attribute_data = attrib_data->current_index; + H5Awrite(attribute, H5T_NATIVE_INT, attribute_data); + H5Aclose(attribute); + return NULL; } -void cleanup_acreate(void) { +void cleanup_acreate(void) +{ + HDunlink(FILENAME); } #endif /*H5_HAVE_THREADSAFE*/ - diff --git a/test/ttsafe_cancel.c b/test/ttsafe_cancel.c index 4e893e9..80981f5 100644 --- a/test/ttsafe_cancel.c +++ b/test/ttsafe_cancel.c @@ -12,7 +12,7 @@ * left the H5Diterate call. * * Temporary files generated: - * ttsafe.h5 + * ttsafe_cancel.h5 * * HDF5 APIs exercised in thread: * H5Screate_simple, H5Tcopy, H5Tset_order, H5Dcreate, H5Dclose, @@ -24,6 +24,10 @@ * Modification History * -------------------- * + * 19 May 2000, Bill Wendling + * Changed so that it creates its own HDF5 file and removes it at cleanup + * time. Added num_errs flag. + * ********************************************************************/ #include "ttsafe.h" @@ -31,8 +35,12 @@ static int dummy; /* just to create a non-empty object file */ #else -#define FILE "ttsafe.h5" -#define DATASETNAME "commonname" +#define FILENAME "ttsafe_cancel.h5" +#define DATASETNAME "commonname" + +/* Global variables */ +extern int num_errs; +extern int Verbosity; void *tts_cancel_thread(void *); void tts_cancel_barrier(void); @@ -41,163 +49,164 @@ void cancellation_cleanup(void *); hid_t cancel_file; typedef struct cleanup_struct { - hid_t dataset; - hid_t datatype; - hid_t dataspace; + hid_t dataset; + hid_t datatype; + hid_t dataspace; } cancel_cleanup_t; pthread_t childthread; pthread_mutex_t mutex; pthread_cond_t cond; -void tts_cancel(void) { - - pthread_attr_t attribute; - hid_t dataset; - - int buffer; - - /* make thread scheduling global */ - pthread_attr_init(&attribute); - pthread_attr_setscope(&attribute, PTHREAD_SCOPE_SYSTEM); - - /* create a hdf5 file using H5F_ACC_TRUNC access, - * default file creation plist and default file - * access plist - */ - cancel_file = H5Fcreate(FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); - - pthread_create(&childthread, &attribute, tts_cancel_thread, NULL); - - tts_cancel_barrier(); - pthread_cancel(childthread); - - dataset = H5Dopen(cancel_file, DATASETNAME); - H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, - &buffer); - - if (buffer == 11) { - /* do nothing */ - } else { - fprintf(stderr, - "operation unsuccessful with value at %d instead of 11\n", - buffer); - } - - H5Dclose(dataset); - H5Fclose(cancel_file); +void tts_cancel(void) +{ + pthread_attr_t attribute; + hid_t dataset; + int buffer; + + /* make thread scheduling global */ + pthread_attr_init(&attribute); + pthread_attr_setscope(&attribute, PTHREAD_SCOPE_SYSTEM); + + /* + * Create a hdf5 file using H5F_ACC_TRUNC access, default file + * creation plist and default file access plist + */ + cancel_file = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + pthread_create(&childthread, &attribute, tts_cancel_thread, NULL); + tts_cancel_barrier(); + pthread_cancel(childthread); + + dataset = H5Dopen(cancel_file, DATASETNAME); + H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, + &buffer); + + if (buffer != 11) { + fprintf(stderr, + "operation unsuccessful with value at %d instead of 11\n", + buffer); + num_errs++; + } + + H5Dclose(dataset); + H5Fclose(cancel_file); } -void *tts_cancel_thread(void *arg) { - - int datavalue; - int *buffer; - hid_t dataspace, datatype, dataset; - hsize_t dimsf[1]; /* dataset dimensions */ - - cancel_cleanup_t *cleanup_structure; - - /* define dataspace for dataset - */ - dimsf[0] = 1; - dataspace = H5Screate_simple(1,dimsf,NULL); - - /* define datatype for the data using native little endian integers - */ - datatype = H5Tcopy(H5T_NATIVE_INT); - H5Tset_order(datatype, H5T_ORDER_LE); - - /* create a new dataset within the file - */ - dataset = H5Dcreate(cancel_file, DATASETNAME, datatype, dataspace, - H5P_DEFAULT); - - /* If thread is cancelled, make cleanup call */ - cleanup_structure = (cancel_cleanup_t*)malloc(sizeof(cancel_cleanup_t)); - cleanup_structure->dataset = dataset; - cleanup_structure->datatype = datatype; - cleanup_structure->dataspace = dataspace; - pthread_cleanup_push(cancellation_cleanup, cleanup_structure); - - datavalue = 1; - H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, - &datavalue); - - buffer = malloc(sizeof(int)); - H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, - buffer); - H5Diterate(buffer, H5T_NATIVE_INT, dataspace, tts_cancel_callback, - &dataset); - - sleep(3); - - datavalue = 100; - H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, - &datavalue); - H5Dclose(dataset); - H5Tclose(datatype); - H5Sclose(dataspace); - - /* required by pthreads. the argument 0 pops the stack but does not - execute the cleanup routine. - */ - pthread_cleanup_pop(0); - - return (NULL); +void *tts_cancel_thread(void *arg) +{ + int datavalue; + int *buffer; + hid_t dataspace, datatype, dataset; + hsize_t dimsf[1]; /* dataset dimensions */ + cancel_cleanup_t *cleanup_structure; + + /* define dataspace for dataset */ + dimsf[0] = 1; + dataspace = H5Screate_simple(1,dimsf,NULL); + + /* define datatype for the data using native little endian integers */ + datatype = H5Tcopy(H5T_NATIVE_INT); + H5Tset_order(datatype, H5T_ORDER_LE); + + /* create a new dataset within the file */ + dataset = H5Dcreate(cancel_file, DATASETNAME, datatype, dataspace, + H5P_DEFAULT); + + /* If thread is cancelled, make cleanup call */ + cleanup_structure = (cancel_cleanup_t*)malloc(sizeof(cancel_cleanup_t)); + cleanup_structure->dataset = dataset; + cleanup_structure->datatype = datatype; + cleanup_structure->dataspace = dataspace; + pthread_cleanup_push(cancellation_cleanup, cleanup_structure); + + datavalue = 1; + H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, + &datavalue); + + buffer = malloc(sizeof(int)); + H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, + buffer); + H5Diterate(buffer, H5T_NATIVE_INT, dataspace, tts_cancel_callback, + &dataset); + + sleep(3); + + datavalue = 100; + H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, + &datavalue); + H5Dclose(dataset); + H5Tclose(datatype); + H5Sclose(dataspace); + + /* + * Required by pthreads. The argument 0 pops the stack but does not + * execute the cleanup routine. + */ + pthread_cleanup_pop(0); + return NULL; } herr_t tts_cancel_callback(void *elem, hid_t type_id, hsize_t ndim, - hssize_t *point, void *operator_data) { - int value = *(int *)elem; - hid_t dataset = *(hid_t *)operator_data; - - tts_cancel_barrier(); - sleep(3); - - if (value != 1) { - fprintf(stderr,"Error! Element value should be 1 and not %d\n", value); - return(-1); - } - - value += 10; - H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, - &value); - - return (0); + hssize_t *point, void *operator_data) +{ + int value = *(int *)elem; + hid_t dataset = *(hid_t *)operator_data; + + tts_cancel_barrier(); + sleep(3); + + if (value != 1) { + fprintf(stderr, "Error! Element value should be 1 and not %d\n", + value); + num_errs++; + return -1; + } + + value += 10; + H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, + &value); + return 0; } -/* need to perform the dataset, datatype and dataspace close that was - never performed because of thread cancellation -*/ -void cancellation_cleanup(void *arg) { - cancel_cleanup_t *cleanup_structure = (cancel_cleanup_t *)arg; - H5Dclose(cleanup_structure->dataset); - H5Tclose(cleanup_structure->datatype); - H5Sclose(cleanup_structure->dataspace); - /* retained for debugging */ - /* printf("cancellation noted, cleaning up ... \n"); */ +/* + * Need to perform the dataset, datatype and dataspace close that was never + * performed because of thread cancellation + */ +void cancellation_cleanup(void *arg) +{ + cancel_cleanup_t *cleanup_structure = (cancel_cleanup_t *)arg; + H5Dclose(cleanup_structure->dataset); + H5Tclose(cleanup_structure->datatype); + H5Sclose(cleanup_structure->dataspace); + + /* retained for debugging */ + /* print_func("cancellation noted, cleaning up ... \n"); */ } /* - artificial (and specific to this test) barrier to keep track of whether - both the main and child threads have reached a point in the program. -*/ -void tts_cancel_barrier() { - - static int count = 2; - - pthread_mutex_lock(&mutex); - if (count != 1) { - count--; - pthread_cond_wait(&cond, &mutex); - } else { - pthread_cond_signal(&cond); - } - pthread_mutex_unlock(&mutex); - + * Artificial (and specific to this test) barrier to keep track of whether + * both the main and child threads have reached a point in the program. + */ +void tts_cancel_barrier(void) +{ + static int count = 2; + + pthread_mutex_lock(&mutex); + + if (count != 1) { + count--; + pthread_cond_wait(&cond, &mutex); + } else { + pthread_cond_signal(&cond); + } + + pthread_mutex_unlock(&mutex); } -void cleanup_cancel() { - H5close(); +void cleanup_cancel(void) +{ + H5close(); + HDunlink(FILENAME); } + #endif /*H5_HAVE_THREADSAFE*/ diff --git a/test/ttsafe_dcreate.c b/test/ttsafe_dcreate.c index cc7d6e6..aa77e36 100644 --- a/test/ttsafe_dcreate.c +++ b/test/ttsafe_dcreate.c @@ -8,7 +8,7 @@ * threadsafe environment. * * Temporary files generated: - * ttsafe.h5 + * ttsafe_dcreate.h5 * * HDF5 APIs exercised in thread: * H5Screate_simple, H5Tcopy, H5Tset_order, H5Dcreate, H5Dwrite, H5Dclose, @@ -20,6 +20,10 @@ * Modification History * -------------------- * + * 19 May 2000, Bill Wendling + * Changed so that it creates its own HDF5 file and removes it at cleanup + * time. Added num_errs flag. + * ********************************************************************/ #include "ttsafe.h" @@ -27,165 +31,157 @@ static int dummy; /* just to create a non-empty object file */ #else -#define FILE "ttsafe.h5" -#define DATASETNAME_LENGTH 10 -#define NUM_THREAD 16 +#define FILENAME "ttsafe_dcreate.h5" +#define DATASETNAME_LENGTH 10 +#define NUM_THREAD 16 + +/* Global variables */ +extern int num_errs; +extern int Verbosity; void *tts_dcreate_creator(void *); +typedef struct thread_info { + int id; + hid_t file; + const char *dsetname; +} thread_info; + /* ********************************************************************** * Thread safe test - multiple dataset creation ********************************************************************** */ -void tts_dcreate(void) { - - /* Pthread definitions - */ - pthread_t threads[NUM_THREAD]; - - /* HDF5 data definitions - */ - hid_t file, dataset, datatype; - - int datavalue; - int i; - - typedef struct thread_info { - int id; - hid_t file; - char *dsetname; - } thread_info; - - thread_info *thread_out; - - char *dsetname[NUM_THREAD]; - pthread_attr_t attribute; - - /* set pthread attribute to perform global scheduling */ - pthread_attr_init(&attribute); - pthread_attr_setscope(&attribute, PTHREAD_SCOPE_SYSTEM); - - /* set individual dataset names (rather than generated the names - automatically) - */ - - for (i=0;iid = i; - thread_out->file = file; - thread_out->dsetname = dsetname[i]; - pthread_create(&threads[i],NULL,tts_dcreate_creator,thread_out); - } - - for (i=0;iid = i; + thread_out->file = file; + thread_out->dsetname = dsetname[i]; + pthread_create(&threads[i], NULL, tts_dcreate_creator, thread_out); + } + + for (i = 0;i < NUM_THREAD; i++) + pthread_join(threads[i], NULL); + + /* compare data to see if it is written correctly */ + + /* define datatype for the data using native little endian integers */ + datatype = H5Tcopy(H5T_NATIVE_INT); + + for (i = 0; i < NUM_THREAD; i++) { + if ((dataset = H5Dopen(file,dsetname[i])) < 0) { + fprintf(stderr, "Dataset name not found - test failed\n"); + H5Fclose(file); + num_errs++; + return; + } else { + H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, &datavalue); + + if (datavalue != i) { + fprintf(stderr, + "Wrong value read %d for dataset name %s - test failed\n", + datavalue, dsetname[i]); + H5Dclose(dataset); + H5Fclose(file); + num_errs++; + return; + } + + H5Dclose(dataset); + } + } + + /* close remaining resources */ H5Fclose(file); - return; - } - H5Dclose(dataset); - } - } - /* close remaining resources - */ - H5Fclose(file); - } -void *tts_dcreate_creator(void *thread_data) { - - hid_t dataspace, datatype, dataset; - hsize_t dimsf[1]; /* dataset dimensions */ - - struct thread_info { - int id; - hid_t file; - char *dsetname; - } thread_in; - - thread_in.dsetname = (char *)malloc(sizeof(char)*DATASETNAME_LENGTH); - thread_in = *((struct thread_info *)thread_data); - - /* define dataspace for dataset - */ - dimsf[0] = 1; - dataspace = H5Screate_simple(1,dimsf,NULL); - - /* define datatype for the data using native little endian integers - */ - datatype = H5Tcopy(H5T_NATIVE_INT); - H5Tset_order(datatype, H5T_ORDER_LE); - - /* create a new dataset within the file - */ - dataset = H5Dcreate(thread_in.file, thread_in.dsetname, - datatype, dataspace, - H5P_DEFAULT); - - /* initialize data for dataset and write value to dataset - */ - H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, - H5P_DEFAULT, &thread_in.id); - - /* close dataset, datatype and dataspace resources - */ - H5Dclose(dataset); - H5Tclose(datatype); - H5Sclose(dataspace); - - return NULL; +void *tts_dcreate_creator(void *thread_data) +{ + hid_t dataspace, datatype, dataset; + hsize_t dimsf[1]; /* dataset dimensions */ + struct thread_info { + int id; + hid_t file; + char *dsetname; + } thread_in; + + thread_in.dsetname = malloc(sizeof(char) * DATASETNAME_LENGTH); + thread_in = *((struct thread_info *)thread_data); + + /* define dataspace for dataset */ + dimsf[0] = 1; + dataspace = H5Screate_simple(1,dimsf,NULL); + + /* define datatype for the data using native little endian integers */ + datatype = H5Tcopy(H5T_NATIVE_INT); + H5Tset_order(datatype, H5T_ORDER_LE); + + /* create a new dataset within the file */ + dataset = H5Dcreate(thread_in.file, thread_in.dsetname, + datatype, dataspace, H5P_DEFAULT); + + /* initialize data for dataset and write value to dataset */ + H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, + H5P_DEFAULT, &thread_in.id); + + /* close dataset, datatype and dataspace resources */ + H5Dclose(dataset); + H5Tclose(datatype); + H5Sclose(dataspace); + return NULL; } -void cleanup_dcreate(void) { - H5close(); +void cleanup_dcreate(void) +{ + H5close(); + HDunlink(FILENAME); } #endif /*H5_HAVE_THREADSAFE*/ diff --git a/test/ttsafe_error.c b/test/ttsafe_error.c index 1dafd23..b9b8b0b 100644 --- a/test/ttsafe_error.c +++ b/test/ttsafe_error.c @@ -9,7 +9,7 @@ * entry. * * Temporary files generated: - * ttsafe.h5 + * ttsafe_error.h5 * * HDF5 APIs exercised in thread: * H5Screate_simple, H5Tcopy, H5Tset_order, H5Dcreate, H5Dclose, @@ -21,6 +21,11 @@ * Modification History * -------------------- * + * 19 May 2000, Bill Wendling + * Modified so that it creates a unique HDF5 file and removes it on + * cleanup. Also added the num_errs flag and increment it when necessary + * to report the errors. + * ********************************************************************/ #include "ttsafe.h" @@ -28,12 +33,17 @@ static int dummy; /* just to create a non-empty object file */ #else -#define NUM_THREAD 16 -#define FILE "ttsafe.h5" +#define NUM_THREAD 16 +#define FILENAME "ttsafe_error.h5" + /* Having a common dataset name is an error */ -#define DATASETNAME "commonname" -#define EXPECTED_ERROR_DEPTH 3 -#define WRITE_NUMBER 37 +#define DATASETNAME "commonname" +#define EXPECTED_ERROR_DEPTH 3 +#define WRITE_NUMBER 37 + +/* Global variables */ +extern int num_errs; +extern int Verbosity; herr_t error_callback(void *); herr_t walk_error_callback(int, H5E_error_t *, void *); @@ -41,139 +51,139 @@ void *tts_error_thread(void *); hid_t error_file; typedef struct err_num_struct { - int maj_num; - int min_num; + int maj_num; + int min_num; } err_num_t; -err_num_t expected[] = {{15, 23}, {15, 23}, {10, 32}}; +err_num_t expected[] = { + {15, 23}, + {15, 23}, + {10, 32} +}; + int error_flag = 0; int error_count = 0; - pthread_mutex_t error_mutex; -void tts_error(void) { - - int i; - - pthread_t threads[NUM_THREAD]; - pthread_attr_t attribute; - - hid_t dataset; - int value; - - H5E_auto_t old_error_cb; - void *old_error_client_data; - - /* set up mutex for global count of errors */ - pthread_mutex_init(&error_mutex, NULL); - - /* preserve previous error stack handler */ - H5Eget_auto(&old_error_cb, &old_error_client_data); - - /* set our own auto error stack handler */ - H5Eset_auto(error_callback, NULL); - - /* make thread scheduling global */ - pthread_attr_init(&attribute); - pthread_attr_setscope(&attribute, PTHREAD_SCOPE_SYSTEM); - - /* create a hdf5 file using H5F_ACC_TRUNC access, - * default file creation plist and default file - * access plist - */ - error_file = H5Fcreate(FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); - - for (i=0;i= 0) { /* not an error */ - value = WRITE_NUMBER; - H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &value); - - H5Dclose(dataset); - } - H5Tclose(datatype); - H5Sclose(dataspace); - return (NULL); +void *tts_error_thread(void *arg) +{ + hid_t dataspace, datatype, dataset; + hsize_t dimsf[1]; /* dataset dimensions */ + int value; + + /* define dataspace for dataset */ + dimsf[0] = 1; + dataspace = H5Screate_simple(1,dimsf,NULL); + + /* define datatype for the data using native little endian integers */ + datatype = H5Tcopy(H5T_NATIVE_INT); + H5Tset_order(datatype, H5T_ORDER_LE); + + /* create a new dataset within the file */ + dataset = H5Dcreate(error_file, DATASETNAME, datatype, dataspace, + H5P_DEFAULT); + if (dataset >= 0) { /* not an error */ + value = WRITE_NUMBER; + H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, + H5P_DEFAULT, &value); + H5Dclose(dataset); + } + + H5Tclose(datatype); + H5Sclose(dataspace); + return (NULL); } -void cleanup_error() { +herr_t error_callback(void *client_data) +{ + pthread_mutex_lock(&error_mutex); + error_count++; + pthread_mutex_unlock(&error_mutex); + return H5Ewalk(H5E_WALK_DOWNWARD, walk_error_callback, NULL); } -herr_t error_callback(void *client_data) { - pthread_mutex_lock(&error_mutex); - error_count++; - pthread_mutex_unlock(&error_mutex); - return (H5Ewalk(H5E_WALK_DOWNWARD, walk_error_callback, NULL)); -} +herr_t walk_error_callback(int n, H5E_error_t *err_desc, void *client_data) +{ + int maj_num, min_num; + + if (err_desc) { + maj_num = err_desc->maj_num; + min_num = err_desc->min_num; -herr_t walk_error_callback(int n, H5E_error_t *err_desc, - void *client_data) { - int maj_num, min_num; - - if (err_desc) { - maj_num = err_desc->maj_num; - min_num = err_desc->min_num; - - if (n < EXPECTED_ERROR_DEPTH) { - if (maj_num == expected[n].maj_num && - min_num == expected[n].min_num) { + if (n < EXPECTED_ERROR_DEPTH && maj_num == expected[n].maj_num && + min_num == expected[n].min_num) + return SUCCEED; + } + + error_flag = -1; return SUCCEED; - } - } - } - error_flag = -1; - return SUCCEED; +} + +void cleanup_error(void) +{ + HDunlink(FILENAME); } #endif /*H5_HAVE_THREADSAFE*/ -- cgit v0.12