1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
2 /*
3  *
4  *  (C) 2001 by Argonne National Laboratory.
5  *      See COPYRIGHT in top-level directory.
6  */
7 
8 #include "mpiimpl.h"
9 
10 /* -- Begin Profiling Symbol Block for routine MPI_Win_set_errhandler */
11 #if defined(HAVE_PRAGMA_WEAK)
12 #pragma weak MPI_Win_set_errhandler = PMPI_Win_set_errhandler
13 #elif defined(HAVE_PRAGMA_HP_SEC_DEF)
14 #pragma _HP_SECONDARY_DEF PMPI_Win_set_errhandler  MPI_Win_set_errhandler
15 #elif defined(HAVE_PRAGMA_CRI_DUP)
16 #pragma _CRI duplicate MPI_Win_set_errhandler as PMPI_Win_set_errhandler
17 #endif
18 /* -- End Profiling Symbol Block */
19 
20 /* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build
21    the MPI routines */
22 #ifndef MPICH_MPI_FROM_PMPI
23 #undef MPI_Win_set_errhandler
24 #define MPI_Win_set_errhandler PMPI_Win_set_errhandler
25 
26 #endif
27 
28 #undef FUNCNAME
29 #define FUNCNAME MPI_Win_set_errhandler
30 
31 /*@
32    MPI_Win_set_errhandler - Set window error handler
33 
34    Input Parameters:
35 + win - window (handle)
36 - errhandler - new error handler for window (handle)
37 
38 .N ThreadSafeNoUpdate
39 
40 .N Fortran
41 
42 .N Errors
43 .N MPI_SUCCESS
44 .N MPI_ERR_WIN
45 @*/
MPI_Win_set_errhandler(MPI_Win win,MPI_Errhandler errhandler)46 int MPI_Win_set_errhandler(MPI_Win win, MPI_Errhandler errhandler)
47 {
48 #ifdef HAVE_ERROR_CHECKING
49     static const char FCNAME[] = "MPI_Win_set_errhandler";
50 #endif
51     int mpi_errno = MPI_SUCCESS;
52     MPID_Win *win_ptr = NULL;
53     int  in_use;
54     MPID_Errhandler *errhan_ptr = NULL;
55     MPID_MPI_STATE_DECL(MPID_STATE_MPI_WIN_SET_ERRHANDLER);
56 
57     MPIR_ERRTEST_INITIALIZED_ORDIE();
58 
59     MPID_MPI_FUNC_ENTER(MPID_STATE_MPI_WIN_SET_ERRHANDLER);
60 
61     /* Validate parameters, especially handles needing to be converted */
62 #   ifdef HAVE_ERROR_CHECKING
63     {
64         MPID_BEGIN_ERROR_CHECKS;
65         {
66 	    MPIR_ERRTEST_WIN(win, mpi_errno);
67 	    MPIR_ERRTEST_ERRHANDLER(errhandler, mpi_errno);
68         }
69         MPID_END_ERROR_CHECKS;
70     }
71 #   endif
72 
73     /* Convert MPI object handles to object pointers */
74     MPID_Win_get_ptr( win, win_ptr );
75     MPID_Errhandler_get_ptr( errhandler, errhan_ptr );
76 
77     /* Validate parameters and objects (post conversion) */
78 #   ifdef HAVE_ERROR_CHECKING
79     {
80         MPID_BEGIN_ERROR_CHECKS;
81         {
82             /* Validate win_ptr */
83             MPID_Win_valid_ptr( win_ptr, mpi_errno );
84 	    /* If win_ptr is not value, it will be reset to null */
85 
86 	    if (HANDLE_GET_KIND(errhandler) != HANDLE_KIND_BUILTIN) {
87 		MPID_Errhandler_valid_ptr( errhan_ptr,mpi_errno );
88 		/* Also check for a valid errhandler kind */
89 		if (!mpi_errno) {
90 		    if (errhan_ptr->kind != MPID_WIN) {
91 			mpi_errno = MPIR_Err_create_code(
92 			    MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME,
93 			    __LINE__, MPI_ERR_ARG, "**errhandnotwin", NULL );
94 		    }
95 		}
96 	    }
97             if (mpi_errno) goto fn_fail;
98         }
99         MPID_END_ERROR_CHECKS;
100     }
101 #   endif /* HAVE_ERROR_CHECKING */
102 
103     /* ... body of routine ...  */
104 
105     MPIU_THREAD_CS_ENTER(MPI_OBJ, win_ptr);
106 
107     if (win_ptr->errhandler != NULL) {
108         MPIR_Errhandler_release_ref(win_ptr->errhandler,&in_use);
109         if (!in_use) {
110             MPID_Errhandler_free( win_ptr->errhandler );
111         }
112     }
113 
114     MPIR_Errhandler_add_ref(errhan_ptr);
115     win_ptr->errhandler = errhan_ptr;
116 
117     MPIU_THREAD_CS_EXIT(MPI_OBJ, win_ptr);
118 
119     /* ... end of body of routine ... */
120 
121 #ifdef HAVE_ERROR_CHECKING
122   fn_exit:
123 #endif
124     MPID_MPI_FUNC_EXIT(MPID_STATE_MPI_WIN_SET_ERRHANDLER);
125     return mpi_errno;
126 
127     /* --BEGIN ERROR HANDLING-- */
128 #   ifdef HAVE_ERROR_CHECKING
129   fn_fail:
130     {
131 	mpi_errno = MPIR_Err_create_code(
132 	    mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER,
133 	    "**mpi_win_set_errhandler",
134 	    "**mpi_win_set_errhandler %W %E", win, errhandler);
135     }
136     mpi_errno = MPIR_Err_return_win(win_ptr, FCNAME, mpi_errno);
137     goto fn_exit;
138 #   endif
139     /* --END ERROR HANDLING-- */
140 }
141