diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index e4f364d3d340a3407e01477f6342c1e553a152e8..c05c8c76e16fc96d5a513608e26fcd24956bc7b6 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -73,6 +73,7 @@ typedef struct { SRpcInfo *pRpc; // associated SRpcInfo SRpcIpSet ipSet; // ip list provided by app void *ahandle; // handle provided by app + void *signature; // for validation struct SRpcConn *pConn; // pConn allocated char msgType; // message type uint8_t *pCont; // content provided by app @@ -361,6 +362,7 @@ void rpcSendRequest(void *shandle, const SRpcIpSet *pIpSet, SRpcMsg *pMsg) { int contLen = rpcCompressRpcMsg(pMsg->pCont, pMsg->contLen); pContext = (SRpcReqContext *) (pMsg->pCont-sizeof(SRpcHead)-sizeof(SRpcReqContext)); pContext->ahandle = pMsg->ahandle; + pContext->signature = pContext; pContext->pRpc = (SRpcInfo *)shandle; pContext->ipSet = *pIpSet; pContext->contLen = contLen; @@ -527,11 +529,13 @@ int rpcReportProgress(void *handle, char *pCont, int contLen) { return code; } -/* todo: cancel process may have race condition, pContext may have been released - just before app calls the rpcCancelRequest */ void rpcCancelRequest(void *handle) { SRpcReqContext *pContext = handle; + // signature is used to check if pContext is freed. + // pContext may have been released just before app calls the rpcCancelRequest + if (pContext->signature != pContext) return; + if (pContext->pConn) { tDebug("%s, app trys to cancel request", pContext->pConn->info); rpcCloseConn(pContext->pConn); @@ -1005,6 +1009,7 @@ static void *rpcProcessMsgFromPeer(SRecvInfo *pRecv) { static void rpcNotifyClient(SRpcReqContext *pContext, SRpcMsg *pMsg) { SRpcInfo *pRpc = pContext->pRpc; + pContext->signature = NULL; pContext->pConn = NULL; if (pContext->pRsp) { // for synchronous API