summaryrefslogtreecommitdiffstats
path: root/src/H5PLint.c
diff options
context:
space:
mode:
authorDana Robinson <derobins@hdfgroup.org>2017-07-14 16:18:33 (GMT)
committerDana Robinson <derobins@hdfgroup.org>2017-07-14 16:18:33 (GMT)
commitd4234d0a98ff68eb55b3fa0d2246e61e53308e41 (patch)
tree64b4a153f36c7fbeaf7e160f1b614e9f0aca9ef0 /src/H5PLint.c
parent26390d02df919476ff3d293293dacbcaba9a4c24 (diff)
downloadhdf5-d4234d0a98ff68eb55b3fa0d2246e61e53308e41.zip
hdf5-d4234d0a98ff68eb55b3fa0d2246e61e53308e41.tar.gz
hdf5-d4234d0a98ff68eb55b3fa0d2246e61e53308e41.tar.bz2
Major rework of H5PL package code before bringing VOL changes
over. Brings coding standards in line with the rest of the library, enforces better software engineering principles, and makes everything more maintainable.
Diffstat (limited to 'src/H5PLint.c')
-rw-r--r--src/H5PLint.c381
1 files changed, 381 insertions, 0 deletions
diff --git a/src/H5PLint.c b/src/H5PLint.c
new file mode 100644
index 0000000..bd6bf7d
--- /dev/null
+++ b/src/H5PLint.c
@@ -0,0 +1,381 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the COPYING file, which can be found at the root of the source code *
+ * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
+ * If you do not have access to either file, you may request a copy from *
+ * help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Purpose: Internal routines for managing plugins.
+ *
+ */
+
+
+/****************/
+/* Module Setup */
+/****************/
+
+#include "H5PLmodule.h" /* This source code file is part of the H5PL module */
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5PLpkg.h" /* Plugin */
+#include "H5Zprivate.h" /* Filter pipeline */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+/* Package initialization variable */
+hbool_t H5_PKG_INIT_VAR = FALSE;
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Bitmask that controls whether classes of plugins
+ * (e.g.: filters, VOL drivers) can be loaded.
+ */
+static unsigned int H5PL_plugin_control_mask_g = H5PL_ALL_PLUGIN;
+
+/* This flag will be set to FALSE if the HDF5_PLUGIN_PRELOAD
+ * environment variable was set to H5PL_NO_PLUGIN at
+ * package initialization.
+ */
+static hbool_t H5PL_allow_plugins_g = TRUE;
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL__get_plugin_control_mask
+ *
+ * Purpose: Gets the internal plugin control mask value.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5PL__get_plugin_control_mask(unsigned int *mask /*out*/)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE_NOERR
+
+ /* Check args - Just assert on package functions */
+ HDassert(mask);
+
+ /* Return the mask */
+ *mask = H5PL_plugin_control_mask_g;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+
+} /* end H5PL__get_plugin_control_mask() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL__set_plugin_control_mask
+ *
+ * Purpose: Sets the internal plugin control mask value.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5PL__set_plugin_control_mask(unsigned int mask)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE_NOERR
+
+ /* Only allow setting this if plugins have not been disabled.
+ * XXX: Note that we don't consider this an error, but instead
+ * silently ignore it. We may want to consider this behavior
+ * more carefully.
+ */
+ if (H5PL_allow_plugins_g)
+ H5PL_plugin_control_mask_g = mask;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+
+} /* end H5PL__set_plugin_control_mask() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL__init_package
+ *
+ * Purpose: Initialize any package-specific data and call any init
+ * routines for the package.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5PL__init_package(void)
+{
+ char *env_var = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_PACKAGE
+
+ /* Check the environment variable to determine if the user wants
+ * to ignore plugins. The special symbol H5PL_NO_PLUGIN (defined in
+ * H5PLpublic.h) means we don't want to load plugins.
+ */
+ if (NULL != (env_var = HDgetenv("HDF5_PLUGIN_PRELOAD")))
+ if (!HDstrcmp(env_var, H5PL_NO_PLUGIN)) {
+ H5PL_plugin_control_mask_g = 0;
+ H5PL_allow_plugins_g = FALSE;
+ }
+
+ /* Create the table of previously-loaded plugins */
+ if (H5PL__create_plugin_cache() < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTINIT, FAIL, "can't create plugin cache")
+
+ /* Create the table of search paths for dynamic libraries */
+ if (H5PL__create_path_table() < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTINIT, FAIL, "can't create plugin search path table")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5PL__init_package() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL_term_package
+ *
+ * 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
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5PL_term_package(void)
+{
+ hbool_t already_closed = FALSE;
+ int ret_value = 0;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if (H5_PKG_INIT_VAR) {
+
+ /* Close the plugin cache.
+ * We need to bump the return value if we did any real work here.
+ */
+ if (H5PL__close_plugin_cache(&already_closed) < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTFREE, (-1), "problem closing plugin cache")
+ if (!already_closed)
+ ret_value++;
+
+ /* Close the search path table and free the paths */
+ if (H5PL__close_path_table() < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTFREE, (-1), "problem closing search path table")
+
+ /* Mark the interface as uninitialized */
+ if (0 == ret_value)
+ H5_PKG_INIT_VAR = FALSE;
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5PL_term_package() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL_load
+ *
+ * Purpose: Given the plugin type and identifier, this function searches
+ * for and, if found, loads a dynamic plugin library.
+ *
+ * The function searches first in the cached plugins and then
+ * in the paths listed in the path table.
+ *
+ * Return: Success: A pointer to the plugin info
+ * Failure: NULL
+ *
+ *-------------------------------------------------------------------------
+ */
+const void *
+H5PL_load(H5PL_type_t type, int id)
+{
+ H5PL_search_params_t search_params;
+ hbool_t found = FALSE; /* Whether the plugin was found */
+ const void *plugin_info = NULL;
+ const void *ret_value = NULL;
+
+ FUNC_ENTER_NOAPI(NULL)
+
+ /* Check if plugins can be loaded for this plugin type */
+ switch (type) {
+ case H5PL_TYPE_FILTER:
+ if ((H5PL_plugin_control_mask_g & H5PL_FILTER_PLUGIN) == 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTLOAD, NULL, "required dynamically loaded plugin filter '%d' is not available", id)
+ break;
+
+ case H5PL_TYPE_ERROR:
+ case H5PL_TYPE_NONE:
+ default:
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTLOAD, NULL, "required dynamically loaded plugin '%d' is not valid", id)
+ }
+
+ /* Set up the search parameters */
+ search_params.type = type;
+ search_params.id = id;
+
+ /* Search in the table of already loaded plugin libraries */
+ if(H5PL__find_plugin_in_cache(&search_params, &found, &plugin_info) < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, NULL, "search in plugin cache failed")
+
+ /* If not found, try iterating through the path table to find an appropriate plugin */
+ if (!found)
+ if (H5PL__find_plugin_in_path_table(&search_params, &found, &plugin_info) < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, NULL, "search in path table failed")
+
+ /* Set the return value we found the plugin */
+ if (found)
+ ret_value = plugin_info;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5PL_load() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL__open
+ *
+ * Purpose: Opens a plugin.
+ *
+ * The success parameter will be set to TRUE and the plugin_info
+ * parameter will be filled in on success. Otherwise, they
+ * will be FALSE and NULL, respectively.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5PL__open(const char *path, H5PL_type_t type, int id, hbool_t *success, const void **plugin_info)
+{
+ H5PL_HANDLE handle = NULL;
+ H5PL_get_plugin_info_t get_plugin_info = NULL;
+ htri_t ret_value = SUCCEED;
+
+ FUNC_ENTER_PACKAGE
+
+ /* Check args - Just assert on package functions */
+ HDassert(path);
+ HDassert(success);
+ HDassert(plugin_info);
+
+ /* Initialize out parameters */
+ *success = FALSE;
+ *plugin_info = NULL;
+
+ /* There are different reasons why a library can't be open, e.g. wrong architecture.
+ * If we can't open the library, just return.
+ */
+ if (NULL == (handle = H5PL_OPEN_DLIB(path))) {
+ H5PL_CLR_ERROR; /* clear error */
+ HGOTO_DONE(SUCCEED);
+ }
+
+
+ /* Return a handle for the function H5PLget_plugin_info in the dynamic library.
+ * The plugin library is suppose to define this function.
+ *
+ * NOTE: We turn off -Wpedantic in gcc to quiet a warning about converting
+ * object pointers to function pointers, which is undefined in ANSI C.
+ * This is basically unavoidable due to the nature of dlsym() and *is*
+ * defined in POSIX, so it's fine.
+ */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpedantic"
+ if (NULL != (get_plugin_info = (H5PL_get_plugin_info_t)H5PL_GET_LIB_FUNC(handle, "H5PLget_plugin_info"))) {
+#pragma GCC diagnostic pop
+
+ const H5Z_class2_t *info;
+
+ /* Get the plugin info */
+ if (NULL == (info = (const H5Z_class2_t *)(*get_plugin_info)()))
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "can't get plugin info")
+
+ /* Check if the filter IDs match */
+ if (info->id == id) {
+
+ /* Store the plugin in the cache */
+ if (H5PL__add_plugin(type, id, handle))
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTINSERT, FAIL, "unable to add new plugin to plugin cache")
+
+ /* Set output parameters */
+ *success = TRUE;
+ *plugin_info = (const void *)info;
+ }
+ }
+
+done:
+ if (!success && handle)
+ if (H5PL__close(handle) < 0)
+ HDONE_ERROR(H5E_PLUGIN, H5E_CLOSEERROR, FAIL, "can't close dynamic library")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5PL__open() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL__close
+ *
+ * Purpose: Closes the handle for dynamic library
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5PL__close(H5PL_HANDLE handle)
+{
+ FUNC_ENTER_PACKAGE_NOERR
+
+ H5PL_CLOSE_LIB(handle);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5PL__close() */
+