My IOCP server program will cost more and more memory while running. After tracking memory leak ,I found that some WSAOVERLAPPED structue feed to WSARecv() is never recycled. I think this is because some malignant client socket only establish connection but never send data or close. So i set a TimerQueueTimer() on every client socket to identify the timeout socket and delete them. But if I free the WSAOVERLAPPED structure when deleting the malignant socket, after a little while ,I got "Free Heap block 014C7D80 modified at 014C7DA8 after it was freed".
Here is some of the relevant code:
typedef struct _SocketState
{
char operation;
SOCKET socket;
DWORD length;
HANDLE hTimer;
HANDLE hCompletion;
WSAOVERLAPPED* thisOvl;
char buf[MAX_BUF];
} SocketState;
static WSAOVERLAPPED* new_overlapped(void)
{
return (WSAOVERLAPPED*)calloc(1, sizeof(WSAOVERLAPPED));
}
static void create_io_completion_port(void)
{
cpl_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
if (!cpl_port)
{
int err = WSAGetLastError();
exit(1);
}
}
static void post_reading(SocketState* socketState, WSAOVERLAPPED* ovl)
{
DWORD flags = 0;
WSABUF wsabuf = { MAX_BUF, socketState->buf };
int err=0;
memset(ovl, 0, sizeof(WSAOVERLAPPED));
socketState->operation = OP_READ;
socketState->thisOvl=ovl;
if (WSARecv(socketState->socket, &wsabuf, 1, NULL, &flags, ovl, NULL)== SOCKET_ERROR)
{
err = WSAGetLastError();
if (err != WSA_IO_PENDING)
{
printf("[%s:%d]WSARecv error\n", __FUNCTION__, __LINE__);
destroy_connection(socketState, ovl);
return ;
}
}
c_WSARecv++;
}
static void destroy_connection(SocketState* socketState, WSAOVERLAPPED* ovl)
{
int err=0;
if(socketState->hTimer != NULL)
{
DeleteTimerQueueTimer(hTimerQueue,socketState->hTimer,INVALID_HANDLE_VALUE);
socketState->hTimer = NULL;
}
socketState->hCompletion=NULL; //newSocketState->hCompletion = cpl_port
closesocket(socketState->socket);
free(socketState);
if(ovl!=0)
{
free(ovl);
}
}
VOID CALLBACK TimerRoutine(PVOID lpParam, BOOLEAN TimerOrWaitFired)
{
SocketState* clientSocketState=(SocketState*)lpParam;
if (lpParam != NULL)
{
if(clientSocketState->hCompletion != NULL)
{
PostQueuedCompletionStatus(clientSocketState->hCompletion,-2,(ULONG_PTR)clientSocketState,clientSocketState->thisOvl);
//should last parameter be NULL?
//the "-2" is for identify this timeout io after GetQueuedCompletionStatus()
}
}
}
As I am using C rather then C++ for my server program, I am putting my self in very awkward situation. Basically I can't find a very good IOCP example in C :(.