1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
|
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2015 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2015 Los Alamos National Security, LLC. All rights
* reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
/**
* @file
*
* Dynamic library framework
*
* General Description:
*
* This framework provides portable access to dlopen- and dlsym-like
* functionality, very similar to Libtool's libltdl. Indeed, one of
* the components in this framework will use libltdl, if it is
* present/available. However, on some common types systems where
* libltdl headers and libraries are *not* available, we can support
* plugins via this simple framework.
*
* This is a compile-time framework: a single component will be
* selected by the priority that its configure.m4 provides. All other
* components will be ignored (i.e., not built/not part of the
* installation). Meaning: the static_components of the dl framework
* will always contain 0 or 1 components.
*
* SIDENOTE: Open MPI used to embed libltdl. However, as of early
* 2015, this became problematic, for a variety of complex and
* uninteresting reasons (see the following if you care about the
* details: https://github.com/open-mpi/ompi/issues/311,
* http://debbugs.gnu.org/cgi/bugreport.cgi?bug=19370,
* https://github.com/open-mpi/ompi/pull/366,
* https://github.com/open-mpi/ompi/pull/390). That being said, we,
* as a developer community, still wanted to be able to natively use
* DSOs by default. A small/simple framework for DL functionality,
* along with a simple component that supports dlopen/dlsym on POSIX
* platforms and another component that natively uses libltdl seemed
* like a good solution.
*/
#ifndef OPAL_MCA_DL_DL_H
#define OPAL_MCA_DL_DL_H
#include "opal_config.h"
#include "opal/mca/base/base.h"
#include "opal/mca/mca.h"
BEGIN_C_DECLS
/**
* Handle for an opened file
*/
struct opal_dl_handle_t;
typedef struct opal_dl_handle_t opal_dl_handle_t;
/**
* Dynamically open the file specified.
*
* Arguments:
* fname = Base filename to open. If NULL, open this process.
* use_ext = If true, try various filename suffixes that are
* relevant on this platform (e.g., .so, .dll, .dylib). If
* false, just use exactly whatever was passed as fname.
* private = If true, open the file in a private namespace.
* Otherwise, open the file in a global namespace.
* handle = Upon successful open, a handle to the opened file will
* be returned.
* err_msg= if non-NULL and !=OPAL_SUCCESS is returned, will point to a
* string error message
*
* Returns:
* OPAL_SUCCESS on success, or OPAL_ERROR
*
* Space for the handle must be allocated by the module (it can be
* freed during the call to opal_dl_base_module_dlclose_fn_t).
*
* The err_msg points to an internal string and should not be altered
* or freed by the caller. The contents of the err_msg string may
* change after successive calls to opal_dl API calls.
*/
typedef int (*opal_dl_base_module_open_fn_t)(const char *fname, bool use_ext,
bool private_namespace, opal_dl_handle_t **handle,
char **err_msg);
/**
* Lookup a symbol in an opened file.
*
* Arguments:
* handle = handle of a previously dynamically opened file
* symbol = name of the symbol to lookup
* ptr = if found, a pointer to the symbol. Otherwise, NULL.
* err_msg= if non-NULL and !=OPAL_SUCCESS is returned, will point to a
* string error message
* Returns:
* OPAL_SUCCESS on success, or OPAL_ERROR
*
*
* The err_msg points to an internal string and should not be altered
* or freed by the caller. The contents of the err_msg string may
* change after successive calls to opal_dl API calls.
*/
typedef int (*opal_dl_base_module_lookup_fn_t)(opal_dl_handle_t *handle, const char *symbol,
void **ptr, char **err_msg);
/**
* Dynamically close a previously dynamically-opened file.
*
* Arguments:
* handle = handle of a previously dynamically opened file.
* Returns:
* OPAL_SUCCESS on success, or OPAL_ERROR
*
* This function should close the file and free and resources
* associated with it (e.g., whatever is cached on the handle).
*/
typedef int (*opal_dl_base_module_close_fn_t)(opal_dl_handle_t *handle);
/**
* Search through a path of directories, invoking a callback on each
* unique regular (non-Libtool) file basename found (e.g., will only
* be invoked once for the files "foo.la" and "foo.so", with the
* parameter "foo").
*
* Arguments:
* path = OPAL_ENV_SEP-delimited list of directories
* cb_func= function to invoke on each filename found
* data = context for callback function
* Returns:
* OPAL_SUCESS on success, OPAL_ERR* otherwise
*/
typedef int (*opal_dl_base_module_foreachfile_fn_t)(
const char *search_path, int (*cb_func)(const char *filename, void *context), void *context);
/**
* Structure for DL components.
*/
struct opal_dl_base_component_1_0_0_t {
/** MCA base component */
mca_base_component_t base_version;
/** MCA base data */
mca_base_component_data_t base_data;
/** Default priority */
int priority;
};
typedef struct opal_dl_base_component_1_0_0_t opal_dl_base_component_1_0_0_t;
typedef struct opal_dl_base_component_1_0_0_t opal_dl_base_component_t;
/**
* Structure for DL modules
*/
struct opal_dl_base_module_1_0_0_t {
mca_base_module_2_0_0_t super;
/** Open / close */
opal_dl_base_module_open_fn_t open;
opal_dl_base_module_close_fn_t close;
/** Lookup a symbol */
opal_dl_base_module_lookup_fn_t lookup;
/** Iterate looking for files */
opal_dl_base_module_foreachfile_fn_t foreachfile;
};
typedef struct opal_dl_base_module_1_0_0_t opal_dl_base_module_1_0_0_t;
typedef struct opal_dl_base_module_1_0_0_t opal_dl_base_module_t;
/**
* Macro for use in components that are of type DL
*/
#define OPAL_DL_BASE_VERSION_1_0_0 OPAL_MCA_BASE_VERSION_2_1_0("dl", 1, 0, 0)
END_C_DECLS
#endif /* OPAL_MCA_DL_DL_H */
|