Ticket #1519: filezilla_3_rc1_keepalive.patch

File filezilla_3_rc1_keepalive.patch, 9.3 KB (added by tommywu, 13 years ago)

keepalive for FZ3rc1

  • src/engine/ControlSocket.h

    diff -Nur Filezilla3/src/engine/ControlSocket.h Filezilla3.patch/src/engine/ControlSocket.h
    old new  
    115115    virtual int Chmod(const CChmodCommand& command) { return FZ_REPLY_NOTSUPPORTED; }
    116116    virtual bool Connected() const = 0;
    117117
     118    virtual int KeepAlive(const CKeepAliveCommand& command) { return FZ_REPLY_OK; }
     119
    118120    // If m_pCurrentOpData is zero, this function returns the current command
    119121    // from the engine.
    120122    enum Command GetCurrentCommandId() const;
  • src/engine/FileZillaEngine.cpp

    diff -Nur Filezilla3/src/engine/FileZillaEngine.cpp Filezilla3.patch/src/engine/FileZillaEngine.cpp
    old new  
    7070    case cmd_chmod:
    7171        res = Chmod(reinterpret_cast<const CChmodCommand&>(command));
    7272        break;
     73    case cmd_keepalive:
     74        res = KeepAlive(reinterpret_cast<const CKeepAliveCommand &>(command));
     75        break;
    7376    default:
    7477        return FZ_REPLY_SYNTAXERROR;
    7578    }
  • src/engine/engineprivate.cpp

    diff -Nur Filezilla3/src/engine/engineprivate.cpp Filezilla3.patch/src/engine/engineprivate.cpp
    old new  
    525525    return m_pControlSocket->Chmod(command);
    526526}
    527527
     528int CFileZillaEnginePrivate::KeepAlive(const CKeepAliveCommand& command)
     529{
     530    if (!IsConnected())
     531        return FZ_REPLY_NOTCONNECTED;
     532
     533    if (IsBusy())
     534        return FZ_REPLY_BUSY;
     535
     536    m_pCurrentCommand = command.Clone();
     537    return m_pControlSocket->KeepAlive(command);
     538}
     539
    528540void CFileZillaEnginePrivate::SendDirectoryListingNotification(const CServerPath& path, bool onList, bool modified, bool failed)
    529541{
    530542    wxASSERT(m_pControlSocket);
  • src/engine/ftpcontrolsocket.cpp

    diff -Nur Filezilla3/src/engine/ftpcontrolsocket.cpp Filezilla3.patch/src/engine/ftpcontrolsocket.cpp
    old new  
    147147{
    148148    LogMessage(Debug_Verbose, _T("CFtpControlSocket::OnReceive()"));
    149149
     150    m_stopWatch.Start();
     151
    150152    m_pBackend->Read(m_receiveBuffer + m_bufferLen, RECVBUFFERSIZE - m_bufferLen);
    151153   
    152154    if (m_pBackend->Error())
     
    386388    case cmd_rawtransfer:
    387389        TransferParseResponse();
    388390        break;
     391    case cmd_keepalive:
     392        KeepAliveParseResponse();
     393        break;
    389394    case cmd_none:
    390395        LogMessage(Debug_Verbose, _T("Out-of-order reply, ignoring."));
    391396        break;
     
    798803        LogMessage(::Error, _T("Failed to convert command to 8 bit charset"));
    799804        return false;
    800805    }
     806    m_stopWatch.Start();
    801807    unsigned int len = (unsigned int)strlen(buffer);
    802808    bool res = CRealControlSocket::Send(buffer, len);
    803809    if (res)
     
    12541260        return DeleteSend(prevResult);
    12551261    case cmd_removedir:
    12561262        return RemoveDirSend(prevResult);
     1263    case cmd_keepalive:
     1264        return KeepAliveSend();
    12571265    default:
    12581266        LogMessage(__TFILE__, __LINE__, this, ::Debug_Warning, _T("Unknown opID (%d) in SendNextCommand"), m_pCurOpData->opId);
    12591267        ResetOperation(FZ_REPLY_INTERNALERROR);
     
    30073015
    30083016    return FZ_REPLY_WOULDBLOCK;
    30093017}
     3018
     3019class CKeepAliveOpData : public COpData
     3020{
     3021public:
     3022    CKeepAliveOpData(const wxString& command)
     3023        : COpData(cmd_keepalive)
     3024    {
     3025        m_command = command;
     3026    }
     3027
     3028    wxString m_command;
     3029};
     3030
     3031int CFtpControlSocket::KeepAlive(const CKeepAliveCommand& command)
     3032{
     3033    LogMessage(Debug_Verbose, _("CFtpControlSocket::KeepAlive"));
     3034
     3035    // ignore keepalive for last I/O for socket less than 15 seconds
     3036    if (m_stopWatch.Time() < 15000)
     3037        return FZ_REPLY_OK;
     3038    // choose any command
     3039    wxString commands[4] = {_T("PWD"),_T("REST 0"), _T("TYPE A"), _T("TYPE I") };
     3040    int choice=(rand()*4)/(RAND_MAX+1);
     3041    m_pCurOpData = new CKeepAliveOpData(commands[choice]);
     3042
     3043    return SendNextCommand();
     3044}
     3045
     3046int CFtpControlSocket::KeepAliveSend()
     3047{
     3048    LogMessage(Debug_Verbose, _T("CFtpControlSocket::KeepAliveSend"));
     3049
     3050    if (!m_pCurOpData)
     3051    {
     3052        LogMessage(__TFILE__, __LINE__, this, Debug_Info, _T("Empty m_pCurOpData"));
     3053        ResetOperation(FZ_REPLY_INTERNALERROR);
     3054        return FZ_REPLY_ERROR;
     3055    }
     3056
     3057    CDirectoryCache cache;
     3058    cache.InvalidateServer(*m_pCurrentServer);
     3059    m_CurrentPath = CServerPath();
     3060
     3061    CKeepAliveOpData *pData = static_cast<CKeepAliveOpData *>(m_pCurOpData);
     3062
     3063    if (!Send(pData->m_command))
     3064        return FZ_REPLY_ERROR;
     3065
     3066    return FZ_REPLY_WOULDBLOCK;
     3067}
     3068
     3069int CFtpControlSocket::KeepAliveParseResponse()
     3070{
     3071    LogMessage(Debug_Verbose, _T("CFtpControlSocket::KeepAliveParseResponse"));
     3072
     3073    int code = GetReplyCode();
     3074    if (code == 2 || code == 3)
     3075    {
     3076        ResetOperation(FZ_REPLY_OK);
     3077        return FZ_REPLY_OK;
     3078    }
     3079    else
     3080    {
     3081        ResetOperation(FZ_REPLY_ERROR);
     3082        return FZ_REPLY_ERROR;
     3083    }
     3084}
     3085
    30103086
    30113087bool CFtpControlSocket::IsMisleadingListResponse() const
    30123088{
  • src/engine/ftpcontrolsocket.h

    diff -Nur Filezilla3/src/engine/ftpcontrolsocket.h Filezilla3.patch/src/engine/ftpcontrolsocket.h
    old new  
    2424
    2525protected:
    2626   
     27    wxStopWatch m_stopWatch;
     28    virtual int KeepAlive(const CKeepAliveCommand& command);
     29    int KeepAliveParseResponse();
     30    int KeepAliveSend();
     31
    2732    virtual int ResetOperation(int nErrorCode);
    2833
    2934    virtual int Connect(const CServer &server);
  • src/include/commands.h

    diff -Nur Filezilla3/src/include/commands.h Filezilla3.patch/src/include/commands.h
    old new  
    1919    cmd_rename,
    2020    cmd_chmod,
    2121    cmd_raw,
     22    cmd_keepalive,
    2223
    2324    // Only used internally
    2425    cmd_cwd,
     
    7677    CServer m_Server;
    7778};
    7879
     80DECLARE_COMMAND(CKeepAliveCommand, cmd_keepalive)
     81};
    7982DECLARE_COMMAND(CDisconnectCommand, cmd_disconnect)
    8083};
    8184
  • src/include/engineprivate.h

    diff -Nur Filezilla3/src/include/engineprivate.h Filezilla3.patch/src/include/engineprivate.h
    old new  
    6969    int Mkdir(const CMkdirCommand& command);
    7070    int Rename(const CRenameCommand& command);
    7171    int Chmod(const CChmodCommand& command);
     72    int KeepAlive(const CKeepAliveCommand& command);
    7273
    7374    int ContinueConnect();
    7475
  • src/interface/Mainfrm.cpp

    diff -Nur Filezilla3/src/interface/Mainfrm.cpp Filezilla3.patch/src/interface/Mainfrm.cpp
    old new  
    4343#endif
    4444
    4545#define TRANSFERSTATUS_TIMER_ID wxID_HIGHEST + 3
     46#define KEEPALIVE_TIMER_ID TRANSFERSTATUS_TIMER_ID + 1
    4647
    4748static const int statbarWidths[6] = {
    4849#ifdef __WXMSW__
     
    159160    }
    160161
    161162    m_transferStatusTimer.SetOwner(this, TRANSFERSTATUS_TIMER_ID);
     163    m_keepAliveTimer.SetOwner(this, KEEPALIVE_TIMER_ID);
    162164
    163165    CreateMenus();
    164166    CreateToolBar();
     
    696698    if (!m_pState->m_pCommandQueue->Idle())
    697699        return;
    698700
     701    m_keepAliveTimer.Stop();
    699702    m_pState->m_pCommandQueue->ProcessCommand(new CDisconnectCommand());
    700703}
    701704
     
    769772    m_pSendLed = 0;
    770773    m_pRecvLed = 0;
    771774
     775    m_keepAliveTimer.Stop();
     776
    772777    m_transferStatusTimer.Stop();
    773778
    774779    bool res = true;
     
    826831    CServerPath path;
    827832    path.SetSafePath(COptions::Get()->GetOption(OPTION_LASTSERVERPATH));
    828833    m_pState->Connect(server, false, path);
     834    // FIXME:
     835    // need to read from options, do this only for KeepAlive enabled
     836    m_keepAliveTimer.Start(1000);
    829837}
    830838
    831839void CMainFrame::OnRefresh(wxCommandEvent &event)
     
    898906        else
    899907            m_transferStatusTimer.Stop();
    900908    }
     909    else if (event.GetId() == KEEPALIVE_TIMER_ID && m_keepAliveTimer.IsRunning())
     910    {
     911        // make sure engine and commandqueue exist
     912        if (!m_pState && !m_pState->m_pEngine && !m_pState->m_pCommandQueue)
     913        {
     914            m_keepAliveTimer.Stop();
     915            return;
     916        }
     917        // just do this for idle, wait for next timer
     918        if (!m_pState->m_pCommandQueue->Idle())
     919            return;
     920        // if not connected, stop keepalive timer
     921        if (!m_pState->m_pEngine->IsConnected())
     922        {
     923            m_keepAliveTimer.Stop();
     924            return;
     925        }
     926        // FIXME:
     927        // need to read the values from options...
     928        int min_wait = 30;
     929        int max_wait = 60;
     930
     931        // if just connected, the interval will be 1000
     932        bool first_time = (m_keepAliveTimer.GetInterval() == 1000);
     933
     934        int waitsecond = min_wait + (int)(rand()*(max_wait - min_wait)/(RAND_MAX+1));
     935        m_keepAliveTimer.Stop();
     936        m_keepAliveTimer.Start(waitsecond * 1000);
     937        // skip keepalive for just connected
     938        if (first_time)
     939            return;
     940        m_pState->m_pCommandQueue->ProcessCommand(new CKeepAliveCommand());
     941    }
    901942}
    902943
    903944void CMainFrame::SetProgress(const CTransferStatus *pStatus)
     
    13421383    }
    13431384
    13441385    m_pState->Connect(pData->m_server, true, pData->m_remoteDir);
     1386    // FIXME:
     1387    // need to read from options, do this only for KeepAlive enabled
     1388    m_keepAliveTimer.Start(1000);
    13451389
    13461390    if (pData->m_localDir != _T(""))
    13471391        m_pState->SetLocalDir(pData->m_localDir);
  • src/interface/Mainfrm.h

    diff -Nur Filezilla3/src/interface/Mainfrm.h Filezilla3.patch/src/interface/Mainfrm.h
    old new  
    8484    CLed* m_pRecvLed;
    8585    CLed* m_pSendLed;
    8686    wxTimer m_transferStatusTimer;
     87
     88    wxTimer m_keepAliveTimer;
     89
    8790    CThemeProvider* m_pThemeProvider;
    8891#if FZ_MANUALUPDATECHECK && FZ_AUTOUPDATECHECK
    8992    CUpdateWizard* m_pUpdateWizard;