Skip to content

Commit ac271d3

Browse files
bosilcajsquyres
authored andcommitted
Propagate the error up to the user.
Make sure to reset the generalized request to guarantee not to call the free callback a second time. Signed-off-by: George Bosilca <bosilca@icl.utk.edu> (cherry picked from commit ac3647e)
1 parent a2dee36 commit ac271d3

File tree

2 files changed

+47
-20
lines changed

2 files changed

+47
-20
lines changed

ompi/request/grequest.c

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,32 @@
2424
#include "ompi/request/grequest.h"
2525
#include "ompi/mpi/fortran/base/fint_2_int.h"
2626

27+
/**
28+
* Internal function to specialize the call to the user provided free_fn
29+
* for generalized requests.
30+
* @return The return value of the user specified callback or MPI_SUCCESS.
31+
*/
32+
static inline int ompi_grequest_internal_free(ompi_grequest_t* greq)
33+
{
34+
int rc = MPI_SUCCESS;
35+
if (NULL != greq->greq_free.c_free) {
36+
/* We were already putting query_fn()'s return value into
37+
* status.MPI_ERROR but for MPI_{Wait,Test}*. If there's a
38+
* free callback to invoke, the standard says to use the
39+
* return value from free_fn() callback, too.
40+
*/
41+
if (greq->greq_funcs_are_c) {
42+
greq->greq_base.req_status.MPI_ERROR =
43+
greq->greq_free.c_free(greq->greq_state);
44+
} else {
45+
MPI_Fint ierr;
46+
greq->greq_free.f_free((MPI_Aint*)greq->greq_state, &ierr);
47+
greq->greq_base.req_status.MPI_ERROR = OMPI_FINT_2_INT(ierr);
48+
}
49+
rc = greq->greq_base.req_status.MPI_ERROR;
50+
}
51+
return rc;
52+
}
2753

2854
/*
2955
* See the comment in the grequest destructor for the weird semantics
@@ -37,9 +63,21 @@
3763
*/
3864
static int ompi_grequest_free(ompi_request_t** req)
3965
{
40-
OBJ_RELEASE(*req);
41-
*req = MPI_REQUEST_NULL;
42-
return OMPI_SUCCESS;
66+
ompi_grequest_t* greq = (ompi_grequest_t*)*req;
67+
int rc = OMPI_SUCCESS;
68+
69+
if( greq->greq_user_freed ) {
70+
return OMPI_ERR_OUT_OF_RESOURCE;
71+
}
72+
greq->greq_user_freed = true;
73+
if( REQUEST_COMPLETE(*req) ) {
74+
rc = ompi_grequest_internal_free(greq);
75+
}
76+
if (OMPI_SUCCESS == rc ) {
77+
OBJ_RELEASE(*req);
78+
*req = MPI_REQUEST_NULL;
79+
}
80+
return rc;
4381
}
4482

4583
static int ompi_grequest_cancel(ompi_request_t* req, int flag)
@@ -72,6 +110,7 @@ static void ompi_grequest_construct(ompi_grequest_t* greq)
72110
override this value if the gen request was created from
73111
Fortran */
74112
greq->greq_funcs_are_c = true;
113+
greq->greq_user_freed = false;
75114
}
76115

77116
/*
@@ -122,23 +161,6 @@ static void ompi_grequest_construct(ompi_grequest_t* greq)
122161
*/
123162
static void ompi_grequest_destruct(ompi_grequest_t* greq)
124163
{
125-
if (greq->greq_free.c_free != NULL) {
126-
/* We were already putting query_fn()'s return value into
127-
* status.MPI_ERROR but for MPI_{Wait,Test}*. If there's a
128-
* free callback to invoke, the standard says to use the
129-
* return value from free_fn() callback, too.
130-
*/
131-
if (greq->greq_funcs_are_c) {
132-
greq->greq_base.req_status.MPI_ERROR =
133-
greq->greq_free.c_free(greq->greq_state);
134-
} else {
135-
MPI_Fint ierr;
136-
greq->greq_free.f_free((MPI_Aint*)greq->greq_state, &ierr);
137-
greq->greq_base.req_status.MPI_ERROR =
138-
OMPI_FINT_2_INT(ierr);
139-
}
140-
}
141-
142164
OMPI_REQUEST_FINI(&greq->greq_base);
143165
}
144166

@@ -188,9 +210,13 @@ int ompi_grequest_start(
188210
*/
189211
int ompi_grequest_complete(ompi_request_t *req)
190212
{
213+
ompi_grequest_t* greq = (ompi_grequest_t*)req;
191214
int rc;
192215

193216
rc = ompi_request_complete(req, true);
217+
if( greq->greq_user_freed ) {
218+
rc = ompi_grequest_internal_free(greq);
219+
}
194220
OBJ_RELEASE(req);
195221
return rc;
196222
}

ompi/request/grequest.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ struct ompi_grequest_t {
104104
#endif
105105
void *greq_state;
106106
bool greq_funcs_are_c;
107+
bool greq_user_freed;
107108
};
108109
/**
109110
* Convenience typedef

0 commit comments

Comments
 (0)