Пример #1
0
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);
    }
}
Пример #2
0
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);
}