none
When is it safe to release RPC_ASYNC_STATE data for asynchronous RPC calls?

    Question

  • Hi,

     

    We are having problems with RPC on Windows XP when trying to release the RPC_ASYNC_STATE data after the asynchronous RPC call completion. Our application makes asynchronous RPC calls and then regularly polls (it uses RpcNotificationTypeNone API) for the call status to determine when the RPC_ASYNC_STATE can be released.

    Random memory related crashes occur in our application once the data chunks holding the RPC_ASYNC_STATE structures get deallocated.

    Note that the application doesn’t crash on all asynchronous calls, crashes happen randomly. To test it we’re sending around 4 messages per second between RPC client and server. And the client application usually crashes after few minutes of such stress test.

     

    The code allocating the RPC_ASYNC_STATE memory chunks is following (chunks are allocated via new operator):

     

    PRPC_ASYNC_STATE CreateRpcAsyncState()

    {

          PRPC_ASYNC_STATE pRpcState = new RPC_ASYNC_STATE;

     

          if ( RpcAsyncInitializeHandle( pRpcState, sizeof(RPC_ASYNC_STATE) ) )

          {

                return NULL;

          }

     

          pRpcState->NotificationType = RpcNotificationTypeNone;

          return pRpcState;

    }

     

     

    Here is the client code that checks for the call status to know when to release RPC_ASYNC_STATE data:

     

    void CheckForCallComplete(PRPC_ASYNC_STATE pRpcState)

    {

                    RPC_STATUS status = RpcAsyncGetCallStatus(pRpcState);

                    if (status==RPC_S_OK)

                    {

                                    int nReply(101);

                                    RpcAsyncCompleteCall(pRpcState, &nReply);

                                    delete pRpcState;

                    }

                    else if (status!=RPC_S_ASYNC_CALL_PENDING)

                    {

                                    // Unexpected error. Release the state.

                                    delete pRpcState;

                    }

    }

     

    We observed that on XP system the  "delete pRpcState" randomly crashes our applications.   It looks like RPC is still writing in RPC_ASYNC_STATE data after we freed it.

     

    Question 1:

     Is there something wrong with our code for CheckForCallComplete? How should we determine when the RPC_ASYNC_STATE data chunk can be safely deallocated?

     

    Question 2:

    Note that we also tried verifying for “pRpcState->Event == RpcCallComplete” and with this check no crash occured. However, is this really the recommended approach of determining whether it’s safe to deallocate data?

     

    Question 3:

    Also, as a workaround we changed the code to use the RpcNotificationTypeCallback WinAPI and we now free the RPC_ASYNC_STATE data in the callback function (when asyncEvent == RpcCallComplete) instead of polling for the call state. Crashes on XP stopped. But is this a safe way to proceed? Can RPC runtime still reference the RPC_ASYNC_STATE data after the callback is invoked?

    I'm hoping someone from Microsoft could help us out with this issue. Note that problems described here happen only on XP platform. We have to support the XP platform due to our product and market requirements.

    Wednesday, July 28, 2010 9:23 PM