0

尝试停止 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;
}
4

0 回答 0