@@ -158,6 +158,9 @@ typedef struct ompi_request_t ompi_request_t;
158
158
#define REQUEST_PENDING (void *)0L
159
159
#define REQUEST_COMPLETED (void *)1L
160
160
161
+ #define REQUEST_CB_PENDING (void *)0L
162
+ #define REQUEST_CB_COMPLETED (void *)1L
163
+
161
164
struct ompi_predefined_request_t {
162
165
struct ompi_request_t request ;
163
166
char padding [PREDEFINED_REQUEST_PAD - sizeof (ompi_request_t )];
@@ -517,12 +520,12 @@ static inline void ompi_request_wait_completion(ompi_request_t *req)
517
520
static inline int ompi_request_complete (ompi_request_t * request , bool with_signal )
518
521
{
519
522
int rc = 0 ;
520
-
521
- if ( NULL != request -> req_complete_cb ) {
522
- /* Set the request cb to NULL to allow resetting in the callback */
523
- ompi_request_complete_fn_t fct = request -> req_complete_cb ;
524
- request -> req_complete_cb = NULL ;
525
- rc = fct ( request );
523
+ ompi_request_complete_fn_t cb ;
524
+ cb = ( ompi_request_complete_fn_t ) OPAL_ATOMIC_SWAP_PTR (( opal_atomic_intptr_t * ) & request -> req_complete_cb ,
525
+ ( intptr_t ) REQUEST_CB_COMPLETED );
526
+ if ( REQUEST_CB_PENDING != cb ) {
527
+ request -> req_complete_cb = REQUEST_CB_PENDING ;
528
+ rc = cb ( request );
526
529
}
527
530
528
531
if (0 == rc ) {
@@ -546,12 +549,17 @@ static inline int ompi_request_set_callback(ompi_request_t* request,
546
549
void * cb_data )
547
550
{
548
551
request -> req_complete_cb_data = cb_data ;
549
- request -> req_complete_cb = cb ;
550
- /* If request is completed and the callback is not called, need to call callback */
551
- if ((NULL != request -> req_complete_cb ) && (request -> req_complete == REQUEST_COMPLETED )) {
552
- ompi_request_complete_fn_t fct = request -> req_complete_cb ;
553
- request -> req_complete_cb = NULL ;
554
- return fct ( request );
552
+ opal_atomic_wmb ();
553
+ if ((REQUEST_CB_COMPLETED == request -> req_complete_cb ) ||
554
+ (REQUEST_CB_COMPLETED == (void * )OPAL_ATOMIC_SWAP_PTR ((opal_atomic_intptr_t * )& request -> req_complete_cb ,
555
+ (intptr_t )cb ))) {
556
+ if (NULL != cb ) {
557
+ /* the request was marked at least partially completed, make sure it's fully complete */
558
+ while (!REQUEST_COMPLETE (request )) {}
559
+ /* Set the request cb to NULL to allow resetting in the callback */
560
+ request -> req_complete_cb = REQUEST_CB_PENDING ;
561
+ cb (request );
562
+ }
555
563
}
556
564
return OMPI_SUCCESS ;
557
565
}
0 commit comments