diff options
author | Mohamad Chaarawi <chaarawi@hdfgroup.org> | 2013-05-10 19:38:53 (GMT) |
---|---|---|
committer | Mohamad Chaarawi <chaarawi@hdfgroup.org> | 2013-05-10 19:38:53 (GMT) |
commit | 68a20c3f56f30e62e062eba2f4c8f782fa604cd3 (patch) | |
tree | db86db14954362b093891cf311ce514cf87fe051 /src | |
parent | 0a3191e36d4ee22c383de9b0917990149c1f2df2 (diff) | |
parent | 5ecebe5b9bc161153a3391bf32eb64687f675172 (diff) | |
download | hdf5-68a20c3f56f30e62e062eba2f4c8f782fa604cd3.zip hdf5-68a20c3f56f30e62e062eba2f4c8f782fa604cd3.tar.gz hdf5-68a20c3f56f30e62e062eba2f4c8f782fa604cd3.tar.bz2 |
[svn-r23694] merge from trunk
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 15 | ||||
-rw-r--r-- | src/H5.c | 1 | ||||
-rw-r--r-- | src/H5AC.c | 31 | ||||
-rw-r--r-- | src/H5ACprivate.h | 5 | ||||
-rw-r--r-- | src/H5C.c | 37 | ||||
-rw-r--r-- | src/H5D.c | 2 | ||||
-rw-r--r-- | src/H5Dchunk.c | 8 | ||||
-rw-r--r-- | src/H5Dint.c | 30 | ||||
-rw-r--r-- | src/H5Dprivate.h | 2 | ||||
-rw-r--r-- | src/H5Edefin.h | 4 | ||||
-rw-r--r-- | src/H5Einit.h | 12 | ||||
-rw-r--r-- | src/H5Epubgen.h | 6 | ||||
-rw-r--r-- | src/H5Eterm.h | 4 | ||||
-rw-r--r-- | src/H5FDmulti.c | 28 | ||||
-rw-r--r-- | src/H5Gint.c | 31 | ||||
-rw-r--r-- | src/H5Gprivate.h | 1 | ||||
-rw-r--r-- | src/H5PL.c | 661 | ||||
-rw-r--r-- | src/H5PLextern.h | 84 | ||||
-rw-r--r-- | src/H5PLprivate.h | 53 | ||||
-rw-r--r-- | src/H5Pocpl.c | 115 | ||||
-rw-r--r-- | src/H5Pprivate.h | 1 | ||||
-rw-r--r-- | src/H5Z.c | 289 | ||||
-rw-r--r-- | src/H5Zprivate.h | 2 | ||||
-rw-r--r-- | src/H5Zpublic.h | 1 | ||||
-rw-r--r-- | src/H5config.h.in | 6 | ||||
-rw-r--r-- | src/H5err.txt | 5 | ||||
-rw-r--r-- | src/H5private.h | 12 | ||||
-rw-r--r-- | src/H5public.h | 4 | ||||
-rw-r--r-- | src/Makefile.am | 5 | ||||
-rw-r--r-- | src/Makefile.in | 32 |
30 files changed, 1344 insertions, 143 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3048484..d04197e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -478,6 +478,15 @@ SET (H5P_HDRS ) IDE_GENERATED_PROPERTIES ("H5P" "${H5P_HDRS}" "${H5P_SRCS}" ) +SET (H5PL_SRCS + ${HDF5_SRC_DIR}/H5PL.c +) + +SET (H5PL_HDRS + ${HDF5_SRC_DIR}/H5PLextern.h +) +IDE_GENERATED_PROPERTIES ("H5PL" "${H5PL_HDRS}" "${H5PL_SRCS}" ) + SET (H5R_SRCS ${HDF5_SRC_DIR}/H5R.c @@ -674,6 +683,7 @@ SET (common_SRCS ${H5MP_SRCS} ${H5O_SRCS} ${H5P_SRCS} + ${H5PL_SRCS} ${H5R_SRCS} ${H5RC_SRCS} ${H5RS_SRCS} @@ -714,6 +724,7 @@ SET (H5_PUBLIC_HEADERS ${H5MP_HDRS} ${H5O_HDRS} ${H5P_HDRS} + ${H5PL_HDRS} ${H5R_HDRS} ${H5S_HDRS} ${H5SM_HDRS} @@ -753,6 +764,7 @@ SET (H5_PRIVATE_HEADERS ${HDF5_SRC_DIR}/H5MPprivate.h ${HDF5_SRC_DIR}/H5Oprivate.h ${HDF5_SRC_DIR}/H5Pprivate.h + ${HDF5_SRC_DIR}/H5PLprivate.h ${HDF5_SRC_DIR}/H5RCprivate.h ${HDF5_SRC_DIR}/H5Rprivate.h ${HDF5_SRC_DIR}/H5RSprivate.h @@ -840,6 +852,9 @@ SET_SOURCE_FILES_PROPERTIES (${HDF5_BINARY_DIR}/H5overflow.h GENERATED) ADD_LIBRARY (${HDF5_LIB_TARGET} ${LIB_TYPE} ${common_SRCS} ${H5_PUBLIC_HEADERS} ${H5_PRIVATE_HEADERS}) TARGET_LINK_LIBRARIES (${HDF5_LIB_TARGET} ${LINK_LIBS}) +IF (NOT WIN32) + TARGET_LINK_LIBRARIES (${HDF5_LIB_TARGET} dl) +ENDIF (NOT WIN32) SET_GLOBAL_VARIABLE (HDF5_LIBRARIES_TO_EXPORT ${HDF5_LIB_TARGET}) H5_SET_LIB_OPTIONS (${HDF5_LIB_TARGET} ${HDF5_LIB_NAME} ${LIB_TYPE}) SET_TARGET_PROPERTIES (${HDF5_LIB_TARGET} PROPERTIES FOLDER libraries) @@ -273,6 +273,7 @@ H5_term_library(void) pending += DOWN(Z); pending += DOWN(FD); pending += DOWN(P); + pending += DOWN(PL); /* Don't shut down the error code until other APIs which use it are shut down */ if(pending == 0) pending += DOWN(E); @@ -259,6 +259,7 @@ H5AC_init_interface(void) H5P_genclass_t *xfer_pclass; /* Dataset transfer property list class object */ H5P_genplist_t *xfer_plist; /* Dataset transfer property list object */ unsigned block_before_meta_write; /* "block before meta write" property value */ + unsigned coll_meta_write; /* "collective metadata write" property value */ unsigned library_internal=1; /* "library internal" property value */ H5FD_mpio_xfer_t xfer_mode; /* I/O transfer mode property value */ herr_t ret_value=SUCCEED; /* Return value */ @@ -272,6 +273,7 @@ H5AC_init_interface(void) if (NULL == (xfer_pclass = H5I_object(H5P_CLS_DATASET_XFER_g))) HGOTO_ERROR(H5E_CACHE, H5E_BADATOM, FAIL, "can't get property list class") + /* Get an ID for the blocking, collective H5AC dxpl */ if ((H5AC_dxpl_id=H5P_create_id(xfer_pclass,FALSE)) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, FAIL, "unable to register property list") @@ -291,10 +293,12 @@ H5AC_init_interface(void) NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't insert metadata cache dxpl property") - /* Set the transfer mode */ - xfer_mode=H5FD_MPIO_COLLECTIVE; - if (H5P_set(xfer_plist,H5D_XFER_IO_XFER_MODE_NAME,&xfer_mode)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set value") + /* Insert 'collective metadata write' property */ + coll_meta_write = 1; + if(H5P_insert(xfer_plist, H5AC_COLLECTIVE_META_WRITE_NAME, H5AC_COLLECTIVE_META_WRITE_SIZE, &coll_meta_write, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't insert metadata cache dxpl property") + /* Get an ID for the non-blocking, collective H5AC dxpl */ if ((H5AC_noblock_dxpl_id=H5P_create_id(xfer_pclass,FALSE)) < 0) @@ -315,10 +319,12 @@ H5AC_init_interface(void) NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't insert metadata cache dxpl property") - /* Set the transfer mode */ - xfer_mode=H5FD_MPIO_COLLECTIVE; - if (H5P_set(xfer_plist,H5D_XFER_IO_XFER_MODE_NAME,&xfer_mode)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set value") + /* Insert 'collective metadata write' property */ + coll_meta_write = 1; + if(H5P_insert(xfer_plist, H5AC_COLLECTIVE_META_WRITE_NAME, H5AC_COLLECTIVE_META_WRITE_SIZE, &coll_meta_write, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't insert metadata cache dxpl property") + /* Get an ID for the non-blocking, independent H5AC dxpl */ if ((H5AC_ind_dxpl_id=H5P_create_id(xfer_pclass,FALSE)) < 0) @@ -339,10 +345,11 @@ H5AC_init_interface(void) NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't insert metadata cache dxpl property") - /* Set the transfer mode */ - xfer_mode=H5FD_MPIO_INDEPENDENT; - if (H5P_set(xfer_plist,H5D_XFER_IO_XFER_MODE_NAME,&xfer_mode)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set value") + /* Insert 'collective metadata write' property */ + coll_meta_write = 0; + if(H5P_insert(xfer_plist, H5AC_COLLECTIVE_META_WRITE_NAME, H5AC_COLLECTIVE_META_WRITE_SIZE, &coll_meta_write, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't insert metadata cache dxpl property") done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h index 17ce310..cc669a7 100644 --- a/src/H5ACprivate.h +++ b/src/H5ACprivate.h @@ -199,6 +199,11 @@ typedef H5C_t H5AC_t; #define H5AC_BLOCK_BEFORE_META_WRITE_SIZE sizeof(unsigned) #define H5AC_BLOCK_BEFORE_META_WRITE_DEF 0 +/* Definitions for "collective metadata write" property */ +#define H5AC_COLLECTIVE_META_WRITE_NAME "H5AC_collective_metadata_write" +#define H5AC_COLLECTIVE_META_WRITE_SIZE sizeof(unsigned) +#define H5AC_COLLECTIVE_META_WRITE_DEF 0 + /* Definitions for "library internal" property */ #define H5AC_LIBRARY_INTERNAL_NAME "H5AC_library_internal" #define H5AC_LIBRARY_INTERNAL_SIZE sizeof(unsigned) @@ -75,6 +75,9 @@ #include "H5private.h" /* Generic Functions */ +#ifdef H5_HAVE_PARALLEL +#include "H5ACprivate.h" /* Metadata cache */ +#endif /* H5_HAVE_PARALLEL */ #include "H5Cpkg.h" /* Cache */ #include "H5Dprivate.h" /* Dataset functions */ #include "H5Eprivate.h" /* Error handling */ @@ -8277,37 +8280,27 @@ H5C_flush_single_entry(H5F_t * f, #ifdef H5_HAVE_PARALLEL #ifndef NDEBUG - /* If MPI based VFD is used, do special parallel I/O sanity checks. * Note that we only do these sanity checks when the clear_only flag * is not set, and the entry to be flushed is dirty. Don't bother * otherwise as no file I/O can result. */ - if ( ( ! clear_only ) && - ( entry_ptr->is_dirty ) && - (H5F_HAS_FEATURE(f, H5FD_FEAT_HAS_MPI) ) ) { - - H5P_genplist_t *dxpl; /* Dataset transfer property list */ - H5FD_mpio_xfer_t xfer_mode; /* I/O xfer mode property value */ + if(!clear_only && entry_ptr->is_dirty && + H5F_HAS_FEATURE(f, H5FD_FEAT_HAS_MPI)) { + H5P_genplist_t *dxpl; /* Dataset transfer property list */ + unsigned coll_meta; /* Collective metadata write flag */ /* Get the dataset transfer property list */ - if ( NULL == (dxpl = H5I_object(primary_dxpl_id)) ) { - - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, \ - "not a dataset transfer property list") - } + if(NULL == (dxpl = H5I_object(primary_dxpl_id))) + HGOTO_ERROR(H5E_CACHE, H5E_BADTYPE, FAIL, "not a dataset transfer property list") - /* Get the transfer mode property */ - if( H5P_get(dxpl, H5D_XFER_IO_XFER_MODE_NAME, &xfer_mode) < 0 ) { - - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, \ - "can't retrieve xfer mode") - } - - /* Sanity check transfer mode */ - HDassert( xfer_mode == H5FD_MPIO_COLLECTIVE ); - } + /* Get the collective metadata write property */ + if(H5P_get(dxpl, H5AC_COLLECTIVE_META_WRITE_NAME, &coll_meta) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTGET, FAIL, "can't retrieve xfer mode") + /* Sanity check collective metadata write flag */ + HDassert(coll_meta); + } /* end if */ #endif /* NDEBUG */ #endif /* H5_HAVE_PARALLEL */ @@ -569,7 +569,7 @@ H5Dget_create_plist(hid_t dset_id) { H5VL_t *vol_plugin; void *dset; - hid_t ret_value = FAIL; /* Return value */ + hid_t ret_value = FAIL; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("i", "i", dset_id); diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index 497846b..31e3179 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -1709,8 +1709,9 @@ H5D__chunk_cacheable(const H5D_io_info_t *io_info, haddr_t caddr, hbool_t write_ /* If the fill value needs to be written then we will need * to use the cache to write the fill value */ if(fill->fill_time == H5D_FILL_TIME_ALLOC || - (fill->fill_time == H5D_FILL_TIME_IFSET - && fill_status == H5D_FILL_VALUE_USER_DEFINED)) + (fill->fill_time == H5D_FILL_TIME_IFSET && + (fill_status == H5D_FILL_VALUE_USER_DEFINED || + fill_status == H5D_FILL_VALUE_DEFAULT))) ret_value = TRUE; else ret_value = FALSE; @@ -1796,7 +1797,8 @@ H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, * but they aren't set, set the flag to skip missing chunks. */ if(fill->fill_time == H5D_FILL_TIME_NEVER || - (fill->fill_time == H5D_FILL_TIME_IFSET && fill_status != H5D_FILL_VALUE_USER_DEFINED)) + (fill->fill_time == H5D_FILL_TIME_IFSET && fill_status != H5D_FILL_VALUE_USER_DEFINED && + fill_status != H5D_FILL_VALUE_DEFAULT)) skip_missing_chunks = TRUE; } diff --git a/src/H5Dint.c b/src/H5Dint.c index 402ff8d..ee7cc83 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -2464,15 +2464,16 @@ done: /*------------------------------------------------------------------------- * Function: H5D_get_create_plist * - * Purpose: Returns a copy of the dataset creation property list. + * Purpose: Private function for H5Dget_create_plist * * Return: Success: ID for a copy of the dataset creation - * property list. + * property list. The template should be + * released by calling H5P_close(). * * Failure: FAIL * - * Programmer: Mohamad Chaarawi - * March, 2012 + * Programmer: Robb Matzke + * Tuesday, February 3, 1998 * *------------------------------------------------------------------------- */ @@ -2482,19 +2483,19 @@ H5D_get_create_plist(H5D_t *dset) H5P_genplist_t *dcpl_plist; /* Dataset's DCPL */ H5P_genplist_t *new_plist; /* Copy of dataset's DCPL */ H5O_fill_t copied_fill; /* Fill value to tweak */ - hid_t new_id = FAIL; - hid_t ret_value = FAIL; + hid_t new_dcpl_id = FAIL; + hid_t ret_value; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_NOAPI(FAIL) /* Check args */ if(NULL == (dcpl_plist = (H5P_genplist_t *)H5I_object(dset->shared->dcpl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list") /* Copy the creation property list */ - if((new_id = H5P_copy_plist(dcpl_plist, TRUE)) < 0) + if((new_dcpl_id = H5P_copy_plist(dcpl_plist, TRUE)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to copy the creation property list") - if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(new_id))) + if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(new_dcpl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list") /* Retrieve any object creation properties */ @@ -2565,14 +2566,13 @@ H5D_get_create_plist(H5D_t *dset) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to set property list fill value") /* Set the return value */ - ret_value = new_id; + ret_value = new_dcpl_id; done: - if(ret_value < 0) { - if(new_id > 0) - if(H5I_dec_app_ref(new_id) < 0) - HDONE_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "can't free") - } /* end if */ + if(ret_value < 0) + if(new_dcpl_id > 0) + if(H5I_dec_app_ref(new_dcpl_id) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "unable to close temporary object") FUNC_LEAVE_NOAPI(ret_value) } /* end H5D_get_create_plist() */ diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h index 8baafe9..fe26137 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -171,8 +171,8 @@ H5_DLL H5O_loc_t *H5D_oloc(H5D_t *dataset); H5_DLL H5G_name_t *H5D_nameof(H5D_t *dataset); H5_DLL H5T_t *H5D_typeof(const H5D_t *dset); H5_DLL herr_t H5D_flush(const H5F_t *f, hid_t dxpl_id); -H5_DLL hid_t H5D_get_access_plist(H5D_t *dset); H5_DLL hid_t H5D_get_create_plist(H5D_t *dset); +H5_DLL hid_t H5D_get_access_plist(H5D_t *dset); H5_DLL hid_t H5D_get_space(H5D_t *dset); H5_DLL hid_t H5D_get_type(H5D_t *dset); diff --git a/src/H5Edefin.h b/src/H5Edefin.h index 51a1f66..a2ee0be5 100644 --- a/src/H5Edefin.h +++ b/src/H5Edefin.h @@ -25,6 +25,7 @@ hid_t H5E_FUNC_g = FAIL; /* Function entry/exit */ hid_t H5E_FILE_g = FAIL; /* File accessibilty */ hid_t H5E_SOHM_g = FAIL; /* Shared Object Header Messages */ hid_t H5E_SYM_g = FAIL; /* Symbol table */ +hid_t H5E_PLUGIN_g = FAIL; /* Plugin for dynamically loaded library */ hid_t H5E_VFL_g = FAIL; /* Virtual File Layer */ hid_t H5E_VOL_g = FAIL; /* Virtual Object Layer */ hid_t H5E_INTERNAL_g = FAIL; /* Internal error (too specific to document in detail) */ @@ -132,6 +133,9 @@ hid_t H5E_PATH_g = FAIL; /* Problem with path to object */ /* No error */ hid_t H5E_NONE_MINOR_g = FAIL; /* No error */ +/* Plugin errors */ +hid_t H5E_OPENERROR_g = FAIL; /* Can't open directory or file */ + /* File accessibilty errors */ hid_t H5E_FILEEXISTS_g = FAIL; /* File already exists */ hid_t H5E_FILEOPEN_g = FAIL; /* File already open */ diff --git a/src/H5Einit.h b/src/H5Einit.h index d62d6aa..6ab28bb 100644 --- a/src/H5Einit.h +++ b/src/H5Einit.h @@ -44,6 +44,11 @@ if((msg = H5E_create_msg(cls, H5E_MAJOR, "Symbol table"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") if((H5E_SYM_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_PLUGIN_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Plugin for dynamically loaded library"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_PLUGIN_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") assert(H5E_VFL_g==(-1)); if((msg = H5E_create_msg(cls, H5E_MAJOR, "Virtual File Layer"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") @@ -482,6 +487,13 @@ if((msg = H5E_create_msg(cls, H5E_MINOR, "No error"))==NULL) if((H5E_NONE_MINOR_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +/* Plugin errors */ +assert(H5E_OPENERROR_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't open directory or file"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_OPENERROR_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") + /* File accessibilty errors */ assert(H5E_FILEEXISTS_g==(-1)); if((msg = H5E_create_msg(cls, H5E_MINOR, "File already exists"))==NULL) diff --git a/src/H5Epubgen.h b/src/H5Epubgen.h index eef9b2c..ab2d885 100644 --- a/src/H5Epubgen.h +++ b/src/H5Epubgen.h @@ -28,6 +28,7 @@ #define H5E_FILE (H5OPEN H5E_FILE_g) #define H5E_SOHM (H5OPEN H5E_SOHM_g) #define H5E_SYM (H5OPEN H5E_SYM_g) +#define H5E_PLUGIN (H5OPEN H5E_PLUGIN_g) #define H5E_VFL (H5OPEN H5E_VFL_g) #define H5E_VOL (H5OPEN H5E_VOL_g) #define H5E_INTERNAL (H5OPEN H5E_INTERNAL_g) @@ -61,6 +62,7 @@ H5_DLLVAR hid_t H5E_FUNC_g; /* Function entry/exit */ H5_DLLVAR hid_t H5E_FILE_g; /* File accessibilty */ H5_DLLVAR hid_t H5E_SOHM_g; /* Shared Object Header Messages */ H5_DLLVAR hid_t H5E_SYM_g; /* Symbol table */ +H5_DLLVAR hid_t H5E_PLUGIN_g; /* Plugin for dynamically loaded library */ H5_DLLVAR hid_t H5E_VFL_g; /* Virtual File Layer */ H5_DLLVAR hid_t H5E_VOL_g; /* Virtual Object Layer */ H5_DLLVAR hid_t H5E_INTERNAL_g; /* Internal error (too specific to document in detail) */ @@ -223,6 +225,10 @@ H5_DLLVAR hid_t H5E_PATH_g; /* Problem with path to object */ #define H5E_NONE_MINOR (H5OPEN H5E_NONE_MINOR_g) H5_DLLVAR hid_t H5E_NONE_MINOR_g; /* No error */ +/* Plugin errors */ +#define H5E_OPENERROR (H5OPEN H5E_OPENERROR_g) +H5_DLLVAR hid_t H5E_OPENERROR_g; /* Can't open directory or file */ + /* File accessibilty errors */ #define H5E_FILEEXISTS (H5OPEN H5E_FILEEXISTS_g) #define H5E_FILEOPEN (H5OPEN H5E_FILEOPEN_g) diff --git a/src/H5Eterm.h b/src/H5Eterm.h index ae1eb95..eda59c5 100644 --- a/src/H5Eterm.h +++ b/src/H5Eterm.h @@ -26,6 +26,7 @@ H5E_FUNC_g= H5E_FILE_g= H5E_SOHM_g= H5E_SYM_g= +H5E_PLUGIN_g= H5E_VFL_g= H5E_VOL_g= H5E_INTERNAL_g= @@ -134,6 +135,9 @@ H5E_PATH_g= /* No error */ H5E_NONE_MINOR_g= +/* Plugin errors */ +H5E_OPENERROR_g= + /* File accessibilty errors */ H5E_FILEEXISTS_g= H5E_FILEOPEN_g= diff --git a/src/H5FDmulti.c b/src/H5FDmulti.c index 9d6e065..a3ce7f8 100644 --- a/src/H5FDmulti.c +++ b/src/H5FDmulti.c @@ -73,10 +73,6 @@ #define END_MEMBERS }} - -#define H5FD_MULTI_DXPL_PROP_NAME "H5FD_MULTI_DXPL" -#define H5FD_MULTI_DXPL_PROP_SIZE sizeof(H5FD_multi_dxpl_t) - #define H5FD_MULT_MAX_FILE_NAME_LEN 1024 /* The driver identification number, initialized at runtime */ @@ -1792,18 +1788,6 @@ H5FD_multi_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); - /* Get the data transfer properties */ - if(H5P_FILE_ACCESS_DEFAULT != dxpl_id) { - /* Check for existence of multi VFD DXPL property in DXPL */ - if((prop_exists = H5Pexist(dxpl_id, H5FD_MULTI_DXPL_PROP_NAME)) < 0) - H5Epush_ret(func, H5E_ERR_CLS, H5E_PLIST, H5E_CANTGET, "can't check for multi VFD property", -1) - - /* Get the DXPL value, if it exists */ - if(prop_exists) - if(H5Pget(dxpl_id, H5FD_MULTI_DXPL_PROP_NAME, &dx) < 0) - H5Epush_ret(func, H5E_ERR_CLS, H5E_PLIST, H5E_CANTGET, "can't get property value", -1) - } /* end if */ - /* Find the file to which this address belongs */ for(mt = H5FD_MEM_SUPER; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1)) { mmt = file->fa.memb_map[mt]; @@ -1856,18 +1840,6 @@ H5FD_multi_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); - /* Get the data transfer properties */ - if(H5P_FILE_ACCESS_DEFAULT != dxpl_id) { - /* Check for existence of multi VFD DXPL property in DXPL */ - if((prop_exists = H5Pexist(dxpl_id, H5FD_MULTI_DXPL_PROP_NAME)) < 0) - H5Epush_ret(func, H5E_ERR_CLS, H5E_PLIST, H5E_CANTGET, "can't check for multi VFD property", -1) - - /* Get the DXPL value, if it exists */ - if(prop_exists) - if(H5Pget(dxpl_id, H5FD_MULTI_DXPL_PROP_NAME, &dx) < 0) - H5Epush_ret(func, H5E_ERR_CLS, H5E_PLIST, H5E_CANTGET, "can't get property value", -1) - } /* end if */ - /* Find the file to which this address belongs */ for(mt = H5FD_MEM_SUPER; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1)) { mmt = file->fa.memb_map[mt]; diff --git a/src/H5Gint.c b/src/H5Gint.c index 3eb374c..2d305a2 100644 --- a/src/H5Gint.c +++ b/src/H5Gint.c @@ -1188,15 +1188,16 @@ done: /*------------------------------------------------------------------------- * Function: H5G_get_create_plist * - * Purpose: Returns a copy of the group creation property list. + * Purpose: Private function for H5Gget_create_plist * * Return: Success: ID for a copy of the group creation - * property list. + * property list. The property list ID should be + * released by calling H5Pclose(). * * Failure: FAIL * - * Programmer: Mohamad Chaarawi - * March, 2012 + * Programmer: Quincey Koziol + * Tuesday, October 25, 2005 * *------------------------------------------------------------------------- */ @@ -1209,17 +1210,17 @@ H5G_get_create_plist(H5G_t *grp) htri_t pline_exists; H5P_genplist_t *gcpl_plist; H5P_genplist_t *new_plist; - hid_t new_id = FAIL; - hid_t ret_value = FAIL; + hid_t new_gcpl_id = FAIL; + hid_t ret_value = FAIL; - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_NOAPI(FAIL) /* Copy the default group creation property list */ if(NULL == (gcpl_plist = (H5P_genplist_t *)H5I_object(H5P_LST_GROUP_CREATE_g))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get default group creation property list") - if((new_id = H5P_copy_plist(gcpl_plist, TRUE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get default group creation property list") + if((new_gcpl_id = H5P_copy_plist(gcpl_plist, TRUE)) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to copy the creation property list") - if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(new_id))) + if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(new_gcpl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list") /* Retrieve any object creation properties */ @@ -1228,7 +1229,7 @@ H5G_get_create_plist(H5G_t *grp) /* Check for the group having a group info message */ if((ginfo_exists = H5O_msg_exists(&(grp->oloc), H5O_GINFO_ID, H5AC_ind_dxpl_id)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header") + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header") if(ginfo_exists) { H5O_ginfo_t ginfo; /* Group info message */ @@ -1243,7 +1244,7 @@ H5G_get_create_plist(H5G_t *grp) /* Check for the group having a link info message */ if((linfo_exists = H5G__obj_get_linfo(&(grp->oloc), &linfo, H5AC_ind_dxpl_id)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header") + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header") if(linfo_exists) { /* Set the link info for the property list */ if(H5P_set(new_plist, H5G_CRT_LINK_INFO_NAME, &linfo) < 0) @@ -1266,12 +1267,12 @@ H5G_get_create_plist(H5G_t *grp) } /* end if */ /* Set the return value */ - ret_value = new_id; + ret_value = new_gcpl_id; done: if(ret_value < 0) { - if(new_id > 0) - if(H5I_dec_app_ref(new_id) < 0) + if(new_gcpl_id > 0) + if(H5I_dec_app_ref(new_gcpl_id) < 0) HDONE_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "can't free") } /* end if */ diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h index 328ef93..e159695 100644 --- a/src/H5Gprivate.h +++ b/src/H5Gprivate.h @@ -244,6 +244,7 @@ H5_DLL herr_t H5G_obj_remove_by_idx(const struct H5O_loc_t *grp_oloc, H5RS_str_t H5_index_t idx_type, H5_iter_order_t order, hsize_t n, hid_t dxpl_id); H5_DLL herr_t H5G_obj_lookup_by_idx(const struct H5O_loc_t *grp_oloc, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, struct H5O_link_t *lnk, hid_t dxpl_id); +H5_DLL hid_t H5G_get_create_plist(H5G_t *grp); /* * These functions operate on symbol table nodes. diff --git a/src/H5PL.c b/src/H5PL.c new file mode 100644 index 0000000..07e90af --- /dev/null +++ b/src/H5PL.c @@ -0,0 +1,661 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic document set and is * + * linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have access * + * to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/****************/ +/* Module Setup */ +/****************/ + +/* Interface initialization */ +#define H5_INTERFACE_INIT_FUNC H5PL__init_interface + + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5PLprivate.h" /* Plugin */ +#include "H5Zprivate.h" /* Filter pipeline */ + + +/****************/ +/* Local Macros */ +/****************/ + +#define H5PL_MAX_PATH_NUM 16 + +/****************************/ +/* Macros for supporting + * both Windows and Unix */ +/****************************/ +/* Windows support */ +#ifdef H5_HAVE_WIN32_API + +#define H5PL_DEFAULT_PATH "%ALLUSERSPROFILE%/hdf5/lib/plugin" +#define H5PL_PATH_SEPARATOR ";" + +/* Handle for dynamic library */ +#define H5PL_HANDLE HINSTANCE + +/* Get a handle to a plugin library. Windows: TEXT macro handles Unicode strings */ +#define H5PL_OPEN_DLIB(S) LoadLibraryEx(TEXT(S), NULL, LOAD_WITH_ALTERED_SEARCH_PATH) + +/* Get the address of a symbol in dynamic library */ +#define H5PL_GET_LIB_FUNC(H,N) GetProcAddress(H,N) + +/* Close dynamic library */ +#define H5PL_CLOSE_LIB(H) FreeLibrary(H) + +/* Clear error - nothing to do */ +#define H5PL_CLR_ERROR + +typedef const void *(__cdecl *H5PL_get_plugin_info_t)(void); + +/* Unix support */ +#else /* H5_HAVE_WIN32_API */ + +#define H5PL_DEFAULT_PATH "/usr/local/hdf5/lib/plugin" +#define H5PL_PATH_SEPARATOR ":" + +/* Handle for dynamic library */ +#define H5PL_HANDLE void * + +/* Get a handle to a plugin library. Windows: TEXT macro handles Unicode strings */ +#define H5PL_OPEN_DLIB(S) dlopen(S, RTLD_NOW) + +/* Get the address of a symbol in dynamic library */ +#define H5PL_GET_LIB_FUNC(H,N) dlsym(H,N) + +/* Close dynamic library */ +#define H5PL_CLOSE_LIB(H) dlclose(H) + +/* Clear error */ +#define H5PL_CLR_ERROR dlerror() + +typedef const void *(*H5PL_get_plugin_info_t)(void); +#endif /* H5_HAVE_WIN32_API */ + +/* Special symbol to indicate no plugin loading */ +#define H5PL_NO_PLUGIN "::" + +/******************/ +/* Local Typedefs */ +/******************/ + +/* Type for the list of info for opened plugin libraries */ +typedef struct H5PL_table_t { + H5PL_type_t pl_type; /* plugin type */ + int pl_id; /* ID for the plugin */ + H5PL_HANDLE handle; /* plugin handle */ +} H5PL_table_t; + + +/********************/ +/* Local Prototypes */ +/********************/ + +static herr_t H5PL__init_path_table(void); +static htri_t H5PL__find(H5PL_type_t plugin_type, int type_id, char *dir, const void **info); +static htri_t H5PL__open(H5PL_type_t pl_type, char *libname, int plugin_id, const void **pl_info); +static htri_t H5PL__search_table(H5PL_type_t plugin_type, int type_id, const void **info); +static herr_t H5PL__close(H5PL_HANDLE handle); + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + +/* Table for opened plugin libraries */ +static size_t H5PL_table_alloc_g = 0; +static size_t H5PL_table_used_g = 0; +static H5PL_table_t *H5PL_table_g = NULL; + +/* Table of location paths for plugin libraries */ +static char *H5PL_path_table_g[H5PL_MAX_PATH_NUM]; +static size_t H5PL_num_paths_g = 0; +static hbool_t H5PL_path_found_g = FALSE; + +/* Whether to preload pathnames for plugin libraries */ +static hbool_t H5PL_no_plugin_g = FALSE; + + +/*-------------------------------------------------------------------------- +NAME + H5PL__init_interface -- Initialize interface-specific information +USAGE + herr_t H5PL__init_interface() +RETURNS + Non-negative on success/Negative on failure +DESCRIPTION + Initializes any interface-specific data or routines. + +--------------------------------------------------------------------------*/ +static herr_t +H5PL__init_interface(void) +{ + char *preload_path; + + FUNC_ENTER_STATIC_NOERR + + /* Retrieve pathnames from HDF5_PLUGIN_PRELOAD if the user sets it + * to tell the library to load plugin libraries without search. + */ + if(NULL != (preload_path = HDgetenv("HDF5_PLUGIN_PRELOAD"))) { + /* Special symbal "::" means no plugin during data reading. */ + if(!HDstrcmp(preload_path, H5PL_NO_PLUGIN)) + H5PL_no_plugin_g = TRUE; + } /* end if */ + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* 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 + * + *------------------------------------------------------------------------- + */ +htri_t +H5PL_no_plugin(void) +{ + htri_t ret_value; + + FUNC_ENTER_NOAPI(FAIL) + + ret_value = (htri_t)H5PL_no_plugin_g; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5PL_no_plugin() */ + + +/*------------------------------------------------------------------------- + * Function: H5PL_term_interface + * + * Purpose: Terminate the H5PL interface: release all memory, reset all + * global variables to initial values. This only happens if all + * types have been destroyed from other interfaces. + * + * Return: Success: Positive if any action was taken that might + * affect some other interface; zero otherwise. + * + * Failure: Negative. + * + * Programmer: Raymond Lu + * 20 February 2013 + * + *------------------------------------------------------------------------- + */ +int +H5PL_term_interface(void) +{ + int i = 0; + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + if(H5_interface_initialize_g) { + size_t u; /* Local index variable */ + + /* Close opened dynamic libraries */ + for(u = 0; u < H5PL_table_used_g; u++) + H5PL__close((H5PL_table_g[u]).handle); + + /* Free the table of dynamic libraries */ + H5PL_table_g = (H5PL_table_t *)H5MM_xfree(H5PL_table_g); + H5PL_table_used_g = H5PL_table_alloc_g = 0; + + /* Free the table of search paths */ + for(u = 0; u < H5PL_num_paths_g; u++) + if(H5PL_path_table_g[u]) + H5PL_path_table_g[u] = (char *)H5MM_xfree(H5PL_path_table_g[u]); + H5PL_num_paths_g = 0; + H5PL_path_found_g = FALSE; + + H5_interface_initialize_g = 0; + i = 1; + } /* end if */ + + FUNC_LEAVE_NOAPI(i) +} /* end H5PL_term_interface() */ + + +/*------------------------------------------------------------------------- + * Function: H5PL_load + * + * Purpose: Given the plugin type and identifier, this function searches + * and/or loads a dynamic plugin library first among the already + * opened libraries then in the designated location paths. + * + * Return: Non-NULL on success/NULL on failure + * + * Programmer: Raymond Lu + * 13 February 2013 + * + *------------------------------------------------------------------------- + */ +const void * +H5PL_load(H5PL_type_t type, int id) +{ + htri_t found; /* Whether the plugin was found */ + const void *plugin_info = NULL; + const void *ret_value = NULL; + + FUNC_ENTER_NOAPI(NULL) + + /* Initialize the location paths for dynamic libraries, if they aren't + * already set up. + */ + if(FALSE == H5PL_path_found_g) + if(H5PL__init_path_table() < 0) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTINIT, NULL, "can't initialize search path table") + + /* Search in the table of already loaded plugin libraries */ + if((found = H5PL__search_table(type, id, &plugin_info)) < 0) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, NULL, "search in table failed") + + /* If not found, iterate through the path table to find the right dynamic library */ + if(!found) { + size_t i; /* Local index variable */ + + for(i = 0; i < H5PL_num_paths_g; i++) { + if((found = H5PL__find(type, id, H5PL_path_table_g[i], &plugin_info)) < 0) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, NULL, "search in paths failed") + + /* Break out if found */ + if(found) { + HDassert(plugin_info); + break; + } /* end if */ + } /* end for */ + } /* end if */ + + /* Check if we found the plugin */ + if(found) + ret_value = plugin_info; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5PL_load() */ + + +/*------------------------------------------------------------------------- + * Function: H5PL__init_path_table + * + * Purpose: Initialize the path table. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * 18 March 2013 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5PL__init_path_table(void) +{ + char *dl_path = NULL; + char *origin_dl_path; + char *dir; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Retrieve paths from HDF5_PLUGIN_PATH if the user sets it + * or from the default paths if it isn't set. + */ + origin_dl_path = HDgetenv("HDF5_PLUGIN_PATH"); + if(NULL == origin_dl_path) + dl_path = HDstrdup(H5PL_DEFAULT_PATH); + else + dl_path = HDstrdup(origin_dl_path); + if(NULL == dl_path) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path") + + /* Put paths in the path table. They are separated by ":" */ + dir = HDstrtok(dl_path, H5PL_PATH_SEPARATOR); + while(dir) { + /* Check for too many directories in path */ + if(H5PL_num_paths_g == H5PL_MAX_PATH_NUM) + HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "too many directories in path for table") + if(NULL == (H5PL_path_table_g[H5PL_num_paths_g] = HDstrdup(dir))) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path") + H5PL_num_paths_g++; + dir = HDstrtok(NULL, H5PL_PATH_SEPARATOR); + } /* end while */ + + H5PL_path_found_g = TRUE; + +done: + if(dl_path) + dl_path = (char *)H5MM_xfree(dl_path); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5PL__init_path_table() */ + + +/*------------------------------------------------------------------------- + * Function: H5PL__find + * + * Purpose: Given a path, this function opens the directory and envokes + * another function to go through all files to find the right + * plugin library. Two function definitions are for Unix and + * Windows. + * + * Return: TRUE on success, + * FALSE on not found, + * negative on failure + * + * Programmer: Raymond Lu + * 13 February 2013 + * + *------------------------------------------------------------------------- + */ +#ifndef H5_HAVE_WIN32_API +static htri_t +H5PL__find(H5PL_type_t plugin_type, int type_id, char *dir, const void **info) +{ + char *pathname = NULL; + DIR *dirp = NULL; + struct dirent *dp; + htri_t ret_value = FALSE; + + FUNC_ENTER_STATIC + + /* Open the directory */ + if(!(dirp = HDopendir(dir))) + HGOTO_ERROR(H5E_PLUGIN, H5E_OPENERROR, FAIL, "can't open directory") + + /* Iterates through all entries in the directory to find the right plugin library */ + while(NULL != (dp = HDreaddir(dirp))) { + /* The library we are looking for should be called libxxx.so... on Unix + * or libxxx.xxx.dylib on Mac. + */ + if(!HDstrncmp(dp->d_name, "lib", (size_t)3) && + (HDstrstr(dp->d_name, ".so") || HDstrstr(dp->d_name, ".dylib"))) { + h5_stat_t my_stat; + size_t pathname_len; + htri_t found_in_dir; + + /* Allocate & initialize the path name */ + pathname_len = HDstrlen(dir) + HDstrlen(dp->d_name) + 2; + if(NULL == (pathname = (char *)H5MM_malloc(pathname_len))) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path") + HDsnprintf(pathname, pathname_len, "%s/%s", dir, dp->d_name); + + /* Get info for directory entry */ + if(HDstat(pathname, &my_stat) == -1) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't stat file: %s", strerror(errno)) + + /* If it is a directory, skip it */ + if(S_ISDIR(my_stat.st_mode)) + continue; + + /* Attempt to open the dynamic library as a filter library */ + if((found_in_dir = H5PL__open(plugin_type, pathname, type_id, info)) < 0) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "search in directory failed") + if(found_in_dir) { + /* Indicate success */ + HGOTO_DONE(TRUE) + } /* end if */ + else + HDassert(pathname); + pathname = (char *)H5MM_xfree(pathname); + } /* end if */ + } /* end while */ + +done: + if(dirp) + if(HDclosedir(dirp) < 0) + HDONE_ERROR(H5E_FILE, H5E_CLOSEERROR, FAIL, "can't close directory: %s", strerror(errno)) + if(pathname) + pathname = (char *)H5MM_xfree(pathname); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5PL__find() */ +#else /* H5_HAVE_WIN32_API */ +static htri_t +H5PL__find(H5PL_type_t plugin_type, int type_id, char *dir, const void **info) +{ + WIN32_FIND_DATA fdFile; + HANDLE hFind; + char *pathname = NULL; + char service[2048]; + htri_t ret_value = FALSE; + + FUNC_ENTER_STATIC + + /* Specify a file mask. *.* = We want everything! */ + sprintf(service, "%s\/*.dll", dir); + if((hFind = FindFirstFile(service, &fdFile)) == INVALID_HANDLE_VALUE) + HGOTO_ERROR(H5E_PLUGIN, H5E_OPENERROR, FAIL, "can't open directory") + + do { + /* Find first file will always return "." + * and ".." as the first two directories. + */ + if(HDstrcmp(fdFile.cFileName, ".") != 0 && HDstrcmp(fdFile.cFileName, "..") != 0) { + size_t pathname_len; + htri_t found_in_dir; + + /* Allocate & initialize the path name */ + pathname_len = HDstrlen(dir) + HDstrlen(fdFile.cFileName) + 2; + if(NULL == (pathname = (char *)H5MM_malloc(pathname_len))) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path") + HDsnprintf(pathname, pathname_len, "%s\\%s", dir, fdFile.cFileName); + + /* Is the entity a File or Folder? */ + if(fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + continue; + + if((found_in_dir = H5PL__open(plugin_type, pathname, type_id, info)) < 0) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "search in directory failed") + if(found_in_dir) { + /* Indicate success */ + HGOTO_DONE(TRUE) + } /* end if */ + else + HDassert(pathname); + pathname = (char *)H5MM_xfree(pathname); + } /* end if */ + } while(FindNextFile(hFind, &fdFile)); /* Find the next file. */ + +done: + if(hFind) + FindClose(hFind); + if(pathname) + pathname = (char *)H5MM_xfree(pathname); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5PL__find() */ +#endif /* H5_HAVE_WIN32_API */ + + +/*------------------------------------------------------------------------- + * Function: H5PL__open + * + * Purpose: Iterates through all files to find the right plugin library. + * It loads the dynamic plugin library and keeps it on the list + * of loaded libraries. + * + * Return: TRUE on success, + * FALSE on not found, + * negative on failure + * + * Programmer: Raymond Lu + * 13 February 2013 + * + *------------------------------------------------------------------------- + */ +static htri_t +H5PL__open(H5PL_type_t pl_type, char *libname, int pl_id, const void **pl_info) +{ + H5PL_HANDLE handle = NULL; + htri_t ret_value = FALSE; + + FUNC_ENTER_STATIC + + /* There are different reasons why a library can't be open, e.g. wrong architecture. + * simply continue if we can't open it. + */ + if(NULL == (handle = H5PL_OPEN_DLIB(libname))) { + H5PL_CLR_ERROR; /* clear error */ + } /* end if */ + else { + H5PL_get_plugin_info_t get_plugin_info = NULL; + + /* Return a handle for the function H5PLget_plugin_info in the dynamic library. + * The plugin library is suppose to define this function. + */ + if(NULL == (get_plugin_info = (H5PL_get_plugin_info_t)H5PL_GET_LIB_FUNC(handle, "H5PLget_plugin_info"))) { + if(H5PL__close(handle) < 0) + HGOTO_ERROR(H5E_PLUGIN, H5E_CLOSEERROR, FAIL, "can't close dynamic library") + } /* end if */ + else { + const H5Z_class2_t *plugin_info; + + /* Invoke H5PLget_plugin_info to verify this is the right library we are looking for. + * Move on if it isn't. + */ + if(NULL == (plugin_info = (const H5Z_class2_t *)(*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") + } /* end if */ + + /* Successfully found plugin library, check if it's the right one */ + if(plugin_info->id == pl_id) { + /* Expand the table if it is too small */ + if(H5PL_table_used_g >= H5PL_table_alloc_g) { + size_t n = MAX(H5Z_MAX_NFILTERS, 2 * H5PL_table_alloc_g); + H5PL_table_t *table = (H5PL_table_t *)H5MM_realloc(H5PL_table_g, n * sizeof(H5PL_table_t)); + + if(!table) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "unable to extend dynamic library table") + + H5PL_table_g = table; + H5PL_table_alloc_g = n; + } /* end if */ + + (H5PL_table_g[H5PL_table_used_g]).handle = handle; + (H5PL_table_g[H5PL_table_used_g]).pl_type = pl_type; + (H5PL_table_g[H5PL_table_used_g]).pl_id = plugin_info->id; + H5PL_table_used_g++; + + /* Set the plugin info to return */ + *pl_info = (const void *)plugin_info; + + /* Indicate success */ + ret_value = TRUE; + } /* end if */ + else + if(H5PL__close(handle) < 0) + HGOTO_ERROR(H5E_PLUGIN, H5E_CLOSEERROR, FAIL, "can't close dynamic library") + } /* end if */ + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5PL__open() */ + + +/*------------------------------------------------------------------------- + * Function: H5PL__search_table + * + * Purpose: Search in the list of already opened dynamic libraries + * to see if the one we are looking for is already opened. + * + * Return: TRUE on success, + * FALSE on not found, + * Negative on failure + * + * Programmer: Raymond Lu + * 13 February 2013 + * + *------------------------------------------------------------------------- + */ +static htri_t +H5PL__search_table(H5PL_type_t plugin_type, int type_id, const void **info) +{ + htri_t ret_value = FALSE; + + FUNC_ENTER_STATIC + + /* Search in the table of already opened dynamic libraries */ + if(H5PL_table_used_g > 0) { + size_t i; + + 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)) { + H5PL_get_plugin_info_t get_plugin_info; + const H5Z_class2_t *plugin_info; + + if(NULL == (get_plugin_info = (H5PL_get_plugin_info_t)H5PL_GET_LIB_FUNC((H5PL_table_g[i]).handle, "H5PLget_plugin_info"))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get function for H5PLget_plugin_info") + + if(NULL == (plugin_info = (const H5Z_class2_t *)(*get_plugin_info)())) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get plugin info") + + *info = plugin_info; + HGOTO_DONE(TRUE) + } /* end if */ + } /* end for */ + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5PL__search_table() */ + + +/*------------------------------------------------------------------------- + * Function: H5PL__close + * + * Purpose: Closes the handle for dynamic library + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Raymond Lu + * 13 February 2013 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5PL__close(H5PL_HANDLE handle) +{ + FUNC_ENTER_STATIC_NOERR + + H5PL_CLOSE_LIB(handle); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5PL__close() */ + diff --git a/src/H5PLextern.h b/src/H5PLextern.h new file mode 100644 index 0000000..943e3aa --- /dev/null +++ b/src/H5PLextern.h @@ -0,0 +1,84 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic document set and is * + * linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have access * + * to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Programmer: Raymond Lu <songyulu@hdfgroup.org> + * 13 February 2013 + */ +#ifndef _H5PLextern_H +#define _H5PLextern_H + +/* Include HDF5 header */ +#include "hdf5.h" + +/*******************/ +/* Public Typedefs */ +/*******************/ + +/* Plugin type */ +typedef enum H5PL_type_t { + H5PL_TYPE_ERROR = -1, /*error */ + H5PL_TYPE_FILTER = 0, /*filter */ + H5PL_TYPE_NONE = 1 /*this must be last! */ +} H5PL_type_t; + + +#ifdef H5_BUILT_AS_DYNAMIC_LIB + + #if defined (hdf5_EXPORTS) + /* hdf5 library imports from plugin */ + #if defined (_MSC_VER) /* MSVC Compiler Case */ + #define H5PLUGIN_DLL __declspec(dllimport) + #elif (__GNUC__ >= 4) /* GCC 4.x has support for visibility options */ + #define H5PLUGIN_DLL __attribute__ ((visibility("default"))) + #endif + #else + /* plugins always export */ + #if defined (_MSC_VER) /* MSVC Compiler Case */ + #define H5PLUGIN_DLL __declspec(dllexport) + #elif (__GNUC__ >= 4) /* GCC 4.x has support for visibility options */ + #define H5PLUGIN_DLL __attribute__ ((visibility("default"))) + #endif + #endif + +#elif defined(H5_BUILT_AS_STATIC_LIB) + #define H5PLUGIN_DLL +#else + + #if defined(H5_HAVE_WIN32_API) + #if defined(_HDF5DLL_) + #pragma warning(disable: 4273) /* Disable the dll linkage warnings */ + #define H5PLUGIN_DLL __declspec(dllimport) + #elif defined(_HDF5USEDLL_) + #define H5PLUGIN_DLL __declspec(dllexport) + #endif /* _HDF5DLL_ */ + #else /*H5_HAVE_WIN32_API*/ + #define H5PLUGIN_DLL + #endif /*H5_HAVE_WIN32_API*/ + +#endif /* H5_BUILT_AS_xxx_LIB */ + +#ifdef __cplusplus +extern "C" { +#endif + +H5PLUGIN_DLL H5PL_type_t H5PLget_plugin_type(void); +H5PLUGIN_DLL const void *H5PLget_plugin_info(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _H5PLextern_H */ + diff --git a/src/H5PLprivate.h b/src/H5PLprivate.h new file mode 100644 index 0000000..b117613 --- /dev/null +++ b/src/H5PLprivate.h @@ -0,0 +1,53 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic document set and is * + * linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have access * + * to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* Programmer: Raymond Lu <songyulu@hdfgroup.org> + * 13 February 2013 + */ + +#ifndef _H5PLprivate_H +#define _H5PLprivate_H + +/* Include package's "external" header */ +#include "H5PLextern.h" + +/* Private headers needed by this file */ +#include "H5private.h" /* Generic Functions */ + + +/**************************/ +/* Library Private Macros */ +/**************************/ + + +/****************************/ +/* Library Private Typedefs */ +/****************************/ + + +/*****************************/ +/* Library-private Variables */ +/*****************************/ + + +/***************************************/ +/* Library-private Function Prototypes */ +/***************************************/ + +/* Internal API routines */ +H5_DLL const void *H5PL_load(H5PL_type_t plugin_type, int type_id); +H5_DLL htri_t H5PL_no_plugin(void); + +#endif /* _H5PLprivate_H */ + diff --git a/src/H5Pocpl.c b/src/H5Pocpl.c index d8ddfee..f80e4e7 100644 --- a/src/H5Pocpl.c +++ b/src/H5Pocpl.c @@ -40,6 +40,8 @@ #include "H5MMprivate.h" /* Memory management */ #include "H5Opkg.h" /* Object headers */ #include "H5Ppkg.h" /* Property lists */ +#include "H5PLprivate.h" /* Dynamic plugin */ +#include "H5Zprivate.h" /* Filter pipeline */ /****************/ @@ -90,6 +92,9 @@ static herr_t H5P__ocrt_pipeline_enc(const void *value, void **_pp, size_t *size static herr_t H5P__ocrt_pipeline_dec(const void **_pp, void *value); static int H5P__ocrt_pipeline_cmp(const void *value1, const void *value2, size_t size); +/* Local routines */ +static herr_t H5P__set_filter(H5P_genplist_t *plist, H5Z_filter_t filter, + unsigned int flags, size_t cd_nelmts, const unsigned int cd_values[/*cd_nelmts*/]); /*********************/ /* Package Variables */ @@ -747,7 +752,6 @@ H5Pset_filter(hid_t plist_id, H5Z_filter_t filter, unsigned int flags, size_t cd_nelmts, const unsigned int cd_values[/*cd_nelmts*/]) { H5P_genplist_t *plist; /* Property list */ - H5O_pline_t pline; /* Filter pipeline */ herr_t ret_value=SUCCEED; /* return value */ FUNC_ENTER_API(FAIL) @@ -765,6 +769,74 @@ H5Pset_filter(hid_t plist_id, H5Z_filter_t filter, unsigned int flags, if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE))) HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + /* Call the private function */ + if(H5P__set_filter(plist, filter, flags, cd_nelmts, cd_values) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "failed to call private function") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pset_filter() */ + + +/*------------------------------------------------------------------------- + * Function: H5P__set_filter + * + * Purpose: Adds the specified FILTER and corresponding properties to the + * end of the data or link output filter pipeline + * depending on whether PLIST is a dataset creation or group + * creation property list. The FLAGS argument specifies certain + * general properties of the filter and is documented below. + * The CD_VALUES is an array of CD_NELMTS integers which are + * auxiliary data for the filter. The integer vlues will be + * stored in the dataset object header as part of the filter + * information. + * + * The FLAGS argument is a bit vector of the following fields: + * + * H5Z_FLAG_OPTIONAL(0x0001) + * If this bit is set then the filter is optional. If the + * filter fails during an H5Dwrite() operation then the filter + * is just excluded from the pipeline for the chunk for which it + * failed; the filter will not participate in the pipeline + * during an H5Dread() of the chunk. If this bit is clear and + * the filter fails then the entire I/O operation fails. + * If this bit is set but encoding is disabled for a filter, + * attempting to write will generate an error. + * + * If the filter is not registered, this function tries to load + * it dynamically during run time. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Wednesday, April 15, 1998 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5P__set_filter(H5P_genplist_t *plist, H5Z_filter_t filter, unsigned int flags, + size_t cd_nelmts, const unsigned int cd_values[/*cd_nelmts*/]) +{ + H5O_pline_t pline; /* Filter pipeline */ + htri_t filter_avail; /* Filter availability */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check if filter is already available */ + if((filter_avail = H5Z_filter_avail(filter)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't check filter availability") + + /* If filter is not available, try to dynamically load it */ + if(!filter_avail) { + const H5Z_class2_t *filter_info; + + if(NULL == (filter_info = (const H5Z_class2_t *)H5PL_load(H5PL_TYPE_FILTER, (int)filter))) + HGOTO_ERROR(H5E_PLINE, H5E_CANTLOAD, FAIL, "failed to load dynamically loaded plugin") + if(H5Z_register(filter_info) < 0) + HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to register filter") + } /* end if */ + /* Get the pipeline property to append to */ if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") @@ -778,8 +850,8 @@ H5Pset_filter(hid_t plist_id, H5Z_filter_t filter, unsigned int flags, HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline") done: - FUNC_LEAVE_API(ret_value) -} /* end H5Pset_filter() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P__set_filter() */ /*------------------------------------------------------------------------- @@ -1105,6 +1177,43 @@ done: /*------------------------------------------------------------------------- + * Function: H5P_filter_in_pline + * + * Purpose: Check whether the filter is in the pipeline of the object + * creation property list. + * + * Return: TRUE: found + * FALSE: not found + * FAIL: error + * + * Programmer: Raymond Lu + * 26 April 2013 + * + *------------------------------------------------------------------------- + */ +htri_t +H5P_filter_in_pline(H5P_genplist_t *plist, H5Z_filter_t id) +{ + H5O_pline_t pline; /* Filter pipeline */ + H5Z_filter_info_t *filter; /* Pointer to filter information */ + htri_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Get pipeline info */ + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") + + /* Check if the file is in the pipeline */ + if((ret_value = H5Z_filter_in_pline(&pline, id)) < 0) + HGOTO_ERROR(H5E_PLINE, H5E_CANTCOMPARE, FAIL, "can't find filter") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P_get_filter_by_id() */ + + +/*------------------------------------------------------------------------- * Function: H5Premove_filter * * Purpose: Deletes a filter from the dataset creation property list; diff --git a/src/H5Pprivate.h b/src/H5Pprivate.h index 3835a16..0c3b5aa 100644 --- a/src/H5Pprivate.h +++ b/src/H5Pprivate.h @@ -112,6 +112,7 @@ H5_DLL herr_t H5P_modify_filter(H5P_genplist_t *plist, H5Z_filter_t filter, H5_DLL herr_t H5P_get_filter_by_id(H5P_genplist_t *plist, H5Z_filter_t id, unsigned int *flags, size_t *cd_nelmts, unsigned cd_values[], size_t namelen, char name[], unsigned *filter_config); +H5_DLL htri_t H5P_filter_in_pline(H5P_genplist_t *plist, H5Z_filter_t id); /* *SPECIAL* Don't make more of these! -QAK */ H5_DLL htri_t H5P_isa_class(hid_t plist_id, hid_t pclass_id); @@ -22,10 +22,12 @@ #include "H5private.h" /* Generic Functions */ #include "H5Dprivate.h" /* Dataset functions */ #include "H5Eprivate.h" /* Error handling */ +#include "H5Fprivate.h" /* File */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Oprivate.h" /* Object headers */ #include "H5Pprivate.h" /* Property lists */ +#include "H5PLprivate.h" /* Plugins */ #include "H5Sprivate.h" /* Dataspace functions */ #include "H5Zpkg.h" /* Data filters */ @@ -44,12 +46,20 @@ typedef struct H5Z_stats_t { } H5Z_stats_t; #endif /* H5Z_DEBUG */ +typedef struct H5Z_object_t { + H5Z_filter_t filter_id; /* ID of the filter we're looking for */ + htri_t found; /* Whether we find an object using the filter */ +} H5Z_object_t; + /* Enumerated type for dataset creation prelude callbacks */ typedef enum { H5Z_PRELUDE_CAN_APPLY, /* Call "can apply" callback */ H5Z_PRELUDE_SET_LOCAL /* Call "set local" callback */ } H5Z_prelude_type_t; +/* Maximal number of the list of opened objects (2^16) */ +#define NUM_OBJS 65536 + /* Local variables */ static size_t H5Z_table_alloc_g = 0; static size_t H5Z_table_used_g = 0; @@ -60,6 +70,8 @@ static H5Z_stats_t *H5Z_stat_table_g = NULL; /* Local functions */ static int H5Z_find_idx(H5Z_filter_t id); +static int H5Z_get_object_cb(void *obj_ptr, hid_t obj_id, void *key); +static int H5Z_get_file_cb(void *obj_ptr, hid_t obj_id, void *key); /*------------------------------------------------------------------------- @@ -402,29 +414,52 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Z_unregister (H5Z_filter_t id) +H5Z_unregister (H5Z_filter_t filter_id) { - size_t i; /* Local index variable */ - herr_t ret_value=SUCCEED; /* Return value */ + size_t filter_index; /* Local index variable for filter */ + H5Z_object_t object; + herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) - assert (id>=0 && id<=H5Z_FILTER_MAX); + assert (filter_id>=0 && filter_id<=H5Z_FILTER_MAX); /* Is the filter already registered? */ - for (i=0; i<H5Z_table_used_g; i++) - if (H5Z_table_g[i].id==id) + for (filter_index=0; filter_index<H5Z_table_used_g; filter_index++) + if (H5Z_table_g[filter_index].id==filter_id) break; /* Fail if filter not found */ - if (i>=H5Z_table_used_g) + if (filter_index>=H5Z_table_used_g) HGOTO_ERROR(H5E_PLINE, H5E_NOTFOUND, FAIL, "filter is not registered") + /* Initialize the structure object for iteration */ + object.filter_id = filter_id; + object.found = FALSE; + + /* Iterate through all opened datasets, returns a failure if any of them uses the filter */ + if(H5I_iterate(H5I_DATASET, H5Z_get_object_cb, &object, FALSE) < 0) + HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed") + + if(object.found) + HGOTO_ERROR(H5E_PLINE, H5E_CANTRELEASE, FAIL, "can't unregister filter because a dataset is still using it") + + /* Iterate through all opened groups, returns a failure if any of them uses the filter */ + if(H5I_iterate(H5I_GROUP, H5Z_get_object_cb, &object, FALSE) < 0) + HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed") + + if(object.found) + HGOTO_ERROR(H5E_PLINE, H5E_CANTRELEASE, FAIL, "can't unregister filter because a group is still using it") + + /* Iterate through all opened files and flush them */ + if(H5I_iterate(H5I_FILE, H5Z_get_file_cb, NULL, FALSE) < 0) + HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed") + /* Remove filter from table */ /* Don't worry about shrinking table size (for now) */ - HDmemmove(&H5Z_table_g[i],&H5Z_table_g[i+1],sizeof(H5Z_class2_t)*((H5Z_table_used_g-1)-i)); + HDmemmove(&H5Z_table_g[filter_index],&H5Z_table_g[filter_index+1],sizeof(H5Z_class2_t)*((H5Z_table_used_g-1)-filter_index)); #ifdef H5Z_DEBUG - HDmemmove(&H5Z_stat_table_g[i],&H5Z_stat_table_g[i+1],sizeof(H5Z_stats_t)*((H5Z_table_used_g-1)-i)); + HDmemmove(&H5Z_stat_table_g[filter_index],&H5Z_stat_table_g[filter_index+1],sizeof(H5Z_stats_t)*((H5Z_table_used_g-1)-filter_index)); #endif /* H5Z_DEBUG */ H5Z_table_used_g--; @@ -434,6 +469,111 @@ done: /*------------------------------------------------------------------------- + * Function: H5Z_get_object_cb + * + * Purpose: The callback function for H5Z_unregister. It iterates + * through all opened objects. If the object is a dataset + * or a group and it uses the filter to be unregistered, the + * function returns TRUE. + * + * Return: TRUE if the object uses the filter. + * FALSE otherwise. + * + * Programmer: Raymond Lu + * 6 May 2013 + * + *------------------------------------------------------------------------- + */ +static int +H5Z_get_object_cb(void *obj_ptr, hid_t obj_id, void *key) +{ + H5I_type_t id_type; + hid_t ocpl_id; + H5P_genplist_t *plist; /* Property list */ + H5Z_object_t *object = (H5Z_object_t *)key; + htri_t filter_in_pline = FALSE; + int ret_value = FALSE; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + HDassert(obj_ptr); + + if((id_type = H5I_get_type(obj_id)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "bad object id"); + + switch(id_type) { + case H5I_GROUP: + if((ocpl_id = H5G_get_create_plist(obj_ptr)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get group creation property list") + + break; + + case H5I_DATASET: + if((ocpl_id = H5D_get_create_plist(obj_ptr)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get dataset creation property list") + + break; + + default: + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid object") + } /* end switch */ + + /* Get the plist structure of object creation */ + if(NULL == (plist = H5P_object_verify(ocpl_id, H5P_OBJECT_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Check if the object creation property list uses the filter */ + if((filter_in_pline = H5P_filter_in_pline(plist, object->filter_id)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't check filter in pipeline") + + /* H5I_iterate expects TRUE to stop the loop over objects. Stop the loop and let + * H5Z_unregister return failure */ + if(filter_in_pline) { + object->found = TRUE; + ret_value = TRUE; + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_get_object_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5Z_get_file_cb + * + * Purpose: The callback function for H5Z_unregister. It iterates + * through all opened files and flush them. + * + * Return: FALSE if finishes flushing and moves on + * FAIL if there is an error + * + * Programmer: Raymond Lu + * 6 May 2013 + * + *------------------------------------------------------------------------- + */ +static int +H5Z_get_file_cb(void *obj_ptr, hid_t obj_id, void *key) +{ + int ret_value = FALSE; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + HDassert(obj_ptr); + + /* Call the flush routine for mounted file hierarchies. Do a global flush + * if the file is opened for write */ + if(H5F_ACC_RDWR & H5F_INTENT((H5F_t *)obj_ptr)) { + if(H5F_flush_mounts((H5F_t *)obj_ptr, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file hierarchy") + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_get_file_cb() */ + + +/*------------------------------------------------------------------------- * Function: H5Zfilter_avail * * Purpose: Check if a filter is available @@ -450,7 +590,6 @@ done: htri_t H5Zfilter_avail(H5Z_filter_t id) { - size_t i; /* Local index variable */ htri_t ret_value=FALSE; /* Return value */ FUNC_ENTER_API(FAIL) @@ -459,13 +598,9 @@ H5Zfilter_avail(H5Z_filter_t id) /* Check args */ if(id<0 || id>H5Z_FILTER_MAX) HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid filter identification number") - - /* Is the filter already registered? */ - for(i=0; i<H5Z_table_used_g; i++) - if(H5Z_table_g[i].id==id) { - ret_value=TRUE; - break; - } /* end if */ + + if((ret_value = H5Z_filter_avail(id)) < 0) + HGOTO_ERROR(H5E_PLINE, H5E_NOTFOUND, FAIL, "unable to check the availability of the filter") done: FUNC_LEAVE_API(ret_value) @@ -473,6 +608,36 @@ done: /*------------------------------------------------------------------------- + * Function: H5Z_filter_avail + * + * Purpose: Private function to check if a filter is available + * + * Return: Non-negative (TRUE/FALSE) on success/Negative on failure + * + * Programmer: Raymond Lu + * 13 February 2013 + * + *------------------------------------------------------------------------- + */ +htri_t +H5Z_filter_avail(H5Z_filter_t id) +{ + size_t i; /* Local index variable */ + htri_t ret_value = FALSE; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Is the filter already registered? */ + for(i = 0; i < H5Z_table_used_g; i++) + if(H5Z_table_g[i].id == id) + HGOTO_DONE(TRUE) + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5Z_filter_avail() */ + + +/*------------------------------------------------------------------------- * Function: H5Z_prelude_callback * * Purpose: Makes a dataset creation "prelude" callback for the "can_apply" @@ -1088,16 +1253,45 @@ H5Z_pipeline(const H5O_pline_t *pline, unsigned flags, failed |= (unsigned)1 << idx; continue;/*filter excluded*/ } - if ((fclass_idx=H5Z_find_idx(pline->filter[idx].id))<0) { - /* 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") - } + /* 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) { + hbool_t issue_error = FALSE; + + /* Check for "no plugins" indicated" */ + if(H5PL_no_plugin()) + issue_error = TRUE; + else { + const H5Z_class2_t *filter_info; + + /* Try loading the filter */ + if(NULL != (filter_info = (const H5Z_class2_t *)H5PL_load(H5PL_TYPE_FILTER, (int)(pline->filter[idx].id)))) { + /* Register the filter we loaded */ + if(H5Z_register(filter_info) < 0) + HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to register filter") + + /* Search in the table of registered filters again to find the dynamic filter just loaded and registered */ + if((fclass_idx = H5Z_find_idx(pline->filter[idx].id)) < 0) + issue_error = TRUE; + } /* end if */ + else + issue_error = TRUE; + } /* end else */ + + /* Check for error */ + if(issue_error) { + /* 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") + } /* end if */ + } /* end if */ + fclass=&H5Z_table_g[fclass_idx]; #ifdef H5Z_DEBUG fstats=&H5Z_stat_table_g[fclass_idx]; @@ -1220,6 +1414,49 @@ done: /*------------------------------------------------------------------------- + * Function: H5Z_filter_in_pline + * + * Purpose: Check wheter a filter is in the filter pipeline using the + * filter ID. This function is very similar to H5Z_filter_info + * + * Return: TRUE - found filter + * FALSE - not found + * FAIL - error + * + * Programmer: Raymond Lu + * 26 April 2013 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +htri_t +H5Z_filter_in_pline(const H5O_pline_t *pline, H5Z_filter_t filter) +{ + size_t idx; /* Index of filter in pipeline */ + htri_t ret_value = TRUE; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + assert(pline); + assert(filter>=0 && filter<=H5Z_FILTER_MAX); + + /* Locate the filter in the pipeline */ + for(idx=0; idx<pline->nused; idx++) + if(pline->filter[idx].id==filter) + break; + + /* Check if the filter was not already in the pipeline */ + if(idx>=pline->nused) + ret_value = FALSE; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5Z_filter_in_pline() */ + + + +/*------------------------------------------------------------------------- * Function: H5Z_all_filters_avail * * Purpose: Verify that all the filters in a pipeline are currently diff --git a/src/H5Zprivate.h b/src/H5Zprivate.h index c1528b3..6c0a46f 100644 --- a/src/H5Zprivate.h +++ b/src/H5Zprivate.h @@ -91,7 +91,9 @@ H5_DLL herr_t H5Z_can_apply_direct(const struct H5O_pline_t *pline); H5_DLL herr_t H5Z_set_local_direct(const struct H5O_pline_t *pline); H5_DLL H5Z_filter_info_t *H5Z_filter_info(const struct H5O_pline_t *pline, H5Z_filter_t filter); +H5_DLL htri_t H5Z_filter_in_pline(const struct H5O_pline_t *pline, H5Z_filter_t filter); H5_DLL htri_t H5Z_all_filters_avail(const struct H5O_pline_t *pline); +H5_DLL htri_t H5Z_filter_avail(H5Z_filter_t id); H5_DLL herr_t H5Z_delete(struct H5O_pline_t *pline, H5Z_filter_t filter); /* Data Transform Functions */ diff --git a/src/H5Zpublic.h b/src/H5Zpublic.h index 5d9b5ed..8daa5f4 100644 --- a/src/H5Zpublic.h +++ b/src/H5Zpublic.h @@ -42,6 +42,7 @@ typedef int H5Z_filter_t; #define H5Z_FILTER_NBIT 5 /*nbit compression */ #define H5Z_FILTER_SCALEOFFSET 6 /*scale+offset compression */ #define H5Z_FILTER_RESERVED 256 /*filter ids below this value are reserved for library use */ + #define H5Z_FILTER_MAX 65535 /*maximum filter id */ /* General macros */ diff --git a/src/H5config.h.in b/src/H5config.h.in index d9016dc..8c57b62 100644 --- a/src/H5config.h.in +++ b/src/H5config.h.in @@ -90,6 +90,9 @@ /* Define if the direct I/O virtual file driver should be compiled */ #undef HAVE_DIRECT +/* Define to 1 if you have the <dirent.h> header file. */ +#undef HAVE_DIRENT_H + /* Define to 1 if you have the <dlfcn.h> header file. */ #undef HAVE_DLFCN_H @@ -190,6 +193,9 @@ /* Define to 1 if you have the <io.h> header file. */ #undef HAVE_IO_H +/* Define to 1 if you have the `dl' library (-ldl). */ +#undef HAVE_LIBDL + /* Define to 1 if you have the `dmalloc' library (-ldmalloc). */ #undef HAVE_LIBDMALLOC diff --git a/src/H5err.txt b/src/H5err.txt index ab3277f..5a38cdf 100644 --- a/src/H5err.txt +++ b/src/H5err.txt @@ -76,6 +76,7 @@ MAJOR, H5E_FSPACE, Free Space Manager MAJOR, H5E_SOHM, Shared Object Header Messages MAJOR, H5E_EARRAY, Extensible Array MAJOR, H5E_FARRAY, Fixed Array +MAJOR, H5E_PLUGIN, Plugin for dynamically loaded library MAJOR, H5E_NONE_MAJOR, No error # Sections (for grouping minor errors) @@ -98,6 +99,7 @@ SECTION, HEAP, Heap errors SECTION, FSPACE, Free space errors SECTION, PIPELINE, I/O pipeline errors SECTION, SYSTEM, System level errors +SECTION, PLUGIN, Plugin errors SECTION, NONE, No error # Minor errors @@ -258,5 +260,8 @@ MINOR, PIPELINE, H5E_CANTFILTER, Filter operation failed # System level errors MINOR, SYSTEM, H5E_SYSERRSTR, System error message +# Plugin errors +MINOR, PLUGIN, H5E_OPENERROR, Can't open directory or file + # No error, for backward compatibility */ MINOR, NONE, H5E_NONE_MINOR, No error diff --git a/src/H5private.h b/src/H5private.h index 46c02e7..b4db8c5 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -149,6 +149,17 @@ # include <io.h> #endif +/* + * Dynamic library handling. These are needed for dynamically loading I/O + * filters and VFDs. + */ +#ifdef H5_HAVE_DLFCN_H +#include <dlfcn.h> +#endif +#ifdef H5_HAVE_DIRENT_H +#include <dirent.h> +#endif + #ifdef H5_HAVE_WIN32_API /* The following two defines must be before any windows headers are included */ @@ -2352,6 +2363,7 @@ H5_DLL int H5G_term_interface(void); H5_DLL int H5I_term_interface(void); H5_DLL int H5L_term_interface(void); H5_DLL int H5P_term_interface(void); +H5_DLL int H5PL_term_interface(void); H5_DLL int H5R_term_interface(void); H5_DLL int H5S_term_interface(void); H5_DLL int H5T_term_interface(void); diff --git a/src/H5public.h b/src/H5public.h index deb4587..88d8984 100644 --- a/src/H5public.h +++ b/src/H5public.h @@ -75,10 +75,10 @@ extern "C" { /* Version numbers */ #define H5_VERS_MAJOR 1 /* For major interface/format changes */ #define H5_VERS_MINOR 9 /* For minor interface/format changes */ -#define H5_VERS_RELEASE 149 /* For tweaks, bug-fixes, or development */ +#define H5_VERS_RELEASE 151 /* For tweaks, bug-fixes, or development */ #define H5_VERS_SUBRELEASE "" /* For pre-releases like snap0 */ /* Empty string for real releases. */ -#define H5_VERS_INFO "HDF5 library version: 1.9.149" /* Full version string */ +#define H5_VERS_INFO "HDF5 library version: 1.9.151" /* Full version string */ #define H5check() H5check_version(H5_VERS_MAJOR,H5_VERS_MINOR, \ H5_VERS_RELEASE) diff --git a/src/Makefile.am b/src/Makefile.am index 47bdb61..8220df4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -91,6 +91,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5Pfapl.c H5Pfcpl.c H5Pfmpl.c \ H5Pgcpl.c H5Pint.c \ H5Plapl.c H5Plcpl.c H5Pocpl.c H5Pocpypl.c H5Pstrcpl.c H5Ptest.c \ + H5PL.c \ H5R.c H5Rdeprec.c \ H5RC.c \ H5RS.c \ @@ -119,7 +120,9 @@ include_HEADERS = hdf5.h H5api_adpt.h H5overflow.h H5pubconf.h H5public.h H5vers H5FDmulti.h H5FDsec2.h H5FDstdio.h \ H5VLpublic.h H5VLnative.h \ H5Gpublic.h H5Ipublic.h H5Lpublic.h \ - H5MMpublic.h H5Opublic.h H5Ppublic.h H5Rpublic.h H5Spublic.h \ + H5MMpublic.h H5Opublic.h H5Ppublic.h \ + H5PLextern.h \ + H5Rpublic.h H5Spublic.h \ H5Tpublic.h H5Zpublic.h # install libhdf5.settings in lib directory diff --git a/src/Makefile.in b/src/Makefile.in index d04c4e1..4cf6542 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -161,18 +161,18 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \ H5P.lo H5Pacpl.lo H5Pdapl.lo H5Pdcpl.lo H5Pdeprec.lo \ H5Pdxpl.lo H5Pencdec.lo H5Pfapl.lo H5Pfcpl.lo H5Pfmpl.lo \ H5Pgcpl.lo H5Pint.lo H5Plapl.lo H5Plcpl.lo H5Pocpl.lo \ - H5Pocpypl.lo H5Pstrcpl.lo H5Ptest.lo H5R.lo H5Rdeprec.lo \ - H5RC.lo H5RS.lo H5S.lo H5Sall.lo H5Sdbg.lo H5Shyper.lo \ - H5Smpio.lo H5Snone.lo H5Spoint.lo H5Sselect.lo H5Stest.lo \ - H5SL.lo H5SM.lo H5SMbtree2.lo H5SMcache.lo H5SMmessage.lo \ - H5SMtest.lo H5ST.lo H5T.lo H5Tarray.lo H5Tbit.lo H5Tcommit.lo \ - H5Tcompound.lo H5Tconv.lo H5Tcset.lo H5Tdbg.lo H5Tdeprec.lo \ - H5Tenum.lo H5Tfields.lo H5Tfixed.lo H5Tfloat.lo H5Tinit.lo \ - H5Tnative.lo H5Toffset.lo H5Toh.lo H5Topaque.lo H5Torder.lo \ - H5Tpad.lo H5Tprecis.lo H5Tstrpad.lo H5Tvisit.lo H5Tvlen.lo \ - H5TS.lo H5V.lo H5WB.lo H5Z.lo H5Zdeflate.lo H5Zfletcher32.lo \ - H5Znbit.lo H5Zshuffle.lo H5Zszip.lo H5Zscaleoffset.lo \ - H5Ztrans.lo + H5Pocpypl.lo H5Pstrcpl.lo H5Ptest.lo H5PL.lo H5R.lo \ + H5Rdeprec.lo H5RC.lo H5RS.lo H5S.lo H5Sall.lo H5Sdbg.lo \ + H5Shyper.lo H5Smpio.lo H5Snone.lo H5Spoint.lo H5Sselect.lo \ + H5Stest.lo H5SL.lo H5SM.lo H5SMbtree2.lo H5SMcache.lo \ + H5SMmessage.lo H5SMtest.lo H5ST.lo H5T.lo H5Tarray.lo \ + H5Tbit.lo H5Tcommit.lo H5Tcompound.lo H5Tconv.lo H5Tcset.lo \ + H5Tdbg.lo H5Tdeprec.lo H5Tenum.lo H5Tfields.lo H5Tfixed.lo \ + H5Tfloat.lo H5Tinit.lo H5Tnative.lo H5Toffset.lo H5Toh.lo \ + H5Topaque.lo H5Torder.lo H5Tpad.lo H5Tprecis.lo H5Tstrpad.lo \ + H5Tvisit.lo H5Tvlen.lo H5TS.lo H5V.lo H5WB.lo H5Z.lo \ + H5Zdeflate.lo H5Zfletcher32.lo H5Znbit.lo H5Zshuffle.lo \ + H5Zszip.lo H5Zscaleoffset.lo H5Ztrans.lo libhdf5_la_OBJECTS = $(am_libhdf5_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -514,7 +514,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog # Add libtool shared library version numbers to the HDF5 library # See libtool versioning documentation online. LT_VERS_INTERFACE = 6 -LT_VERS_REVISION = 139 +LT_VERS_REVISION = 141 LT_VERS_AGE = 0 H5detect_CFLAGS = -g $(AM_CFLAGS) @@ -580,6 +580,7 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5Pfapl.c H5Pfcpl.c H5Pfmpl.c \ H5Pgcpl.c H5Pint.c \ H5Plapl.c H5Plcpl.c H5Pocpl.c H5Pocpypl.c H5Pstrcpl.c H5Ptest.c \ + H5PL.c \ H5R.c H5Rdeprec.c \ H5RC.c \ H5RS.c \ @@ -608,7 +609,9 @@ include_HEADERS = hdf5.h H5api_adpt.h H5overflow.h H5pubconf.h H5public.h H5vers H5FDmulti.h H5FDsec2.h H5FDstdio.h \ H5VLpublic.h H5VLnative.h \ H5Gpublic.h H5Ipublic.h H5Lpublic.h \ - H5MMpublic.h H5Opublic.h H5Ppublic.h H5Rpublic.h H5Spublic.h \ + H5MMpublic.h H5Opublic.h H5Ppublic.h \ + H5PLextern.h \ + H5Rpublic.h H5Spublic.h \ H5Tpublic.h H5Zpublic.h @@ -930,6 +933,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Otest.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ounknown.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5P.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5PL.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pacpl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pdapl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pdcpl.Plo@am__quote@ |