From 8ffd55478e11904f193b4a98477b3bcb452b93ac Mon Sep 17 00:00:00 2001 From: Raymond Lu Date: Fri, 22 Mar 2013 16:39:53 -0500 Subject: [svn-r23432] I added a new macro HDF5_PLUGIN_PRELOAD to skip plugin loading during data reading. Tested on koala and jam. --- MANIFEST | 1 + src/H5PL.c | 98 +++++++++++++++++++++++++++---------------- src/H5PLprivate.h | 3 +- src/H5Z.c | 14 +++++-- src/H5Zpublic.h | 3 -- test/plugin.c | 7 ++++ test/testerror.sh.in | 9 +++- tools/h5dump/testh5dump.sh.in | 5 ++- 8 files changed, 94 insertions(+), 46 deletions(-) diff --git a/MANIFEST b/MANIFEST index 17de021..ca718f5 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1097,6 +1097,7 @@ ./test/plugin_lib/dynlib1.c ./test/plugin_lib/Makefile.in +./test/plugin_lib/CMakeLists.txt ./test/testfiles/err_compat_1 ./test/testfiles/err_compat_2 diff --git a/src/H5PL.c b/src/H5PL.c index 54d3407..85ca97d 100644 --- a/src/H5PL.c +++ b/src/H5PL.c @@ -43,8 +43,10 @@ /****************************/ /* Windows support */ #ifdef H5_HAVE_WIN32_API + #define H5PL_DEFAULT_PATH ".;/ProgramData;/Users/Public" #define H5PL_PATH_SEPARATOR ";" + /* Handle for dynamic library */ #define H5PL_HANDLE HINSTANCE @@ -60,25 +62,14 @@ /* Clear error - nothing to do */ #define H5PL_CLR_ERROR -#define H5PL_GET_PLUGIN_TYPE(H, ret_val) { \ -typedef const int (__cdecl *get_plugin_type_t)(); \ -get_plugin_type_t get_plugin_type; \ -get_plugin_type = (get_plugin_type_t)H5PL_GET_LIB_FUNC(H, "H5PL_get_plugin_type"); \ -ret_val = get_plugin_type(); \ -} - -#define H5PL_GET_PLUGIN_INFO(H, ret_val) { \ -typedef const H5Z_class2_t *(__cdecl *get_filter_info_t)(); \ -get_filter_info_t get_filter_info; \ -get_filter_info = (get_filter_info_t)H5PL_GET_LIB_FUNC(H, "H5PL_get_plugin_info"); \ -ret_val = get_filter_info(); \ -} - typedef const H5Z_class2_t *(__cdecl *get_filter_info_t)(); +/* Unix support */ #else /* H5_HAVE_WIN32_API */ + #define H5PL_DEFAULT_PATH "/usr:/usr/lib:/usr/local" #define H5PL_PATH_SEPARATOR ":" + /* Handle for dynamic library */ #define H5PL_HANDLE void * @@ -94,23 +85,11 @@ typedef const H5Z_class2_t *(__cdecl *get_filter_info_t)(); /* Clear error */ #define H5PL_CLR_ERROR dlerror() -#define H5PL_GET_PLUGIN_TYPE(H, ret_val) { \ -typedef const int (*get_plugin_type_t)(); \ -get_plugin_type_t get_plugin_type; \ -get_plugin_type = (get_plugin_type_t)H5PL_GET_LIBRARY_FUNCTION(H, "H5PL_get_plugin_type"); \ -ret_val = (*get_plugin_type)(); \ -} - -#define H5PL_GET_PLUGIN_INFO(H, ret_val) { \ -typedef const H5Z_class2_t *(*get_filter_info_t)(); \ -get_filter_info_t get_filter_info; \ -*(void**)(&get_filter_info) = (get_filter_info_t)H5PL_GET_LIB_FUNC(H, "H5PL_get_plugin_info"); \ -ret_val = get_filter_info(); \ -} - typedef const H5Z_class2_t *(*get_filter_info_t)(); #endif /* H5_HAVE_WIN32_API */ +/* Special symbol to indicate no plugin loading */ +#define H5PL_NO_PLUGIN "::" /******************/ /* Local Typedefs */ @@ -159,6 +138,10 @@ static char *H5PL_path_table_g[H5PL_MAX_PATH_NUM]; static size_t H5PL_num_paths_g = 0; static htri_t H5PL_path_found_g = FALSE; +/* Table of preload pathnames for plugin libraries */ +static char *H5PL_preload_table_g[H5PL_MAX_PATH_NUM]; +static size_t H5PL_num_preload_g = 0; +static hbool_t H5PL_no_plugin_g = FALSE; /*-------------------------------------------------------------------------- @@ -175,13 +158,56 @@ DESCRIPTION static herr_t H5PL__init_interface(void) { - FUNC_ENTER_STATIC_NOERR + char *preload_path = NULL; + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_LEAVE_NOAPI(SUCCEED) + FUNC_ENTER_STATIC + + /* Retrieve pathnames from HDF5_PLUGIN_PRELOAD if the user sets it + * to tell the library to load plugin libraries without search. + */ + if(!(preload_path = HDgetenv("HDF5_PLUGIN_PRELOAD"))) + HGOTO_DONE(ret_value) + + /* Special symbal "::" means no plugin during data reading. */ + if(!HDstrcmp(preload_path, H5PL_NO_PLUGIN)) { + H5PL_no_plugin_g = TRUE; + HGOTO_DONE(ret_value) + } + +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5PL__init_interface() */ /*------------------------------------------------------------------------- + * Function: H5PL_no_plugin + * + * Purpose: Quick way for filter module to query whether to load plugin + * + * Return: TRUE: No plugin loading during data reading + * + * FALSE: Load plugin during data reading + * + * Programmer: Raymond Lu + * 20 February 2013 + * + *------------------------------------------------------------------------- + */ +hbool_t H5PL_no_plugin(void) +{ + hbool_t ret_value = FALSE; + + FUNC_ENTER_NOAPI(ret_value) + + ret_value = H5PL_no_plugin_g; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} + + +/*------------------------------------------------------------------------- * Function: H5PL_term_interface * * Purpose: Terminate the H5PL interface: release all memory, reset all @@ -496,7 +522,7 @@ static htri_t H5PL__open(H5PL_type_t pl_type, char *libname, int pl_id, void **pl_info) { H5PL_HANDLE handle = NULL; - get_filter_info_t H5PL_get_plugin_info = NULL; + get_filter_info_t get_plugin_info = NULL; htri_t ret_value = FALSE; FUNC_ENTER_STATIC @@ -511,7 +537,7 @@ H5PL__open(H5PL_type_t pl_type, char *libname, int pl_id, void **pl_info) /* Return a handle for the function H5PL_get_plugin_info in the dynamic library. * The plugin library is suppose to define this function. */ - if(NULL == (H5PL_get_plugin_info = (get_filter_info_t)H5PL_GET_LIB_FUNC(handle, "H5PL_get_plugin_info"))) { + if(NULL == (get_plugin_info = (get_filter_info_t)H5PL_GET_LIB_FUNC(handle, "H5PL_get_plugin_info"))) { if(H5PL__close(handle) < 0) HGOTO_ERROR(H5E_PLUGIN, H5E_CLOSEERROR, FAIL, "can't close dynamic library") } /* end if */ @@ -521,7 +547,7 @@ H5PL__open(H5PL_type_t pl_type, char *libname, int pl_id, void **pl_info) /* Invoke H5PL_get_plugin_info to verify this is the right library we are looking for. * Move on if it isn't. */ - if(NULL == (plugin_info = (*H5PL_get_plugin_info)())) { + if(NULL == (plugin_info = (*get_plugin_info)())) { if(H5PL__close(handle) < 0) HGOTO_ERROR(H5E_PLUGIN, H5E_CLOSEERROR, FAIL, "can't close dynamic library") HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "can't get plugin info") @@ -583,7 +609,7 @@ H5PL__search_table(H5PL_type_t plugin_type, int type_id, void **info) { size_t i; H5Z_class2_t *plugin_info; - get_filter_info_t H5PL_get_plugin_info = NULL; + get_filter_info_t get_plugin_info = NULL; htri_t ret_value = FALSE; FUNC_ENTER_STATIC @@ -592,10 +618,10 @@ H5PL__search_table(H5PL_type_t plugin_type, int type_id, void **info) if(H5PL_table_used_g > 0) { for(i = 0; i < H5PL_table_used_g; i++) { if((plugin_type == (H5PL_table_g[i]).pl_type) && (type_id == (H5PL_table_g[i]).pl_id)) { - if(NULL == (H5PL_get_plugin_info = (get_filter_info_t)H5PL_GET_LIB_FUNC((H5PL_table_g[i]).handle, "H5PL_get_plugin_info"))) + if(NULL == (get_plugin_info = (get_filter_info_t)H5PL_GET_LIB_FUNC((H5PL_table_g[i]).handle, "H5PL_get_plugin_info"))) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get function for H5PL_get_plugin_info") - if(NULL == (plugin_info = (*H5PL_get_plugin_info)())) + if(NULL == (plugin_info = (*get_plugin_info)())) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get plugin info") *info = (void *)plugin_info; diff --git a/src/H5PLprivate.h b/src/H5PLprivate.h index 25fbc51..127ba98 100644 --- a/src/H5PLprivate.h +++ b/src/H5PLprivate.h @@ -47,6 +47,7 @@ /***************************************/ /* Internal API routines */ -H5_DLL void *H5PL_load(H5PL_type_t plugin_type, int type_id); +H5_DLL void *H5PL_load(H5PL_type_t plugin_type, int type_id); +H5_DLL hbool_t H5PL_no_plugin(void); #endif /* _H5PLprivate_H */ diff --git a/src/H5Z.c b/src/H5Z.c index bfd0045..f838328 100644 --- a/src/H5Z.c +++ b/src/H5Z.c @@ -1115,8 +1115,9 @@ H5Z_pipeline(const H5O_pline_t *pline, unsigned flags, continue;/*filter excluded*/ } - /* If the filter isn't registered, try to load it dynamically and register it. Otherwise, return failure */ - if((fclass_idx = H5Z_find_idx(pline->filter[idx].id)) < 0) { + /* If the filter isn't registered and the application doesn't indicate no plugin through HDF5_PRELOAD_PLUG (using the symbol "::"), + * try to load it dynamically and register it. Otherwise, return failure */ + if((fclass_idx = H5Z_find_idx(pline->filter[idx].id)) < 0 && !H5PL_no_plugin()) { H5Z_class2_t *filter_info; if(NULL != (filter_info = (H5Z_class2_t *)H5PL_load(H5PL_TYPE_FILTER, (int)(pline->filter[idx].id)))) { @@ -1141,7 +1142,14 @@ H5Z_pipeline(const H5O_pline_t *pline, unsigned flags, else HGOTO_ERROR(H5E_PLINE, H5E_READERROR, FAIL, "required filter (name unavailable) is not registered") } /* end if */ - } /* end if */ + } else if((fclass_idx = H5Z_find_idx(pline->filter[idx].id)) < 0 && H5PL_no_plugin()) { + /* Print out the filter name to give more info. But the name is optional for + * the filter */ + if(pline->filter[idx].name) + HGOTO_ERROR(H5E_PLINE, H5E_READERROR, FAIL, "required filter '%s' is not registered", pline->filter[idx].name) + else + HGOTO_ERROR(H5E_PLINE, H5E_READERROR, FAIL, "required filter (name unavailable) is not registered") + } fclass=&H5Z_table_g[fclass_idx]; #ifdef H5Z_DEBUG diff --git a/src/H5Zpublic.h b/src/H5Zpublic.h index 24496e4..c7c3562 100644 --- a/src/H5Zpublic.h +++ b/src/H5Zpublic.h @@ -47,9 +47,6 @@ typedef int H5Z_filter_t; #define H5Z_FILTER_DYNLIB1 257 #define H5Z_FILTER_DYNLIB2 258 -/* Registered third-party filters */ -#define H5Z_FILTER_BZIP2 307 - #define H5Z_FILTER_MAX 65535 /*maximum filter id */ /* General macros */ diff --git a/test/plugin.c b/test/plugin.c index 3cadb3c..d5a30f9 100644 --- a/test/plugin.c +++ b/test/plugin.c @@ -31,6 +31,13 @@ #define H5Z_PACKAGE #include "H5Zpkg.h" +/* Filters for HDF5 internal test */ +#define H5Z_FILTER_DYNLIB1 257 +#define H5Z_FILTER_DYNLIB2 258 + +/* Bzip2 filter */ +#define H5Z_FILTER_BZIP2 307 + const char *FILENAME[] = { "plugin", NULL diff --git a/test/testerror.sh.in b/test/testerror.sh.in index b68fa7e..eb01fb1 100644 --- a/test/testerror.sh.in +++ b/test/testerror.sh.in @@ -23,6 +23,9 @@ DEPRECATED_SYMBOLS="@DEPRECATED_SYMBOLS@" CMP='cmp -s' DIFF='diff -c' +# Skip plugin module to test missing filter +ENVCMD="env HDF5_PLUGIN_PRELOAD=::" + nerrors=0 verbose=yes @@ -61,7 +64,9 @@ TEST() { echo "#############################" echo "Expected output for $TEST_ERR" echo "#############################" - $RUNSERIAL $TEST_ERR_BIN + + # Skip the plugin for testing missing filter. + $ENVCMD $RUNSERIAL $TEST_ERR_BIN ) >$actual 2>$actual_err # Extract file name, line number, version and thread IDs because they may be different sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ @@ -109,7 +114,7 @@ else TEST err_compat fi -# test for error_test +# test for error_test. Skip the plugin for testing missing filter. TEST error_test if test $nerrors -eq 0 ; then diff --git a/tools/h5dump/testh5dump.sh.in b/tools/h5dump/testh5dump.sh.in index 238eee9..cdd292a 100644 --- a/tools/h5dump/testh5dump.sh.in +++ b/tools/h5dump/testh5dump.sh.in @@ -38,6 +38,9 @@ DIRNAME='dirname' LS='ls' AWK='awk' +# Skip plugin module to test missing filter +ENVCMD="env HDF5_PLUGIN_PRELOAD=::" + nerrors=0 verbose=yes @@ -675,7 +678,7 @@ TOOLTEST4() { TESTING $DUMPER $@ ( cd $TESTDIR - $RUNSERIAL $DUMPER_BIN "$@" + $ENVCMD $RUNSERIAL $DUMPER_BIN "$@" ) >$actual 2>$actual_err # save actual and actual_err in case they are needed later. -- cgit v0.12