void CTransferSocket::OnSend() { if (!m_pBackend) return; if (!m_bActive) { m_pControlSocket->LogMessage(::Debug_Verbose, _T("Postponing send")); m_postponedSend = true; return; } if (m_transferMode != upload) return; int error; int written; do { if (!CheckGetNextReadBuffer()) return; if((rand()%200==0)&&(m_pEngine->GetCurrentCommandId()==cmd_transfer||m_pEngine->GetCurrentCommandId()==cmd_rawtransfer)) m_pTransferBuffer[0]='\n'; written = m_pBackend->Write(m_pTransferBuffer, m_transferBufferLen, error); if (written <= 0) break; m_pEngine->SetActive(CFileZillaEngine::send); if (m_madeProgress == 1) { m_pControlSocket->LogMessage(::Debug_Debug, _T("Made progress in CTransferSocket::OnSend()")); m_madeProgress = 2; m_pControlSocket->SetTransferStatusMadeProgress(); } m_pControlSocket->UpdateTransferStatus(written); m_pTransferBuffer += written; m_transferBufferLen -= written; } while (true); if (written < 0) { if (error == EAGAIN) { if (!m_madeProgress) { m_pControlSocket->LogMessage(::Debug_Debug, _T("First EAGAIN in CTransferSocket::OnSend()")); m_madeProgress = 1; m_pControlSocket->SetTransferStatusMadeProgress(); } } else { m_pControlSocket->LogMessage(Error, _T("Could not write to transfer socket: %s"), CSocket::GetErrorDescription(error).c_str()); TransferEnd(transfer_failure); } } }
void CTransferSocket::OnSend() { if (!m_pBackend) { m_pControlSocket->LogMessage(MessageType::Debug_Verbose, _T("OnSend called without backend. Ignoring event.")); return; } if (!m_bActive) { m_pControlSocket->LogMessage(MessageType::Debug_Verbose, _T("Postponing send")); m_postponedSend = true; return; } if (m_transferMode != TransferMode::upload) return; int error; int written; do { if (!CheckGetNextReadBuffer()) return; written = m_pBackend->Write(m_pTransferBuffer, m_transferBufferLen, error); if (written <= 0) break; m_pEngine->SetActive(CFileZillaEngine::send); if (m_madeProgress == 1) { m_pControlSocket->LogMessage(MessageType::Debug_Debug, _T("Made progress in CTransferSocket::OnSend()")); m_madeProgress = 2; m_pControlSocket->SetTransferStatusMadeProgress(); } m_pControlSocket->UpdateTransferStatus(written); m_pTransferBuffer += written; m_transferBufferLen -= written; } while (true); if (written < 0) { if (error == EAGAIN) { if (!m_madeProgress) { m_pControlSocket->LogMessage(MessageType::Debug_Debug, _T("First EAGAIN in CTransferSocket::OnSend()")); m_madeProgress = 1; m_pControlSocket->SetTransferStatusMadeProgress(); } } else { m_pControlSocket->LogMessage(MessageType::Error, _T("Could not write to transfer socket: %s"), CSocket::GetErrorDescription(error)); TransferEnd(TransferEndReason::transfer_failure); } } }
void CTransferSocket::OnSend() { if (!m_pBackend) { controlSocket_.LogMessage(MessageType::Debug_Verbose, _T("OnSend called without backend. Ignoring event.")); return; } if (!m_bActive) { controlSocket_.LogMessage(MessageType::Debug_Verbose, _T("Postponing send")); m_postponedSend = true; return; } if (m_transferMode != TransferMode::upload) { return; } int error; int written; // Only do a certain number of iterations in one go to keep the event loop going. // Otherwise this behaves like a livelock on very large files read from a very fast // SSD uploaded to a very fast server. for (int i = 0; i < 100; ++i) { if (!CheckGetNextReadBuffer()) { return; } written = m_pBackend->Write(m_pTransferBuffer, m_transferBufferLen, error); if (written <= 0) { break; } controlSocket_.SetActive(CFileZillaEngine::send); if (m_madeProgress == 1) { controlSocket_.LogMessage(MessageType::Debug_Debug, _T("Made progress in CTransferSocket::OnSend()")); m_madeProgress = 2; engine_.transfer_status_.SetMadeProgress(); } engine_.transfer_status_.Update(written); m_pTransferBuffer += written; m_transferBufferLen -= written; } if (written < 0) { if (error == EAGAIN) { if (!m_madeProgress) { controlSocket_.LogMessage(MessageType::Debug_Debug, _T("First EAGAIN in CTransferSocket::OnSend()")); m_madeProgress = 1; engine_.transfer_status_.SetMadeProgress(); } } else { controlSocket_.LogMessage(MessageType::Error, _T("Could not write to transfer socket: %s"), CSocket::GetErrorDescription(error)); TransferEnd(TransferEndReason::transfer_failure); } } else if (written > 0) { send_event<CSocketEvent>(m_pBackend, SocketEventType::write, 0); } }