root/opal/mca/pmix/pmix4x/pmix/src/mca/base/pmix_mca_base_component_repository.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. clf_constructor
  2. clf_destructor
  3. process_repository_item
  4. file_exists
  5. pmix_mca_base_component_repository_add
  6. pmix_mca_base_component_repository_init
  7. pmix_mca_base_component_repository_get_components
  8. pmix_mca_base_component_repository_release_internal
  9. find_component
  10. pmix_mca_base_component_repository_release
  11. pmix_mca_base_component_repository_retain_component
  12. pmix_mca_base_component_repository_open
  13. pmix_mca_base_component_repository_finalize
  14. ri_constructor
  15. ri_destructor

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
   4  *                         University Research and Technology
   5  *                         Corporation.  All rights reserved.
   6  * Copyright (c) 2004-2005 The University of Tennessee and The University
   7  *                         of Tennessee Research Foundation.  All rights
   8  *                         reserved.
   9  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
  10  *                         University of Stuttgart.  All rights reserved.
  11  * Copyright (c) 2004-2005 The Regents of the University of California.
  12  *                         All rights reserved.
  13  * Copyright (c) 2008-2019 Cisco Systems, Inc.  All rights reserved
  14  * Copyright (c) 2015      Los Alamos National Security, LLC. All rights
  15  *                         reserved.
  16  * Copyright (c) 2015      Research Organization for Information Science
  17  *                         and Technology (RIST). All rights reserved.
  18  * Copyright (c) 2016-2019 Intel, Inc.  All rights reserved.
  19  * $COPYRIGHT$
  20  *
  21  * Additional copyrights may follow
  22  *
  23  * $HEADER$
  24  */
  25 
  26 
  27 #include <src/include/pmix_config.h>
  28 #ifdef HAVE_SYS_TYPES_H
  29 #include <sys/types.h>
  30 #endif
  31 #include <string.h>
  32 #include <stdlib.h>
  33 #include <stdio.h>
  34 #ifdef HAVE_UNISTD_H
  35 #include <unistd.h>
  36 #endif
  37 
  38 #include "src/class/pmix_list.h"
  39 #include "src/mca/mca.h"
  40 #include "src/mca/base/base.h"
  41 #include "src/mca/base/pmix_mca_base_component_repository.h"
  42 #include "src/mca/pdl/base/base.h"
  43 #include "pmix_common.h"
  44 #include "src/class/pmix_hash_table.h"
  45 #include "src/util/basename.h"
  46 #include "src/util/show_help.h"
  47 
  48 #if PMIX_HAVE_PDL_SUPPORT
  49 
  50 /*
  51  * Private types
  52  */
  53 static void ri_constructor(pmix_mca_base_component_repository_item_t *ri);
  54 static void ri_destructor(pmix_mca_base_component_repository_item_t *ri);
  55 PMIX_CLASS_INSTANCE(pmix_mca_base_component_repository_item_t, pmix_list_item_t,
  56                     ri_constructor, ri_destructor);
  57 
  58 #endif /* PMIX_HAVE_PDL_SUPPORT */
  59 
  60 static void clf_constructor(pmix_object_t *obj)
  61 {
  62     pmix_mca_base_failed_component_t *cli = (pmix_mca_base_failed_component_t *) obj;
  63     cli->comp = NULL;
  64     cli->error_msg = NULL;
  65 }
  66 
  67 static void clf_destructor(pmix_object_t *obj)
  68 {
  69     pmix_mca_base_failed_component_t *cli = (pmix_mca_base_failed_component_t *) obj;
  70     cli->comp = NULL;
  71     if( NULL != cli->error_msg ) {
  72         free(cli->error_msg);
  73         cli->error_msg = NULL;
  74     }
  75 }
  76 
  77 PMIX_CLASS_INSTANCE(pmix_mca_base_failed_component_t, pmix_list_item_t,
  78                     clf_constructor, clf_destructor);
  79 
  80 
  81 /*
  82  * Private variables
  83  */
  84 static bool initialized = false;
  85 
  86 
  87 #if PMIX_HAVE_PDL_SUPPORT
  88 
  89 static pmix_hash_table_t pmix_mca_base_component_repository;
  90 
  91 /* two-level macro for stringifying a number */
  92 #define STRINGIFYX(x) #x
  93 #define STRINGIFY(x) STRINGIFYX(x)
  94 
  95 static int process_repository_item (const char *filename, void *data)
  96 {
  97     char name[PMIX_MCA_BASE_MAX_COMPONENT_NAME_LEN + 1];
  98     char type[PMIX_MCA_BASE_MAX_TYPE_NAME_LEN + 1];
  99     pmix_mca_base_component_repository_item_t *ri;
 100     pmix_list_t *component_list;
 101     char *base;
 102     int ret;
 103 
 104     base = pmix_basename (filename);
 105     if (NULL == base) {
 106         return PMIX_ERROR;
 107     }
 108 
 109     /* check if the plugin has the appropriate prefix */
 110     if (0 != strncmp (base, "mca_", 4)) {
 111         free (base);
 112         return PMIX_SUCCESS;
 113     }
 114 
 115     /* read framework and component names. framework names may not include an _
 116      * but component names may */
 117     ret = sscanf(base, "mca_%" STRINGIFY(PMIX_MCA_BASE_MAX_TYPE_NAME_LEN) "[^_]_%"
 118                  STRINGIFY(PMIX_MCA_BASE_MAX_COMPONENT_NAME_LEN) "s", type, name);
 119     if (0 > ret) {
 120         /* does not patch the expected template. skip */
 121         free(base);
 122         return PMIX_SUCCESS;
 123     }
 124 
 125     /* lookup the associated framework list and create if it doesn't already exist */
 126     ret = pmix_hash_table_get_value_ptr(&pmix_mca_base_component_repository, type,
 127                                         strlen (type), (void **) &component_list);
 128     if (PMIX_SUCCESS != ret) {
 129         component_list = PMIX_NEW(pmix_list_t);
 130         if (NULL == component_list) {
 131             free (base);
 132             /* OOM. nothing to do but fail */
 133             return PMIX_ERR_OUT_OF_RESOURCE;
 134         }
 135 
 136         ret = pmix_hash_table_set_value_ptr(&pmix_mca_base_component_repository, type,
 137                                             strlen (type), (void *) component_list);
 138         if (PMIX_SUCCESS != ret) {
 139             free (base);
 140             PMIX_RELEASE(component_list);
 141             return ret;
 142         }
 143     }
 144 
 145     /* check for duplicate components */
 146     PMIX_LIST_FOREACH(ri, component_list, pmix_mca_base_component_repository_item_t) {
 147         if (0 == strcmp (ri->ri_name, name)) {
 148             /* already scanned this component */
 149             free (base);
 150             return PMIX_SUCCESS;
 151         }
 152     }
 153 
 154     ri = PMIX_NEW(pmix_mca_base_component_repository_item_t);
 155     if (NULL == ri) {
 156         free (base);
 157         return PMIX_ERR_OUT_OF_RESOURCE;
 158     }
 159 
 160     ri->ri_base = base;
 161 
 162     ri->ri_path = strdup (filename);
 163     if (NULL == ri->ri_path) {
 164         PMIX_RELEASE(ri);
 165         return PMIX_ERR_OUT_OF_RESOURCE;
 166     }
 167 
 168     /* pmix_strncpy does not guarantee a \0 */
 169     ri->ri_type[PMIX_MCA_BASE_MAX_TYPE_NAME_LEN] = '\0';
 170     pmix_strncpy (ri->ri_type, type, PMIX_MCA_BASE_MAX_TYPE_NAME_LEN);
 171 
 172     ri->ri_name[PMIX_MCA_BASE_MAX_TYPE_NAME_LEN] = '\0';
 173     pmix_strncpy (ri->ri_name, name, PMIX_MCA_BASE_MAX_COMPONENT_NAME_LEN);
 174 
 175     pmix_list_append (component_list, &ri->super);
 176 
 177     return PMIX_SUCCESS;
 178 }
 179 
 180 static int file_exists(const char *filename, const char *ext)
 181 {
 182     char *final;
 183     int ret;
 184 
 185     if (NULL == ext) {
 186         return access (filename, F_OK) == 0;
 187     }
 188 
 189     ret = asprintf(&final, "%s.%s", filename, ext);
 190     if (0 > ret || NULL == final) {
 191         return 0;
 192     }
 193 
 194     ret = access (final, F_OK);
 195     free(final);
 196     return (0 == ret);
 197 }
 198 
 199 #endif /* PMIX_HAVE_PDL_SUPPORT */
 200 
 201 int pmix_mca_base_component_repository_add (const char *path)
 202 {
 203 #if PMIX_HAVE_PDL_SUPPORT
 204     char *path_to_use = NULL, *dir, *ctx;
 205     const char sep[] = {PMIX_ENV_SEP, '\0'};
 206 
 207     if (NULL == path) {
 208         /* nothing to do */
 209         return PMIX_SUCCESS;
 210     }
 211 
 212     path_to_use = strdup (path);
 213 
 214     dir = strtok_r (path_to_use, sep, &ctx);
 215     do {
 216         if ((0 == strcmp(dir, "USER_DEFAULT") || 0 == strcmp(dir, "USR_DEFAULT"))
 217             && NULL != pmix_mca_base_user_default_path) {
 218             dir = pmix_mca_base_user_default_path;
 219         } else if (0 == strcmp(dir, "SYS_DEFAULT") ||
 220                    0 == strcmp(dir, "SYSTEM_DEFAULT")) {
 221             dir = pmix_mca_base_system_default_path;
 222         }
 223 
 224         if (0 != pmix_pdl_foreachfile(dir, process_repository_item, NULL) &&
 225             !(0 == strcmp(dir, pmix_mca_base_system_default_path) || 0 == strcmp(dir, pmix_mca_base_user_default_path))) {
 226             // It is not an error if a directory fails to add (e.g.,
 227             // if it doesn't exist).  But we should warn about it as
 228             // it is something related to "show_load_errors"
 229             pmix_show_help("help-pmix-mca-base.txt",
 230                            "failed to add component dir", true, dir);
 231         }
 232     } while (NULL != (dir = strtok_r (NULL, sep, &ctx)));
 233 
 234     free (path_to_use);
 235 
 236 #endif /* PMIX_HAVE_PDL_SUPPORT */
 237 
 238     return PMIX_SUCCESS;
 239 }
 240 
 241 
 242 /*
 243  * Initialize the repository
 244  */
 245 int pmix_mca_base_component_repository_init(void)
 246 {
 247   /* Setup internal structures */
 248 
 249   if (!initialized) {
 250 #if PMIX_HAVE_PDL_SUPPORT
 251 
 252     /* Initialize the dl framework */
 253     int ret = pmix_mca_base_framework_open(&pmix_pdl_base_framework, 0);
 254     if (PMIX_SUCCESS != ret) {
 255         pmix_output(0, "%s %d:%s failed -- process will likely abort (open the dl framework returned %d instead of PMIX_SUCCESS)\n",
 256                     __FILE__, __LINE__, __func__, ret);
 257         return ret;
 258     }
 259     pmix_pdl_base_select();
 260 
 261     PMIX_CONSTRUCT(&pmix_mca_base_component_repository, pmix_hash_table_t);
 262     ret = pmix_hash_table_init (&pmix_mca_base_component_repository, 128);
 263     if (PMIX_SUCCESS != ret) {
 264         (void) pmix_mca_base_framework_close(&pmix_pdl_base_framework);
 265         return ret;
 266     }
 267 
 268     ret = pmix_mca_base_component_repository_add(pmix_mca_base_component_path);
 269     if (PMIX_SUCCESS != ret) {
 270         PMIX_DESTRUCT(&pmix_mca_base_component_repository);
 271         (void) pmix_mca_base_framework_close(&pmix_pdl_base_framework);
 272         return ret;
 273     }
 274 #endif
 275 
 276     initialized = true;
 277   }
 278 
 279   /* All done */
 280 
 281   return PMIX_SUCCESS;
 282 }
 283 
 284 int pmix_mca_base_component_repository_get_components (pmix_mca_base_framework_t *framework,
 285                                                        pmix_list_t **framework_components)
 286 {
 287     *framework_components = NULL;
 288 #if PMIX_HAVE_PDL_SUPPORT
 289     return pmix_hash_table_get_value_ptr (&pmix_mca_base_component_repository, framework->framework_name,
 290                                           strlen (framework->framework_name), (void **) framework_components);
 291 #endif
 292     return PMIX_ERR_NOT_FOUND;
 293 }
 294 
 295 #if PMIX_HAVE_PDL_SUPPORT
 296 static void pmix_mca_base_component_repository_release_internal(pmix_mca_base_component_repository_item_t *ri) {
 297     int group_id;
 298 
 299     group_id = pmix_mca_base_var_group_find (NULL, ri->ri_type, ri->ri_name);
 300     if (0 <= group_id) {
 301         /* ensure all variables are deregistered before we dlclose the component */
 302         pmix_mca_base_var_group_deregister (group_id);
 303     }
 304 
 305     /* Close the component (and potentially unload it from memory */
 306     if (ri->ri_dlhandle) {
 307         pmix_pdl_close(ri->ri_dlhandle);
 308         ri->ri_dlhandle = NULL;
 309     }
 310 }
 311 #endif
 312 
 313 #if PMIX_HAVE_PDL_SUPPORT
 314 static pmix_mca_base_component_repository_item_t *find_component(const char *type, const char *name)
 315 {
 316     pmix_mca_base_component_repository_item_t *ri;
 317     pmix_list_t *component_list;
 318     int ret;
 319 
 320     ret = pmix_hash_table_get_value_ptr (&pmix_mca_base_component_repository, type,
 321                                          strlen (type), (void **) &component_list);
 322     if (PMIX_SUCCESS != ret) {
 323         /* component does not exist in the repository */
 324         return NULL;
 325     }
 326 
 327     PMIX_LIST_FOREACH(ri, component_list, pmix_mca_base_component_repository_item_t) {
 328         if (0 == strcmp (ri->ri_name, name)) {
 329             return ri;
 330         }
 331     }
 332 
 333     return NULL;
 334 }
 335 #endif
 336 
 337 void pmix_mca_base_component_repository_release(const pmix_mca_base_component_t *component)
 338 {
 339 #if PMIX_HAVE_PDL_SUPPORT
 340     pmix_mca_base_component_repository_item_t *ri;
 341 
 342     ri = find_component (component->pmix_mca_type_name, component->pmix_mca_component_name);
 343     if (NULL != ri && !(--ri->ri_refcnt)) {
 344         pmix_mca_base_component_repository_release_internal (ri);
 345     }
 346 #endif
 347 }
 348 
 349 int pmix_mca_base_component_repository_retain_component(const char *type, const char *name)
 350 {
 351 #if PMIX_HAVE_PDL_SUPPORT
 352     pmix_mca_base_component_repository_item_t *ri = find_component(type, name);
 353 
 354     if (NULL != ri) {
 355         ++ri->ri_refcnt;
 356         return PMIX_SUCCESS;
 357     }
 358 
 359     return PMIX_ERR_NOT_FOUND;
 360 #else
 361     return PMIX_ERR_NOT_SUPPORTED;
 362 #endif
 363 }
 364 
 365 int pmix_mca_base_component_repository_open(pmix_mca_base_framework_t *framework,
 366                                             pmix_mca_base_component_repository_item_t *ri)
 367 {
 368 #if PMIX_HAVE_PDL_SUPPORT
 369     pmix_mca_base_component_t *component_struct;
 370     pmix_mca_base_component_list_item_t *mitem = NULL;
 371     char *struct_name = NULL;
 372     int vl, ret;
 373 
 374     pmix_output_verbose(PMIX_MCA_BASE_VERBOSE_INFO, 0, "pmix_mca_base_component_repository_open: examining dynamic "
 375                         "%s MCA component \"%s\" at path %s", ri->ri_type, ri->ri_name, ri->ri_path);
 376 
 377     vl = pmix_mca_base_component_show_load_errors ? PMIX_MCA_BASE_VERBOSE_ERROR : PMIX_MCA_BASE_VERBOSE_INFO;
 378 
 379     /* Ensure that this component is not already loaded (should only happen
 380        if it was statically loaded).  It's an error if it's already
 381        loaded because we're evaluating this file -- not this component.
 382        Hence, returning PMIX_ERR_PARAM indicates that the *file* failed
 383        to load, not the component. */
 384 
 385     PMIX_LIST_FOREACH(mitem, &framework->framework_components, pmix_mca_base_component_list_item_t) {
 386         if (0 == strcmp(mitem->cli_component->pmix_mca_component_name, ri->ri_name)) {
 387             pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_INFO, 0, "pmix_mca_base_component_repository_open: already loaded (ignored)");
 388             return PMIX_ERR_BAD_PARAM;
 389         }
 390     }
 391 
 392     /* silence coverity issue (invalid free) */
 393     mitem = NULL;
 394 
 395     if (NULL != ri->ri_dlhandle) {
 396         pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_INFO, 0, "pmix_mca_base_component_repository_open: already loaded. returning cached component");
 397         mitem = PMIX_NEW(pmix_mca_base_component_list_item_t);
 398         if (NULL == mitem) {
 399             return PMIX_ERR_OUT_OF_RESOURCE;
 400         }
 401 
 402         mitem->cli_component = ri->ri_component_struct;
 403         pmix_list_append (&framework->framework_components, &mitem->super);
 404 
 405         return PMIX_SUCCESS;
 406     }
 407 
 408     if (0 != strcmp (ri->ri_type, framework->framework_name)) {
 409         /* shouldn't happen. attempting to open a component belonging to
 410          * another framework. if this happens it is likely a MCA base
 411          * bug so assert */
 412         assert (0);
 413         return PMIX_ERR_NOT_SUPPORTED;
 414     }
 415 
 416     /* Now try to load the component */
 417 
 418     char *err_msg = NULL;
 419     if (PMIX_SUCCESS != pmix_pdl_open(ri->ri_path, true, false, &ri->ri_dlhandle, &err_msg)) {
 420         if (NULL == err_msg) {
 421             err_msg = "pmix_dl_open() error message was NULL!";
 422         }
 423         /* Because libltdl erroneously says "file not found" for any
 424            type of error -- which is especially misleading when the file
 425            is actually there but cannot be opened for some other reason
 426            (e.g., missing symbol) -- do some simple huersitics and if
 427            the file [probably] does exist, print a slightly better error
 428            message. */
 429         if (0 == strcasecmp("file not found", err_msg) &&
 430             (file_exists(ri->ri_path, "lo") ||
 431              file_exists(ri->ri_path, "so") ||
 432              file_exists(ri->ri_path, "dylib") ||
 433              file_exists(ri->ri_path, "dll"))) {
 434             err_msg = "perhaps a missing symbol, or compiled for a different version of Open MPI?";
 435         }
 436         pmix_output_verbose(vl, 0, "pmix_mca_base_component_repository_open: unable to open %s: %s (ignored)",
 437                             ri->ri_base, err_msg);
 438 
 439         if( pmix_mca_base_component_track_load_errors ) {
 440             pmix_mca_base_failed_component_t *f_comp = PMIX_NEW(pmix_mca_base_failed_component_t);
 441             f_comp->comp = ri;
 442             if (0 > asprintf(&(f_comp->error_msg), "%s", err_msg)) {
 443                 PMIX_RELEASE(f_comp);
 444                 return PMIX_ERR_BAD_PARAM;
 445             }
 446             pmix_list_append(&framework->framework_failed_components, &f_comp->super);
 447         }
 448 
 449         return PMIX_ERR_BAD_PARAM;
 450     }
 451 
 452     /* Successfully opened the component; now find the public struct.
 453        Malloc out enough space for it. */
 454 
 455     do {
 456         ret = asprintf (&struct_name, "mca_%s_%s_component", ri->ri_type, ri->ri_name);
 457         if (0 > ret) {
 458             ret = PMIX_ERR_OUT_OF_RESOURCE;
 459             break;
 460         }
 461 
 462         mitem = PMIX_NEW(pmix_mca_base_component_list_item_t);
 463         if (NULL == mitem) {
 464             ret = PMIX_ERR_OUT_OF_RESOURCE;
 465             break;
 466         }
 467 
 468         err_msg = NULL;
 469         ret = pmix_pdl_lookup(ri->ri_dlhandle, struct_name, (void**) &component_struct, &err_msg);
 470         if (PMIX_SUCCESS != ret || NULL == component_struct) {
 471             if (NULL == err_msg) {
 472                 err_msg = "pmix_dl_loookup() error message was NULL!";
 473             }
 474             pmix_output_verbose(vl, 0, "pmix_mca_base_component_repository_open: \"%s\" does not appear to be a valid "
 475                                 "%s MCA dynamic component (ignored): %s. ret %d", ri->ri_base, ri->ri_type, err_msg, ret);
 476 
 477             ret = PMIX_ERR_BAD_PARAM;
 478             break;
 479         }
 480 
 481         /* done with the structure name */
 482         free (struct_name);
 483         struct_name = NULL;
 484 
 485         /* We found the public struct.  Make sure its MCA major.minor
 486            version is the same as ours. TODO -- add checks for project version (from framework) */
 487         if (!(PMIX_MCA_BASE_VERSION_MAJOR == component_struct->pmix_mca_major_version &&
 488               PMIX_MCA_BASE_VERSION_MINOR == component_struct->pmix_mca_minor_version)) {
 489             pmix_output_verbose(vl, 0, "pmix_mca_base_component_repository_open: %s \"%s\" uses an MCA interface that is "
 490                                 "not recognized (component MCA v%d.%d.%d != supported MCA v%d.%d.%d) -- ignored",
 491                                 ri->ri_type, ri->ri_path, component_struct->pmix_mca_major_version,
 492                                 component_struct->pmix_mca_minor_version, component_struct->pmix_mca_release_version,
 493                                 PMIX_MCA_BASE_VERSION_MAJOR, PMIX_MCA_BASE_VERSION_MINOR, PMIX_MCA_BASE_VERSION_RELEASE);
 494             ret = PMIX_ERR_BAD_PARAM;
 495             break;
 496         }
 497 
 498         /* Also check that the component struct framework and component
 499            names match the expected names from the filename */
 500         if (0 != strcmp(component_struct->pmix_mca_type_name, ri->ri_type) ||
 501             0 != strcmp(component_struct->pmix_mca_component_name, ri->ri_name)) {
 502             pmix_output_verbose(vl, 0, "Component file data does not match filename: %s (%s / %s) != %s %s -- ignored",
 503                                 ri->ri_path, ri->ri_type, ri->ri_name,
 504                                 component_struct->pmix_mca_type_name,
 505                                 component_struct->pmix_mca_component_name);
 506             ret = PMIX_ERR_BAD_PARAM;
 507             break;
 508         }
 509 
 510         /* Alles gut.  Save the component struct, and register this
 511            component to be closed later. */
 512 
 513         ri->ri_component_struct = mitem->cli_component = component_struct;
 514         ri->ri_refcnt = 1;
 515         pmix_list_append(&framework->framework_components, &mitem->super);
 516 
 517         pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_INFO, 0, "pmix_mca_base_component_repository_open: opened dynamic %s MCA "
 518                              "component \"%s\"", ri->ri_type, ri->ri_name);
 519 
 520         return PMIX_SUCCESS;
 521     } while (0);
 522 
 523     if (mitem) {
 524         PMIX_RELEASE(mitem);
 525     }
 526 
 527     if (struct_name) {
 528         free (struct_name);
 529     }
 530 
 531     pmix_pdl_close (ri->ri_dlhandle);
 532     ri->ri_dlhandle = NULL;
 533 
 534     return ret;
 535 #else
 536 
 537     /* no dlopen support */
 538     return PMIX_ERR_NOT_SUPPORTED;
 539 #endif
 540 }
 541 
 542 /*
 543  * Finalize the repository -- close everything that's still open.
 544  */
 545 void pmix_mca_base_component_repository_finalize(void)
 546 {
 547     if (!initialized) {
 548         return;
 549     }
 550 
 551     initialized = false;
 552 
 553 #if PMIX_HAVE_PDL_SUPPORT
 554     pmix_list_t *component_list;
 555     void *node, *key;
 556     size_t key_size;
 557     int ret;
 558 
 559     ret = pmix_hash_table_get_first_key_ptr (&pmix_mca_base_component_repository, &key, &key_size,
 560                                              (void **) &component_list, &node);
 561     while (PMIX_SUCCESS == ret) {
 562         PMIX_LIST_RELEASE(component_list);
 563         ret = pmix_hash_table_get_next_key_ptr (&pmix_mca_base_component_repository, &key,
 564                                                 &key_size, (void **) &component_list,
 565                                                 node, &node);
 566     }
 567 
 568     (void) pmix_mca_base_framework_close(&pmix_pdl_base_framework);
 569     PMIX_DESTRUCT(&pmix_mca_base_component_repository);
 570 #endif
 571 }
 572 
 573 #if PMIX_HAVE_PDL_SUPPORT
 574 
 575 /*
 576  * Basic sentinel values, and construct the inner list
 577  */
 578 static void ri_constructor (pmix_mca_base_component_repository_item_t *ri)
 579 {
 580     memset(ri->ri_type, 0, sizeof(ri->ri_type));
 581     ri->ri_dlhandle = NULL;
 582     ri->ri_component_struct = NULL;
 583     ri->ri_path = NULL;
 584 }
 585 
 586 
 587 /*
 588  * Close a component
 589  */
 590 static void ri_destructor (pmix_mca_base_component_repository_item_t *ri)
 591 {
 592     /* dlclose the component if it is still open */
 593     pmix_mca_base_component_repository_release_internal (ri);
 594 
 595     /* It should be obvious, but I'll state it anyway because it bit me
 596        during debugging: after the dlclose(), the pmix_mca_base_component_t
 597        pointer is no longer valid because it has [potentially] been
 598        unloaded from memory.  So don't try to use it.  :-) */
 599 
 600     if (ri->ri_path) {
 601         free (ri->ri_path);
 602     }
 603 
 604     if (ri->ri_base) {
 605         free (ri->ri_base);
 606     }
 607 }
 608 
 609 #endif /* PMIX_HAVE_PDL_SUPPORT */

/* [<][>][^][v][top][bottom][index][help] */