@@ -529,12 +529,13 @@ static inline void ompi_request_wait_completion(ompi_request_t *req)
529529static inline int ompi_request_complete (ompi_request_t * request , bool with_signal )
530530{
531531 int rc = 0 ;
532-
533- if (NULL != request -> req_complete_cb ) {
534- /* Set the request cb to NULL to allow resetting in the callback */
535- ompi_request_complete_fn_t fct = request -> req_complete_cb ;
536- request -> req_complete_cb = NULL ;
537- rc = fct ( request );
532+ ompi_request_complete_fn_t cb ;
533+ cb = (ompi_request_complete_fn_t )OPAL_ATOMIC_SWAP_PTR ((opal_atomic_intptr_t * )& request -> req_complete_cb ,
534+ (intptr_t )REQUEST_CB_COMPLETED );
535+ if (REQUEST_CB_PENDING != cb ) {
536+ request -> req_complete_cb = REQUEST_CB_PENDING ;
537+ opal_atomic_wmb ();
538+ rc = cb (request );
538539 }
539540
540541 if (0 == rc ) {
@@ -560,12 +561,18 @@ static inline int ompi_request_set_callback(ompi_request_t* request,
560561 void * cb_data )
561562{
562563 request -> req_complete_cb_data = cb_data ;
563- request -> req_complete_cb = cb ;
564- /* If request is completed and the callback is not called, need to call callback */
565- if ((NULL != request -> req_complete_cb ) && (request -> req_complete == REQUEST_COMPLETED )) {
566- ompi_request_complete_fn_t fct = request -> req_complete_cb ;
567- request -> req_complete_cb = NULL ;
568- return fct ( request );
564+ opal_atomic_wmb ();
565+ if ((REQUEST_CB_COMPLETED == request -> req_complete_cb ) ||
566+ (REQUEST_CB_COMPLETED == (void * )OPAL_ATOMIC_SWAP_PTR ((opal_atomic_intptr_t * )& request -> req_complete_cb ,
567+ (intptr_t )cb ))) {
568+ if (NULL != cb ) {
569+ /* the request was marked at least partially completed, make sure it's fully complete */
570+ while (!REQUEST_COMPLETE (request )) {}
571+ /* Set the request cb to NULL to allow resetting in the callback */
572+ request -> req_complete_cb = REQUEST_CB_PENDING ;
573+ opal_atomic_wmb ();
574+ cb (request );
575+ }
569576 }
570577 return OMPI_SUCCESS ;
571578}
0 commit comments