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