1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
/*
* Copyright (C) 2004 University of Chicago.
* See COPYRIGHT notice in top-level directory.
*/
#include <stdarg.h>
#include <stdio.h>
#include "mpioimpl.h"
#include "adio_extern.h"
/* MPICH error handling implementation */
/* FIXME: These external prototypes should be included from
mpich/src/include/mpiext.h */
int MPIR_Err_create_code_valist(int, int, const char [], int, int,
const char [], const char [], va_list );
int MPIR_Err_is_fatal(int);
void MPIR_Get_file_error_routine( MPI_Errhandler,
void (**)(MPI_File *, int *, ...),
int * );
int MPIR_File_call_cxx_errhandler( MPI_File *, int *,
void (*)(MPI_File *, int *, ... ) );
typedef int (* MPIR_Err_get_class_string_func_t)(int error, char *str, int length);
void MPIR_Err_get_string( int, char *, int, MPIR_Err_get_class_string_func_t );
struct MPID_Comm;
int MPID_Abort(struct MPID_Comm *comm, int mpi_errno, int exit_code, const char *error_msg);
int MPIO_Err_create_code(int lastcode, int fatal, const char fcname[],
int line, int error_class, const char generic_msg[],
const char specific_msg[], ... )
{
va_list Argp;
int error_code;
va_start(Argp, specific_msg);
error_code = MPIR_Err_create_code_valist(lastcode, fatal, fcname, line,
error_class, generic_msg,
specific_msg, Argp);
va_end(Argp);
return error_code;
}
int MPIO_Err_return_file(MPI_File mpi_fh, int error_code)
{
MPI_Errhandler e;
void (*c_errhandler)(MPI_File *, int *, ... );
int kind; /* Error handler kind (see below) */
char error_msg[4096];
int len;
/* If the file pointer is not valid, we use the handler on
MPI_FILE_NULL (MPI-2, section 9.7). For now, this code assumes that
MPI_FILE_NULL has the default handler (return). FIXME. See
below - the set error handler uses ADIOI_DFLT_ERR_HANDLER;
*/
/* First, get the handler and the corresponding function */
if (mpi_fh == MPI_FILE_NULL) {
e = ADIOI_DFLT_ERR_HANDLER;
}
else {
ADIO_File fh;
fh = MPIO_File_resolve(mpi_fh);
e = fh->err_handler;
}
/* Actually, e is just the value provide by the MPICH routines
file_set_errhandler. This is actually a *pointer* to the
errhandler structure. We don't know that, so we ask
the MPICH code to translate this object into an error handler.
kind = 0: errors are fatal
kind = 1: errors return
kind = 2: errors call function
*/
if (e == MPI_ERRORS_RETURN || e == MPIR_ERRORS_THROW_EXCEPTIONS || !e) {
/* FIXME: This is a hack in case no error handler was set */
kind = 1;
c_errhandler = 0;
}
else {
MPIR_Get_file_error_routine( e, &c_errhandler, &kind );
}
/* --BEGIN ERROR HANDLING-- */
if (MPIR_Err_is_fatal(error_code) || kind == 0)
{
ADIOI_Snprintf(error_msg, 4096, "I/O error: ");
len = (int)strlen(error_msg);
MPIR_Err_get_string(error_code, &error_msg[len], 4096-len, NULL);
MPID_Abort(NULL, MPI_SUCCESS, error_code, error_msg);
}
/* --END ERROR HANDLING-- */
else if (kind == 2) {
(*c_errhandler)( &mpi_fh, &error_code, 0 );
}
else if (kind == 3) {
MPIR_File_call_cxx_errhandler( &mpi_fh, &error_code, c_errhandler );
}
/* kind == 1 just returns */
return error_code;
}
int MPIO_Err_return_comm(MPI_Comm mpi_comm, int error_code)
{
/* note: MPI calls inside the MPICH implementation are prefixed
* with an "N", indicating a nested call.
*/
MPI_Comm_call_errhandler(mpi_comm, error_code);
return error_code;
}
|