1
1
openmpi/test/support/components.c
Jeff Squyres 3962c53e2e - Add to AM_CPPFLAGS $(OPAL_LTDL_CPPFLAGS) where necessary in order to
add a -I to find the included ltdl.h (vs. a system-installed ltdl.h)
- Clean up kruft in a bunch of Makefile.am's to remove now-unnecessary
  AM_CPPFLAGS settings to get static-components.h for each framework
- Move the component_repository API functions out of opal/mca/base/base.h
  and into opal/mca/base/mca_base_component_repository.h in order to
  decrease unnecessary dependencies (e.g., before this, almost
  everything in the tree depended on ltdl.h, which is unnecessary --
  only a small number of files really need ltdl.h)

This commit was SVN r7127.
2005-09-01 12:16:36 +00:00

199 строки
5.4 KiB
C

/*
* Copyright (c) 2004-2005 The Trustees of Indiana University.
* All rights reserved.
* Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
* All rights reserved.
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#include "ompi_config.h"
#include <string.h>
#include "ompi/include/constants.h"
#include "opal/include/constants.h"
#include "opal/mca/mca.h"
/* Ensure to get the right <ltdl.h> -- a -I should be setup in this
directory's Makefile.am to get opal/libltdl */
#include "ltdl.h"
#include "components.h"
/*
* Local functions
*/
static bool try_dlopen(const char *dir, const char *fw, const char *comp,
test_component_handle_t *comp_handle,
test_component_sym_t *comp_symbol);
static char *dir_concat(const char *a, const char *b);
int test_component_open(const char *framework, const char *component,
test_component_handle_t *comp_handle,
mca_base_component_t **mca)
{
test_component_sym_t sym;
if (NULL == framework || NULL == component || NULL == comp_handle ||
NULL == mca) {
return OMPI_ERR_BAD_PARAM;
}
comp_handle->tch_handle = NULL;
sym.tcs_variable = NULL;
/* It's ok to call lt_dlinit() multiple times; it ref counts for
lt_dlexit() */
lt_dlinit();
/* Try to open */
if (try_dlopen(".", framework, component, comp_handle, &sym) ||
try_dlopen(dir_concat(BUILDDIR, "src/mca"), framework,
component, comp_handle, &sym) ||
try_dlopen(dir_concat(SRCDIR, "src/mca"), framework,
component, comp_handle, &sym)) {
/* Ok, dlopen'ed it. Now call the component's open
function. */
*mca = (mca_base_component_t*) sym.tcs_variable;
if (NULL == (*mca)->mca_open_component ||
(NULL != (*mca)->mca_open_component &&
OMPI_SUCCESS == (*mca)->mca_open_component())) {
return OMPI_SUCCESS;
}
/* Badness occurred, so dlclose the component */
test_component_close(comp_handle);
}
/* Didn't find it / unable to open it */
return OMPI_ERROR;
}
int test_component_find_symbol(const char *name,
test_component_handle_t *handle,
test_component_sym_t *sym)
{
/* Use a union to avoid pesky compilers that complain [rightfully,
unfortunately] about converting (void*) to a function pointer
-- need to wait until the ltdl library has a lt_dlsymfunc()
function for a real fix... */
union {
void *vvalue;
void (*fvalue)(void);
} value;
if (NULL == handle || NULL == sym) {
return OMPI_ERR_BAD_PARAM;
}
value.vvalue = lt_dlsym(handle->tch_handle, name);
sym->tcs_function = value.fvalue;
return OMPI_SUCCESS;
}
int test_component_close(test_component_handle_t *handle)
{
/* Note that lt_dlinit() refcounts, so ld_dlexit() only actually
shuts down if we've called it as many times as we've called
lt_dlinit() */
if (NULL != handle && NULL != handle->tch_handle) {
lt_dlclose(handle->tch_handle);
lt_dlexit();
handle->tch_handle = NULL;
}
return OMPI_SUCCESS;
}
static bool try_dlopen(const char *dir, const char *fw, const char *comp,
test_component_handle_t *comp_handle,
test_component_sym_t *comp_symbol)
{
char component_name[BUFSIZ];
char file_name[BUFSIZ];
#ifdef WIN32
char dirsep = '\\';
#else
char dirsep = '/';
#endif
component_name[BUFSIZ - 1] = '\0';
snprintf(component_name, BUFSIZ - 1, "mca_%s_%s_component", fw, comp);
if ('\0' != component_name[BUFSIZ - 1]) {
return false;
}
/* First, look for the component symbol statically */
comp_handle->tch_handle = lt_dlopen(NULL);
if (NULL != comp_handle->tch_handle) {
comp_symbol->tcs_variable =
lt_dlsym(comp_handle->tch_handle, component_name);
if (NULL != comp_symbol->tcs_variable) {
return true;
}
lt_dlclose(comp_handle->tch_handle);
}
/* Not in self -- look for a real component */
file_name[BUFSIZ - 1] = '\0';
snprintf(file_name, BUFSIZ - 1, "%s%c%s%c%s%cmca_%s_%s", dir, dirsep,
fw, dirsep, comp, dirsep, fw, comp);
if ('\0' != file_name[BUFSIZ - 1]) {
return false;
}
comp_handle->tch_handle = lt_dlopenext(file_name);
if (NULL != comp_handle->tch_handle) {
comp_symbol->tcs_variable =
lt_dlsym(comp_handle->tch_handle, component_name);
if (NULL != comp_symbol->tcs_variable) {
return true;
}
lt_dlclose(comp_handle->tch_handle);
}
/* Nope, didn't find it */
return false;
}
static char *dir_concat(const char *a, const char *b)
{
static char name[BUFSIZ];
name[0] = '\0';
if (NULL != a) {
strcat(name, a);
#ifdef WIN32
strcat(name, "\\");
#else
strcat(name, "/");
#endif
}
if (NULL != b) {
strcat(name, b);
}
return name;
}