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 matched_errregs[PMIX_MAX_ERROR_REGISTRATIONS]; int i, nmatched = 0; unsigned int j,k; bool exact_match = false; int allerrhandler_ind = -1; pmix_error_reg_info_t *errreg; for (i = 0; i < pmix_pointer_array_get_size(&pmix_globals.errregs) && !exact_match; i++) { errreg = (pmix_error_reg_info_t*) pmix_pointer_array_get_item (&pmix_globals.errregs, i); if(0 == errreg->ninfo) { // this is a general err handler we will call it if there is no better match allerrhandler_ind = i; } else { /* match error name key first */ for(j = 0; j < errreg->ninfo; j++) { if ((0 == strcmp(errreg->info[j].key, PMIX_ERROR_NAME)) && (status == errreg->info[j].value.data.int32)) { matched_errregs[0] = i; nmatched = 1; exact_match = true; break; } else { 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))) { matched_errregs[nmatched++] = 1; break; } } } } } } for ( i =0 ;i < nmatched; i++) { errreg = (pmix_error_reg_info_t*) pmix_pointer_array_get_item (&pmix_globals.errregs, matched_errregs[i]); errreg->errhandler (status, procs, nprocs, info, ninfo); } if ( 0 == nmatched && 0 <= allerrhandler_ind) { errreg = (pmix_error_reg_info_t*) pmix_pointer_array_get_item (&pmix_globals.errregs, allerrhandler_ind); errreg->errhandler (status, procs, nprocs, info, ninfo); } }
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); }