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