Blame src/mpi/errhan/file_call_errhandler.c

Packit Service c5cf8c
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
Packit Service c5cf8c
/*
Packit Service c5cf8c
 *  (C) 2001 by Argonne National Laboratory.
Packit Service c5cf8c
 *      See COPYRIGHT in top-level directory.
Packit Service c5cf8c
 */
Packit Service c5cf8c
Packit Service c5cf8c
#include "mpiimpl.h"
Packit Service c5cf8c
#include "mpir_ext.h"
Packit Service c5cf8c
Packit Service c5cf8c
/* -- Begin Profiling Symbol Block for routine MPI_File_call_errhandler */
Packit Service c5cf8c
#if defined(HAVE_PRAGMA_WEAK)
Packit Service c5cf8c
#pragma weak MPI_File_call_errhandler = PMPI_File_call_errhandler
Packit Service c5cf8c
#elif defined(HAVE_PRAGMA_HP_SEC_DEF)
Packit Service c5cf8c
#pragma _HP_SECONDARY_DEF PMPI_File_call_errhandler  MPI_File_call_errhandler
Packit Service c5cf8c
#elif defined(HAVE_PRAGMA_CRI_DUP)
Packit Service c5cf8c
#pragma _CRI duplicate MPI_File_call_errhandler as PMPI_File_call_errhandler
Packit Service c5cf8c
#elif defined(HAVE_WEAK_ATTRIBUTE)
Packit Service c5cf8c
int MPI_File_call_errhandler(MPI_File fh, int errorcode)
Packit Service c5cf8c
    __attribute__ ((weak, alias("PMPI_File_call_errhandler")));
Packit Service c5cf8c
#endif
Packit Service c5cf8c
/* -- End Profiling Symbol Block */
Packit Service c5cf8c
Packit Service c5cf8c
/* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build
Packit Service c5cf8c
   the MPI routines */
Packit Service c5cf8c
#ifndef MPICH_MPI_FROM_PMPI
Packit Service c5cf8c
#undef MPI_File_call_errhandler
Packit Service c5cf8c
#define MPI_File_call_errhandler PMPI_File_call_errhandler
Packit Service c5cf8c
Packit Service c5cf8c
#endif
Packit Service c5cf8c
Packit Service c5cf8c
#undef FUNCNAME
Packit Service c5cf8c
#define FUNCNAME MPI_File_call_errhandler
Packit Service c5cf8c
#undef FCNAME
Packit Service c5cf8c
#define FCNAME "MPI_File_call_errhander"
Packit Service c5cf8c
/*@
Packit Service c5cf8c
   MPI_File_call_errhandler - Call the error handler installed on a
Packit Service c5cf8c
   file
Packit Service c5cf8c
Packit Service c5cf8c
Input Parameters:
Packit Service c5cf8c
+ fh - MPI file with error handler (handle)
Packit Service c5cf8c
- errorcode - error code (integer)
Packit Service c5cf8c
Packit Service c5cf8c
.N ThreadSafeNoUpdate
Packit Service c5cf8c
Packit Service c5cf8c
.N Fortran
Packit Service c5cf8c
Packit Service c5cf8c
.N Errors
Packit Service c5cf8c
.N MPI_SUCCESS
Packit Service c5cf8c
.N MPI_ERR_FILE
Packit Service c5cf8c
@*/
Packit Service c5cf8c
int MPI_File_call_errhandler(MPI_File fh, int errorcode)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int mpi_errno = MPI_SUCCESS;
Packit Service c5cf8c
#ifdef MPI_MODE_RDONLY
Packit Service c5cf8c
    MPIR_Errhandler *e;
Packit Service c5cf8c
    MPI_Errhandler eh;
Packit Service c5cf8c
#endif
Packit Service c5cf8c
    MPIR_FUNC_TERSE_STATE_DECL(MPID_STATE_MPI_FILE_CALL_ERRHANDLER);
Packit Service c5cf8c
Packit Service c5cf8c
    MPIR_ERRTEST_INITIALIZED_ORDIE();
Packit Service c5cf8c
Packit Service c5cf8c
    MPIR_FUNC_TERSE_ENTER(MPID_STATE_MPI_FILE_CALL_ERRHANDLER);
Packit Service c5cf8c
Packit Service c5cf8c
#ifdef MPI_MODE_RDONLY
Packit Service c5cf8c
    /* Validate parameters, especially handles needing to be converted */
Packit Service c5cf8c
    /* FIXME: check for a valid file handle (fh) before converting to a
Packit Service c5cf8c
     * pointer */
Packit Service c5cf8c
Packit Service c5cf8c
    /* ... body of routine ...  */
Packit Service c5cf8c
Packit Service c5cf8c
    MPIR_ROMIO_Get_file_errhand(fh, &eh;;
Packit Service c5cf8c
    /* Check for the special case of errors-throw-exception.  In this case
Packit Service c5cf8c
     * return the error code; the C++ wrapper will cause an exception to
Packit Service c5cf8c
     * be thrown.
Packit Service c5cf8c
     */
Packit Service c5cf8c
#ifdef HAVE_CXX_BINDING
Packit Service c5cf8c
    if (eh == MPIR_ERRORS_THROW_EXCEPTIONS) {
Packit Service c5cf8c
        mpi_errno = errorcode;
Packit Service c5cf8c
        goto fn_exit;
Packit Service c5cf8c
    }
Packit Service c5cf8c
#endif
Packit Service c5cf8c
    if (!eh) {
Packit Service c5cf8c
        MPIR_Errhandler_get_ptr(MPI_ERRORS_RETURN, e);
Packit Service c5cf8c
    } else {
Packit Service c5cf8c
        MPIR_Errhandler_get_ptr(eh, e);
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    /* Note that, unlike the rest of MPICH, MPI_File objects are pointers,
Packit Service c5cf8c
     * not integers.  */
Packit Service c5cf8c
Packit Service c5cf8c
    if (e->handle == MPI_ERRORS_RETURN) {
Packit Service c5cf8c
        goto fn_exit;
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    if (e->handle == MPI_ERRORS_ARE_FATAL) {
Packit Service c5cf8c
        MPIR_Handle_fatal_error(NULL, "MPI_File_call_errhandler", errorcode);
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    switch (e->language) {
Packit Service c5cf8c
        case MPIR_LANG__C:
Packit Service c5cf8c
            (*e->errfn.C_File_Handler_function) (&fh, &errorcode);
Packit Service c5cf8c
            break;
Packit Service c5cf8c
#ifdef HAVE_CXX_BINDING
Packit Service c5cf8c
        case MPIR_LANG__CXX:
Packit Service c5cf8c
            /* See HAVE_LANGUAGE_FORTRAN below for an explanation */
Packit Service c5cf8c
            {
Packit Service c5cf8c
                void *fh1 = (void *) &fh;
Packit Service c5cf8c
                (*MPIR_Process.cxx_call_errfn) (1, fh1, &errorcode,
Packit Service c5cf8c
                                                (void (*)(void)) *e->errfn.C_File_Handler_function);
Packit Service c5cf8c
            }
Packit Service c5cf8c
            break;
Packit Service c5cf8c
#endif
Packit Service c5cf8c
#ifdef HAVE_FORTRAN_BINDING
Packit Service c5cf8c
        case MPIR_LANG__FORTRAN90:
Packit Service c5cf8c
        case MPIR_LANG__FORTRAN:
Packit Service c5cf8c
            /* The assignemt to a local variable prevents the compiler
Packit Service c5cf8c
             * from generating a warning about a type-punned pointer.  Since
Packit Service c5cf8c
             * the value is really const (but MPI didn't define error handlers
Packit Service c5cf8c
             * with const), this preserves the intent */
Packit Service c5cf8c
            {
Packit Service c5cf8c
                void *fh1 = (void *) &fh;
Packit Service c5cf8c
                MPI_Fint ferr = errorcode;      /* Needed if MPI_Fint and int aren't
Packit Service c5cf8c
                                                 * the same size */
Packit Service c5cf8c
                (*e->errfn.F77_Handler_function) (fh1, &ferr);
Packit Service c5cf8c
            }
Packit Service c5cf8c
            break;
Packit Service c5cf8c
#endif
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
#else
Packit Service c5cf8c
    /* Dummy in case ROMIO is not defined */
Packit Service c5cf8c
    mpi_errno = MPI_ERR_INTERN;
Packit Service c5cf8c
#endif
Packit Service c5cf8c
    /* ... end of body of routine ... */
Packit Service c5cf8c
Packit Service c5cf8c
#if defined(HAVE_CXX_BINDING) && defined(MPI_MODE_RDONLY)
Packit Service c5cf8c
  fn_exit:
Packit Service c5cf8c
#else
Packit Service c5cf8c
  fn_exit:
Packit Service c5cf8c
#endif
Packit Service c5cf8c
    MPIR_FUNC_TERSE_EXIT(MPID_STATE_MPI_FILE_CALL_ERRHANDLER);
Packit Service c5cf8c
    return mpi_errno;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
#ifndef MPICH_MPI_FROM_PMPI
Packit Service c5cf8c
/* This is a glue routine that can be used by ROMIO
Packit Service c5cf8c
   (see mpi-io/glue/mpich/mpio_err.c) to properly invoke the C++
Packit Service c5cf8c
   error handler */
Packit Service c5cf8c
#undef FUNCNAME
Packit Service c5cf8c
#define FUNCNAME MPIR_File_call_cxx_errhandler
Packit Service c5cf8c
#undef FCNAME
Packit Service c5cf8c
#define FCNAME MPL_QUOTE(FUNCNAME)
Packit Service c5cf8c
int MPIR_File_call_cxx_errhandler(MPI_File * fh, int *errorcode,
Packit Service c5cf8c
                                  void (*c_errhandler) (MPI_File *, int *, ...))
Packit Service c5cf8c
{
Packit Service c5cf8c
    /* ROMIO will contain a reference to this routine, so if there is
Packit Service c5cf8c
     * no C++ support, it will never be called but it must be availavle. */
Packit Service c5cf8c
#ifdef HAVE_CXX_BINDING
Packit Service c5cf8c
    void *fh1 = (void *) fh;
Packit Service c5cf8c
    (*MPIR_Process.cxx_call_errfn) (1, fh1, errorcode, (void (*)(void)) c_errhandler);
Packit Service c5cf8c
    /* The C++ code throws an exception if the error handler
Packit Service c5cf8c
     * returns something other than MPI_SUCCESS. There is no "return"
Packit Service c5cf8c
     * of an error code. This code mirrors that in errutil.c */
Packit Service c5cf8c
    *errorcode = MPI_SUCCESS;
Packit Service c5cf8c
#endif
Packit Service c5cf8c
    return *errorcode;
Packit Service c5cf8c
}
Packit Service c5cf8c
#endif