/** * Copyright (C) Mellanox Technologies Ltd. 2001-2019. ALL RIGHTS RESERVED. * * See file LICENSE for terms. */ #ifndef UCS_MODULE_H_ #define UCS_MODULE_H_ #include #include /** * Flags for @ref UCS_MODULE_FRAMEWORK_LOAD */ typedef enum { UCS_MODULE_LOAD_FLAG_NODELETE = UCS_BIT(0), /**< Never unload */ UCS_MODULE_LOAD_FLAG_GLOBAL = UCS_BIT(1) /**< Load to global scope */ } ucs_module_load_flags_t; /** * Declare a "framework", which is a context for a specific collection of * loadable modules. Usually the modules in a particular framework provide * alternative implementations of the same internal interface. * * @param [in] _name Framework name (as a token) */ #define UCS_MODULE_FRAMEWORK_DECLARE(_name) \ static ucs_init_once_t ucs_framework_init_once_##_name = \ UCS_INIT_ONCE_INITIALIZER /** * Load all modules in a particular framework. * * @param [in] _name Framework name, same as passed to * @ref UCS_MODULE_FRAMEWORK_DECLARE * @param [in] _flags Modules load flags, see @ref ucs_module_load_flags_t * * The modules in the framework are loaded by dlopen(). The shared library name * of a module is: "lib_.so.", where: * - is the framework name * - is the module name. The list of all modules in a framework is * defined by the preprocessor macro _MODULES in the auto-generated * config.h file, for example: #define foo_MODULES ":bar1:bar2". * - is the shared library version of the module, as generated by * libtool. It's extracted from the full path of the current library (libucs). * * Module shared libraries are searched in the following locations (in order of * priority): * 1. 'ucx' sub-directory inside the directory of the current shared library (libucs) * 2. ${libdir}/ucx, where ${libdir} is the directory where libraries are installed * Note that if libucs is loaded from its installation path, (1) and (2) are the * same location. Only if libucs is moved or ran from build directory, the paths * will be different, in which case we prefer the 'local' library rather than the * 'installed' one. * * @param [in] _name Framework name (as a token) */ #define UCS_MODULE_FRAMEWORK_LOAD(_name, _flags) \ ucs_load_modules(#_name, _name##_MODULES, &ucs_framework_init_once_##_name, \ _flags) /** * Define a function to be called when a module is loaded. * Some things can't be done in shared library constructor, and need to be done * only after dlopen() completes. For example, loading another shared library * which uses symbols from the current module. * * Usage: * UCS_MODULE_INIT() { ... code ... } */ #define UCS_MODULE_INIT() \ ucs_status_t __attribute__((visibility("protected"))) \ UCS_MODULE_CONSTRUCTOR_NAME(void) /** * Define the name of a loadable module global constructor */ #define UCS_MODULE_CONSTRUCTOR_NAME \ ucs_module_global_init /** * Internal function. Please use @ref UCS_MODULE_FRAMEWORK_LOAD macro instead. */ void ucs_load_modules(const char *framework, const char *modules, ucs_init_once_t *init_once, unsigned flags); #endif