ANSC_STATUS
AnscDetoClean
    (
        ANSC_HANDLE                 hThisObject
    )
{
    ANSC_STATUS                     returnStatus = ANSC_STATUS_SUCCESS;
    PANSC_DAEMON_ENGINE_TCP_OBJECT  pMyObject    = (PANSC_DAEMON_ENGINE_TCP_OBJECT)hThisObject;
    PANSC_DAEMON_SERVER_TCP_OBJECT  pServer      = (PANSC_DAEMON_SERVER_TCP_OBJECT)pMyObject->hDaemonServer;
    PANSC_DSTO_WORKER_OBJECT        pWorker      = (PANSC_DSTO_WORKER_OBJECT      )pServer->hWorker;
    PANSC_DAEMON_SOCKET_TCP_OBJECT  pSocket      = NULL;
    PSINGLE_LINK_ENTRY              pSLinkEntry  = NULL;
    ULONG                           ulHashIndex  = 0;
    BOOL                            bSocketFound = FALSE;
    ULONG                           ulCurTime    = AnscGetTickInSecondsAbs();
    ULONG                           ulTimeout    = ANSC_DETO_SOCKET_TIMEOUT;

    if ( !pMyObject->bStarted )
    {
        return  ANSC_STATUS_SUCCESS;
    }
    /*
    else if ( pMyObject->ControlFlags & ANSC_DETO_FLAG_NO_TIMEOUT )
    {
        return  ANSC_STATUS_SUCCESS;
    }
    */

    if ( pMyObject->CurSocketCount >= pMyObject->MaxSocketCount )
    {
        ulTimeout = ANSC_DETO_SOCKET_TIMEOUT2;
    }
    else
    {
        ulTimeout = ANSC_DETO_SOCKET_TIMEOUT;
    }

    ulHashIndex  = 0;
    bSocketFound = FALSE;

    while ( ulHashIndex < ANSC_DETO_SOCKET_TABLE_SIZE )
    {
        AnscAcquireLock(&pMyObject->SocketTableLock);

        bSocketFound = FALSE;
        pSLinkEntry  = AnscSListGetFirstEntry(&pMyObject->SocketTable[ulHashIndex]);

        while ( pSLinkEntry )
        {
            pSocket     = ACCESS_ANSC_DAEMON_SOCKET_TCP_OBJECT(pSLinkEntry);
            pSLinkEntry = AnscSListGetNextEntry(pSLinkEntry);

            if ( pSocket->bLocked )
            {
                continue;
            }
            else if ( pSocket->bToBeCleaned )
            {
                bSocketFound = TRUE;

                break;
            }
            else if ( pMyObject->ControlFlags & ANSC_DETO_FLAG_NO_TIMEOUT )
            {
                continue;
            }
            else
            {
                ulCurTime = AnscGetTickInSecondsAbs();
            }

            if ( ((ulCurTime - pSocket->LastRecvAt) >= ulTimeout) &&
                 ((ulCurTime - pSocket->LastSendAt) >= ulTimeout) )
            {
                bSocketFound = TRUE;

                break;
            }
        }

        AnscReleaseLock(&pMyObject->SocketTableLock);

        if ( bSocketFound )
        {
            if ( !pSocket->bTlsEnabled ||
                 (pSocket->bTlsEnabled && pSocket->bTlsConnected) )
            {
                returnStatus =
                    pWorker->Notify
                        (
                            pWorker->hWorkerContext,
                            (ANSC_HANDLE)pSocket,
                            ANSC_DSTOWO_EVENT_TIME_OUT,
                            (ANSC_HANDLE)NULL
                        );
            }

            returnStatus =
                pMyObject->DelSocket
                    (
                        (ANSC_HANDLE)pMyObject,
                        (ANSC_HANDLE)pSocket
                    );

            pMyObject->TtcCount++;
        }
        else
        {
            ulHashIndex++;
        }
    }

    return  ANSC_STATUS_SUCCESS;
}