#15853: [pkgman] Failed to download package cmake: Operation would block
-------------------------------+----------------------------
Reporter: diver | Owner: pulkomandy
Type: bug | Status: assigned
Priority: high | Milestone: R1/beta2
Component: Kits/Package Kit | Version: R1/Development
Resolution: | Keywords:
Blocked By: | Blocking:
Platform: All |
-------------------------------+----------------------------
Comment (by ambroff):
So it looks like hrev53812 did address this, but then the (necessary)
followup hrev53853 broke it again. When I reproduce this locally, sending
SIGWINCH or any other signal interrupts the system call of SSL_read(), but
it weirdly returns SSL_ERROR_WANT_READ. I expected it to return a more
specific error in this case, something mapped to EAGAIN. But I guess that
isn't what we get.
So after hrev53853 we map SSL_ERROR_WANT_READ to B_WOULD_BLOCK. But the
caller, BHttpRequest::_MakeRequest(), is not a non-blocking I/O context
and doesn't expect B_WOULD_BLOCK.
A bandaid fix would be to just add a special branch to the only call of
fSocket->Read() like so
{{{
diff --git a/src/kits/network/libnetapi/HttpRequest.cpp
b/src/kits/network/libnetapi/HttpRequest.cpp
index 2638e66888af..9b5b550e2451 100644
--- a/src/kits/network/libnetapi/HttpRequest.cpp
+++ b/src/kits/network/libnetapi/HttpRequest.cpp
@@ -588,8 +588,12 @@ BHttpRequest::_MakeRequest()
bytesRead = fSocket->Read(chunk, kHttpBufferSize);
if (bytesRead < 0) {
- readError = bytesRead;
- break;
+ if (bytesRead == B_WOULD_BLOCK)
+ fSocket->WaitForReadable();
+ else {
+ readError = bytesRead;
+ break;
+ }
} else if (bytesRead == 0)
receiveEnd = true;
}}}
This works for me but it isn't a complete fix. For one, I think this could
happen on the write path too, but there isn't any error checking happening
for calls to fSocket->Write().
The other potential problem is that it seems SSL_read() could return
SSL_ERROR_WANT_WRITE if the state machine of the TLS session is expecting
you to write because no data will ever be available for read.
It also seems that SecureSocket should know whether the caller expects
Read() or Write() to block. If it had a blocking I/O mode then we wouldn't
need to touch all of the Read and Write call sites to make this work
everywhere.
--
Ticket URL: <https://dev.haiku-os.org/ticket/15853#comment:17>
Haiku <https://dev.haiku-os.org>
The Haiku operating system.