尝试停止 IOCP 工作线程并关闭套接字和相关的每个 io 数据 这是基于引用计数,当引用计数达到 0 时,关闭套接字并删除缓冲区。下面是 IOCP 工作线程的骨架。当我想停止 IO 时,调用 'FFT_stop_session' 函数。这只是 'PostQueuedCompletion.." 这种方式似乎有效。但崩溃时有发生..错误消息如下所示..
"HEAP: Free Heap block ??? modified at ??? after it was freed"
但我不明白为什么会发生双重免费???
static unsigned int WINAPI FFT_thread_worker (LPVOID param)
{
...
while(fft->running==TRUE)
{
iostatus = GetQueuedCompletionStatus(fft->hIOCP,&byteio,&completion_key (LPOVERLAPPED*)&ovlp,INFINITE);
if(iostatus == TRUE)
{
fftsock = (FFTSOCKET*)ovlp;
ffts = fftsock->session;
switch(completion_key)
{
//-- S E N D
case FFT_SEND:
{
// io works here
FFTSOCKET_ref_inc(fftsock);
FFTSOCKET_send(fftsock,&byteio);
break;
}
//-- R E C V
case FFT_RECV:
{
// io works
FFTSOCKET_ref_inc(fftsock);
FFTSOCKET_recv(fftsock,&byteio);
break;
}
case FFT_STOPIO:
{
// Just consume complete state
break;
}
default:break;
}
FFTSOCKET_ref_dec(fftsock); // dec ref counter and if it reasch 0 delete socket
}
}
return 0;
}
// Stop session
int FFT_stop_session (FFTCONTEXT* fft,FFT_session* session)
{
FFTSOCKET* sock = NULL;
HANDLE* handles = NULL;
if (fft != NULL && session != NULL)
{
::EnterCriticalSection (&(fft->cs));
for(int i = 0; i < session->socks.size(); i++)
{
sock = session->socks[i];
::PostQueuedCompletionStatus(fft->hIOCP,0,FFT_STOPIO,&(sock->overlapped));
}
::LeaveCriticalSection (&(fft->cs));
}
return 0;
}
int FFTSOCKET_ref_inc (FFTSOCKET* sock)
{
return ::InterlockedIncrement(&(sock->ref));
}
int FFTSOCKET_ref_dec (FFTSOCKET* sock)
{
int rst = 0;
if(sock->ref == 0)
{
rst = 1;
}
else if(::InterlockedDecrement(&(sock->ref))==0)
{
cout<<endl<<"sock delete:"<<sock->port<<flush;
if(sock->wsabuf.buf) VirtualFree(sock->wsabuf.buf,0,MEM_RELEASE);
sock->wsabuf.buf = NULL;
sock->wsabuf.len = 0;
WSACloseEvent(sock->overlapped.hEvent);
if(sock->ai != NULL) freeaddrinfo(sock->ai);
LINGER lingerStruct;
lingerStruct.l_onoff = 1;
lingerStruct.l_linger = 0;
::setsockopt(sock->socket, SOL_SOCKET, SO_LINGER, (char *)&lingerStruct, sizeof(lingerStruct));
shutdown(sock->socket,SD_BOTH);
closesocket(sock->socket);
sock->socket = INVALID_SOCKET;
delete sock;
sock = NULL;
rst = 2;
}
return rst;
}