diff --git a/src/game/desc.cpp b/src/game/desc.cpp index c8727d8..05e9b91 100644 --- a/src/game/desc.cpp +++ b/src/game/desc.cpp @@ -17,6 +17,18 @@ #include "locale_service.h" #include "log.h" +namespace +{ +bool IsPeerDisconnectWriteError(int error_code) +{ +#ifdef OS_WINDOWS + return error_code == WSAECONNRESET || error_code == WSAECONNABORTED || error_code == WSAENOTCONN; +#else + return error_code == EPIPE || error_code == ECONNRESET || error_code == ENOTCONN; +#endif +} +} + extern int max_bytes_written; extern int current_bytes_written; extern int total_bytes_written; @@ -318,7 +330,14 @@ int DESC::ProcessOutput() } #endif - sys_err("ProcessOutput: send failed: %s (fd %d)", strerror(errno), m_sock); + const int error_code = errno; + BeginClosePhase(); + + if (IsPeerDisconnectWriteError(error_code)) + sys_log(0, "ProcessOutput: peer disconnected during send (host=%s fd=%d errno=%d %s)", GetHostName(), m_sock, error_code, strerror(error_code)); + else + sys_err("ProcessOutput: send failed (host=%s fd=%d errno=%d %s)", GetHostName(), m_sock, error_code, strerror(error_code)); + return -1; } @@ -408,8 +427,23 @@ void DESC::LargePacket(const void * c_pvData, int iSize) Packet(c_pvData, iSize); } +void DESC::BeginClosePhase() +{ + if (m_iPhase == PHASE_CLOSE) + return; + + m_iPhase = PHASE_CLOSE; + m_pInputProcessor = &m_inputClose; +} + void DESC::SetPhase(int _phase) { + if (_phase == PHASE_CLOSE) + { + BeginClosePhase(); + return; + } + m_iPhase = _phase; TPacketGCPhase pack; diff --git a/src/game/desc.h b/src/game/desc.h index ca7e4c3..e0049ec 100644 --- a/src/game/desc.h +++ b/src/game/desc.h @@ -146,6 +146,7 @@ class DESC protected: void Initialize(); + void BeginClosePhase(); protected: CInputProcessor * m_pInputProcessor;