int pmix_mca_base_var_group_finalize (void) { pmix_object_t *object; int size, i; if (pmix_mca_base_var_group_initialized) { size = pmix_pointer_array_get_size(&pmix_mca_base_var_groups); for (i = 0 ; i < size ; ++i) { object = pmix_pointer_array_get_item (&pmix_mca_base_var_groups, i); if (NULL != object) { PMIX_RELEASE(object); } } PMIX_DESTRUCT(&pmix_mca_base_var_groups); PMIX_DESTRUCT(&pmix_mca_base_var_group_index_hash); pmix_mca_base_var_group_count = 0; pmix_mca_base_var_group_initialized = false; } return PMIX_SUCCESS; }
pmix_status_t pmix_bfrop_close(void) { int32_t i; if (!pmix_bfrop_initialized) { return PMIX_SUCCESS; } pmix_bfrop_initialized = false; for (i = 0 ; i < pmix_pointer_array_get_size(&pmix_bfrop_types) ; ++i) { pmix_bfrop_type_info_t *info = (pmix_bfrop_type_info_t*)pmix_pointer_array_get_item(&pmix_bfrop_types, i); if (NULL != info) { pmix_pointer_array_set_item(&pmix_bfrop_types, i, NULL); PMIX_RELEASE(info); } } PMIX_DESTRUCT(&pmix_bfrop_types); return PMIX_SUCCESS; }
int pmix_bfrop_copy(void **dest, void *src, pmix_data_type_t type) { pmix_bfrop_type_info_t *info; /* check for error */ if (NULL == dest) { PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); return PMIX_ERR_BAD_PARAM; } if (NULL == src) { PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); return PMIX_ERR_BAD_PARAM; } /* Lookup the copy function for this type and call it */ if (NULL == (info = (pmix_bfrop_type_info_t*)pmix_pointer_array_get_item(&pmix_bfrop_types, type))) { PMIX_ERROR_LOG(PMIX_ERR_UNKNOWN_DATA_TYPE); return PMIX_ERR_UNKNOWN_DATA_TYPE; } return info->odti_copy_fn(dest, src, type); }
/* lookup an errhandler during registration */ pmix_status_t pmix_lookup_errhandler(pmix_info_t info[], size_t ninfo, int *index) { int i, idflt=-1, igrp=-1; pmix_error_reg_info_t *errreg; size_t sz, n; bool exact_given = false; int given = -1; pmix_status_t status; /* scan the incoming specification to see if it is a general errhandler, * a group errhandler, or an error handler for a specific status. Only * one of these options can be specified! */ if (NULL == info) { /* this is the general error handler */ given = 0; } else { for (n=0; n < ninfo; n++) { if (0 == strncmp(info[n].key, PMIX_ERROR_NAME, PMIX_MAX_KEYLEN)) { /* this is a specific errhandler */ given = 1; status = info[n].value.data.integer; break; } else if (0 == strcmp(info[n].key, "pmix.errgroup")) { /* this is a group errhandler */ given = 2; break; } } } /* search our array of errhandlers for a match */ for (i = 0; i < pmix_globals.errregs.size ; i++) { errreg = (pmix_error_reg_info_t*)pmix_pointer_array_get_item(&pmix_globals.errregs, i); if (NULL == errreg) { continue; } if (NULL == errreg->info) { /* this is the general errhandler - if they gave us * another general errhandler, then we should * replace it */ if (0 == given) { *index = i; return PMIX_ERR_DFLT_FOUND; } /* save this spot as we will default to it if nothing else is found */ idflt = i; continue; } if (0 == given) { /* they are looking for the general errhandler */ continue; } /* if this registration is for a single specific errhandler, then * see if the incoming one matches */ if (1 == given && errreg->sglhdlr) { for (sz=0; sz < errreg->ninfo; sz++) { if (0 == strncmp(errreg->info[sz].key, PMIX_ERROR_NAME, PMIX_MAX_KEYLEN)) { if (status == errreg->info[sz].value.data.integer) { /* we have an exact match - return this errhandler and * let the caller know it was an exact match */ *index = i; return PMIX_EXISTS; } } } } else if (2 == given && !errreg->sglhdlr) { /* this registration is for a group, so check that case */ } } /* if we get here, then no match was found. If they * gave us a specific error, then we have to return not_found */ if (exact_given) { return PMIX_ERR_NOT_FOUND; } /* If we have a group match, then that takes precedence */ if (0 <= igrp) { *index = igrp; return PMIX_ERR_GRP_FOUND; } /* if we found a default errhandler, then use it */ if (0 <= idflt) { *index = idflt; return PMIX_ERR_DFLT_FOUND; } /* otherwise, it wasn't found */ return PMIX_ERR_NOT_FOUND; }
void pmix_errhandler_invoke(pmix_status_t status, pmix_proc_t procs[], size_t nprocs, pmix_info_t info[], size_t ninfo) { /* We need to parse thru each registered handler and determine * which one to call for the specific error */ int i, idflt; size_t j, k; bool fired = false; bool exact_match; pmix_error_reg_info_t *errreg, *errdflt=NULL; pmix_info_t *iptr; /* we will need to provide the errhandler reference id when * we provide the callback. Since the callback function doesn't * provide a param for that purpose, we have to add it to any * info array that came from the RM, so extend the array by 1 */ PMIX_INFO_CREATE(iptr, ninfo+1); /* put the reference id in the first location */ (void)strncpy(iptr[0].key, PMIX_ERROR_HANDLER_ID, PMIX_MAX_KEYLEN); iptr[0].value.type = PMIX_INT; /* we don't know the reference id yet, but we'll fill that in * later - for now, just copy the incoming info array across */ if (NULL != info) { for (j=0; j < ninfo; j++) { PMIX_INFO_LOAD(&iptr[j+1], info[j].key, &info[j].value.data, info[j].value.type); } } /* search our array of errhandlers for a match. We take any specific * error status first, then take the group of the incoming status next. * If neither of those have been registered, then use any default * errhandler - otherwise, ignore it */ for (i = 0; i < pmix_globals.errregs.size; i++) { if (NULL == (errreg = (pmix_error_reg_info_t*) pmix_pointer_array_get_item(&pmix_globals.errregs, i))) { continue; } if (NULL == errreg->info || 0 == errreg->ninfo) { // this is a general err handler - we will call it if there is no better match errdflt = errreg; idflt = i; continue; } iptr[0].value.data.integer = i; /* match error name key first */ exact_match = false; for (j = 0; j < errreg->ninfo; j++) { if ((0 == strcmp(errreg->info[j].key, PMIX_ERROR_NAME)) && (status == errreg->info[j].value.data.int32)) { iptr[0].value.data.integer = i; errreg->errhandler(status, procs, nprocs, iptr, ninfo+1); fired = true; exact_match = true; break; } } if (!exact_match && NULL != info) { /* if no exact match was found, then we will fire the errhandler * for any matching info key. This may be too lax and need to be adjusted * later */ for (k = 0; k < errreg->ninfo; k++) { if ((0 == strcmp(errreg->info[j].key, info[k].key)) && (pmix_value_cmp(&errreg->info[j].value, &info[k].value))) { errreg->errhandler(status, procs, nprocs, iptr, ninfo+1); fired = true; } } } } /* if nothing fired and we found a general err handler, then fire it */ if (!fired && NULL != errdflt) { iptr[0].value.data.integer = idflt; errdflt->errhandler(status, procs, nprocs, iptr, ninfo+1); } /* cleanup */ PMIX_INFO_FREE(iptr, ninfo+1); }
static pmix_peer_t* find_peer(const pmix_proc_t *proc) { pmix_status_t rc; pmix_peer_t *peer; pmix_proc_t wildcard; pmix_value_t *value; int i; if (NULL == proc ) { return pmix_globals.mypeer; } /* if the target is someone in my nspace, then use my own peer */ if (0 == strncmp(proc->nspace, pmix_globals.myid.nspace, PMIX_MAX_NSLEN)) { return pmix_globals.mypeer; } if (PMIX_PROC_IS_SERVER(pmix_globals.mypeer)) { /* see if we know this proc */ for (i=0; i < pmix_server_globals.clients.size; i++) { if (NULL != (peer = (pmix_peer_t*)pmix_pointer_array_get_item(&pmix_server_globals.clients, i))) { continue; } if (0 == strncmp(proc->nspace, peer->nptr->nspace, PMIX_MAX_NSLEN)) { return peer; } } /* didn't find it, so try to get the library version of the target * from the host - the result will be cached, so we will only have * to retrieve it once */ (void)strncpy(wildcard.nspace, proc->nspace, PMIX_MAX_NSLEN); wildcard.rank = PMIX_RANK_WILDCARD; if (PMIX_SUCCESS != (rc = PMIx_Get(&wildcard, PMIX_BFROPS_MODULE, NULL, 0, &value))) { /* couldn't get it - nothing we can do */ return NULL; } /* setup a peer for this nspace */ peer = PMIX_NEW(pmix_peer_t); if (NULL == peer) { PMIX_RELEASE(value); return NULL; } peer->nptr = PMIX_NEW(pmix_nspace_t); if (NULL == peer->nptr) { PMIX_RELEASE(peer); PMIX_RELEASE(value); return NULL; } peer->nptr->nspace = strdup(proc->nspace); /* assign a module to it based on the returned version */ peer->nptr->compat.bfrops = pmix_bfrops_base_assign_module(value->data.string); PMIX_RELEASE(value); if (NULL == peer->nptr->compat.bfrops) { PMIX_RELEASE(peer); return NULL; } /* cache the peer object */ pmix_pointer_array_add(&pmix_server_globals.clients, peer); return peer; } // we are a client or tool /* If the target is for the server, then * pack it using that peer. */ if (0 == strncmp(proc->nspace, pmix_client_globals.myserver->info->pname.nspace, PMIX_MAX_NSLEN)) { return pmix_client_globals.myserver; } /* if the target is another member of my nspace, then * they must be using the same version */ if (0 == strncmp(proc->nspace, pmix_globals.myid.nspace, PMIX_MAX_NSLEN)) { return pmix_globals.mypeer; } /* try to get the library version of this peer - the result will be * cached, so we will only have to retrieve it once */ (void)strncpy(wildcard.nspace, proc->nspace, PMIX_MAX_NSLEN); wildcard.rank = PMIX_RANK_WILDCARD; if (PMIX_SUCCESS != (rc = PMIx_Get(&wildcard, PMIX_BFROPS_MODULE, NULL, 0, &value))) { /* couldn't get it - nothing we can do */ return NULL; } /* setup a peer for this nspace */ peer = PMIX_NEW(pmix_peer_t); if (NULL == peer) { PMIX_RELEASE(value); return NULL; } peer->nptr = PMIX_NEW(pmix_nspace_t); if (NULL == peer->nptr) { PMIX_RELEASE(peer); PMIX_RELEASE(value); return NULL; } peer->nptr->nspace = strdup(proc->nspace); /* assign a module to it based on the returned version */ peer->nptr->compat.bfrops = pmix_bfrops_base_assign_module(value->data.string); PMIX_RELEASE(value); if (NULL == peer->nptr->compat.bfrops) { PMIX_RELEASE(peer); return NULL; } /* need to cache the peer someplace so we can clean it * up later */ return peer; }