Commit d56a51cb authored by Max Kellermann's avatar Max Kellermann

Merge branch 'v0.22.x'

parents 065a0c09 9e2d09da
...@@ -3,6 +3,8 @@ ver 0.23 (not yet released) ...@@ -3,6 +3,8 @@ ver 0.23 (not yet released)
- new command "getvol" - new command "getvol"
ver 0.22.5 (not yet released) ver 0.22.5 (not yet released)
* output
- httpd: error handling on Windows improved
ver 0.22.4 (2021/01/21) ver 0.22.4 (2021/01/21)
* protocol * protocol
......
...@@ -36,7 +36,7 @@ BufferedSocket::DirectRead(void *data, size_t length) noexcept ...@@ -36,7 +36,7 @@ BufferedSocket::DirectRead(void *data, size_t length) noexcept
} }
const auto code = GetSocketError(); const auto code = GetSocketError();
if (IsSocketErrorAgain(code)) if (IsSocketErrorReceiveWouldBlock(code))
return 0; return 0;
if (IsSocketErrorClosed(code)) if (IsSocketErrorClosed(code))
......
...@@ -31,7 +31,7 @@ FullyBufferedSocket::DirectWrite(const void *data, size_t length) noexcept ...@@ -31,7 +31,7 @@ FullyBufferedSocket::DirectWrite(const void *data, size_t length) noexcept
const auto nbytes = GetSocket().Write((const char *)data, length); const auto nbytes = GetSocket().Write((const char *)data, length);
if (gcc_unlikely(nbytes < 0)) { if (gcc_unlikely(nbytes < 0)) {
const auto code = GetSocketError(); const auto code = GetSocketError();
if (IsSocketErrorAgain(code)) if (IsSocketErrorSendWouldBlock(code))
return 0; return 0;
idle_event.Cancel(); idle_event.Cancel();
......
...@@ -52,14 +52,79 @@ GetSocketError() noexcept ...@@ -52,14 +52,79 @@ GetSocketError() noexcept
#endif #endif
} }
gcc_const constexpr bool
static inline bool IsSocketErrorInProgress(socket_error_t code) noexcept
IsSocketErrorAgain(socket_error_t code) noexcept
{ {
#ifdef _WIN32 #ifdef _WIN32
return code == WSAEINPROGRESS; return code == WSAEINPROGRESS;
#else #else
return code == EAGAIN; return code == EINPROGRESS;
#endif
}
constexpr bool
IsSocketErrorWouldBlock(socket_error_t code) noexcept
{
#ifdef _WIN32
return code == WSAEWOULDBLOCK;
#else
return code == EWOULDBLOCK;
#endif
}
constexpr bool
IsSocketErrorConnectWouldBlock(socket_error_t code) noexcept
{
#if defined(_WIN32) || defined(__linux__)
/* on Windows, WSAEINPROGRESS is for blocking sockets and
WSAEWOULDBLOCK for non-blocking sockets */
/* on Linux, EAGAIN==EWOULDBLOCK is for local sockets and
EINPROGRESS is for all other sockets */
return IsSocketErrorInProgress(code) || IsSocketErrorWouldBlock(code);
#else
/* on all other operating systems, there's just EINPROGRESS */
return IsSocketErrorInProgress(code);
#endif
}
constexpr bool
IsSocketErrorSendWouldBlock(socket_error_t code) noexcept
{
#ifdef _WIN32
/* on Windows, WSAEINPROGRESS is for blocking sockets and
WSAEWOULDBLOCK for non-blocking sockets */
return IsSocketErrorInProgress(code) || IsSocketErrorWouldBlock(code);
#else
/* on all other operating systems, there's just EAGAIN==EWOULDBLOCK */
return IsSocketErrorWouldBlock(code);
#endif
}
constexpr bool
IsSocketErrorReceiveWouldBlock(socket_error_t code) noexcept
{
#ifdef _WIN32
/* on Windows, WSAEINPROGRESS is for blocking sockets and
WSAEWOULDBLOCK for non-blocking sockets */
return IsSocketErrorInProgress(code) || IsSocketErrorWouldBlock(code);
#else
/* on all other operating systems, there's just
EAGAIN==EWOULDBLOCK */
return IsSocketErrorWouldBlock(code);
#endif
}
constexpr bool
IsSocketErrorAcceptWouldBlock(socket_error_t code) noexcept
{
#ifdef _WIN32
/* on Windows, WSAEINPROGRESS is for blocking sockets and
WSAEWOULDBLOCK for non-blocking sockets */
return IsSocketErrorInProgress(code) || IsSocketErrorWouldBlock(code);
#else
/* on all other operating systems, there's just
EAGAIN==EWOULDBLOCK */
return IsSocketErrorWouldBlock(code);
#endif #endif
} }
......
...@@ -278,7 +278,7 @@ HttpdClient::TryWrite() noexcept ...@@ -278,7 +278,7 @@ HttpdClient::TryWrite() noexcept
metadata_current_position); metadata_current_position);
if (nbytes < 0) { if (nbytes < 0) {
auto e = GetSocketError(); auto e = GetSocketError();
if (IsSocketErrorAgain(e)) if (IsSocketErrorSendWouldBlock(e))
return true; return true;
if (!IsSocketErrorClosed(e)) { if (!IsSocketErrorClosed(e)) {
...@@ -305,7 +305,7 @@ HttpdClient::TryWrite() noexcept ...@@ -305,7 +305,7 @@ HttpdClient::TryWrite() noexcept
ssize_t nbytes = GetSocket().Write(&empty_data, 1); ssize_t nbytes = GetSocket().Write(&empty_data, 1);
if (nbytes < 0) { if (nbytes < 0) {
auto e = GetSocketError(); auto e = GetSocketError();
if (IsSocketErrorAgain(e)) if (IsSocketErrorSendWouldBlock(e))
return true; return true;
if (!IsSocketErrorClosed(e)) { if (!IsSocketErrorClosed(e)) {
...@@ -328,7 +328,7 @@ HttpdClient::TryWrite() noexcept ...@@ -328,7 +328,7 @@ HttpdClient::TryWrite() noexcept
bytes_to_write); bytes_to_write);
if (nbytes < 0) { if (nbytes < 0) {
auto e = GetSocketError(); auto e = GetSocketError();
if (IsSocketErrorAgain(e)) if (IsSocketErrorSendWouldBlock(e))
return true; return true;
if (!IsSocketErrorClosed(e)) { if (!IsSocketErrorClosed(e)) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment