Skip to content

Commit e534611

Browse files
authored
Merge pull request #11683 from bosilca/topic/fix_grequest_free
Propagate the error from the generalize request free callback to the user
2 parents 6ab6775 + ac3647e commit e534611

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)