Menu

#4 CFtpServer destructor execute before all shell thread terminated !

Unstable (example)
open
nobody
None
5
2014-07-24
2014-07-23
Erakis
No

There a racing condition while closing the FTPServer while there a still user connected on.

The CFtpServer destructor is executed without waiting for all Client (thread -> Shell) is terminated.

On the Shell function, the problem usually occurred here :

    pFtpServer->ClientListLock.Enter();
    {
        pClient->ResetDataConnection( false ); // do not wait sync on self
        if( pClient->bIsCtrlCanalOpen == true ) {
            pClient->ResetTimeout();
        } else
            delete pClient;
    }
    pFtpServer->ClientListLock.Leave();  // Here, as the pFtpServer object has been destructed !

Discussion

  • Erakis

    Erakis - 2014-07-24

    There an error in the code of my last message and as I CANNOT edit my own message, I will describe the problem again here + how to correct it.

    There a racing condition while closing the FTPServer while there a still user connected on.
    The CFtpServer destructor is executed without waiting for all Client (thread -> Shell) thread terminated.

    On the Shell function, the problem usually occurred here :

        pFtpServer->ClientListLock.Enter();
        {
            pClient->ClientLock.Enter();
            {
                if( pClient->CtrlSock != INVALID_SOCKET ) {
                    SOCKET tmpSock = pClient->CtrlSock;
                    pClient->CtrlSock = INVALID_SOCKET;
                    CloseSocket( tmpSock );
                }
            }
            pClient->ClientLock.Leave();
            if( pClient->eStatus == WAITING ) {
                delete pClient;
            } else
                pClient->bIsCtrlCanalOpen = false;
        }
        pFtpServer->ClientListLock.Leave();  // Here, as the pFtpServer object has been destructed !
    

    To correct the problem, simply remove the lock on ClientListLock object. It is not useful as we delete and object that has been already detached from this list and we don't modify the list itself. So :

        pClient->ClientLock.Enter();
        {
            if( pClient->CtrlSock != INVALID_SOCKET ) {
                SOCKET tmpSock = pClient->CtrlSock;
                pClient->CtrlSock = INVALID_SOCKET;
                CloseSocket( tmpSock );
            }
        }
        pClient->ClientLock.Leave();
        if( pClient->eStatus == WAITING ) {
            delete pClient;
        } else
            pClient->bIsCtrlCanalOpen = false;
    
     
  • js107

    js107 - 2016-06-21
    Post awaiting moderation.
  • js107

    js107 - 2016-06-27
    Post awaiting moderation.
  • js107

    js107 - 2016-08-08
    Post awaiting moderation.
  • js107

    js107 - 2018-02-20
    Post awaiting moderation.

Log in to post a comment.