unix: get a read event when read-polling a read-shutdown socket

UnixEndpoint::Receivable(): EOF means there is nothing left to read, and
the shutdown happened on the read side or the write side.

also fix x86_64 build with trace

Change-Id: I54c806f0b900591c3d441240b8f6768dfb756bad
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3808
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
This commit is contained in:
Jérôme Duval 2021-03-19 21:14:54 +01:00
parent 9335a062be
commit f0c4b0a69a
3 changed files with 45 additions and 29 deletions

View File

@ -16,7 +16,7 @@
# define TRACE(args...) UNIX_DEBUG_PRINT(args)
# define PRINT_ERROR(error) \
do { \
UNIX_DEBUG_PRINT("[%ld] l. %d: %s: %s\n", \
UNIX_DEBUG_PRINT("[%" B_PRId32 "] l. %d: %s: %s\n", \
find_thread(NULL), __LINE__, __PRETTY_FUNCTION__, \
strerror(error)); \
} while (false)

View File

@ -50,7 +50,8 @@ UnixEndpoint::UnixEndpoint(net_socket* socket)
fAcceptSemaphore(-1),
fIsChild(false)
{
TRACE("[%ld] %p->UnixEndpoint::UnixEndpoint()\n", find_thread(NULL), this);
TRACE("[%" B_PRId32 "] %p->UnixEndpoint::UnixEndpoint()\n",
find_thread(NULL), this);
mutex_init(&fLock, "unix endpoint");
}
@ -58,7 +59,8 @@ UnixEndpoint::UnixEndpoint(net_socket* socket)
UnixEndpoint::~UnixEndpoint()
{
TRACE("[%ld] %p->UnixEndpoint::~UnixEndpoint()\n", find_thread(NULL), this);
TRACE("[%" B_PRId32 "] %p->UnixEndpoint::~UnixEndpoint()\n",
find_thread(NULL), this);
mutex_destroy(&fLock);
}
@ -67,7 +69,8 @@ UnixEndpoint::~UnixEndpoint()
status_t
UnixEndpoint::Init()
{
TRACE("[%ld] %p->UnixEndpoint::Init()\n", find_thread(NULL), this);
TRACE("[%" B_PRId32 "] %p->UnixEndpoint::Init()\n", find_thread(NULL),
this);
RETURN_ERROR(B_OK);
}
@ -76,7 +79,8 @@ UnixEndpoint::Init()
void
UnixEndpoint::Uninit()
{
TRACE("[%ld] %p->UnixEndpoint::Uninit()\n", find_thread(NULL), this);
TRACE("[%" B_PRId32 "] %p->UnixEndpoint::Uninit()\n", find_thread(NULL),
this);
// check whether we're closed
UnixEndpointLocker locker(this);
@ -97,7 +101,8 @@ UnixEndpoint::Uninit()
status_t
UnixEndpoint::Open()
{
TRACE("[%ld] %p->UnixEndpoint::Open()\n", find_thread(NULL), this);
TRACE("[%" B_PRId32 "] %p->UnixEndpoint::Open()\n", find_thread(NULL),
this);
status_t error = ProtocolSocket::Open();
if (error != B_OK)
@ -112,7 +117,8 @@ UnixEndpoint::Open()
status_t
UnixEndpoint::Close()
{
TRACE("[%ld] %p->UnixEndpoint::Close()\n", find_thread(NULL), this);
TRACE("[%" B_PRId32 "] %p->UnixEndpoint::Close()\n", find_thread(NULL),
this);
UnixEndpointLocker locker(this);
@ -138,7 +144,8 @@ UnixEndpoint::Close()
status_t
UnixEndpoint::Free()
{
TRACE("[%ld] %p->UnixEndpoint::Free()\n", find_thread(NULL), this);
TRACE("[%" B_PRId32 "] %p->UnixEndpoint::Free()\n", find_thread(NULL),
this);
UnixEndpointLocker locker(this);
@ -154,7 +161,8 @@ UnixEndpoint::Bind(const struct sockaddr *_address)
if (_address->sa_family != AF_UNIX)
RETURN_ERROR(EAFNOSUPPORT);
TRACE("[%ld] %p->UnixEndpoint::Bind(\"%s\")\n", find_thread(NULL), this,
TRACE("[%" B_PRId32 "] %p->UnixEndpoint::Bind(\"%s\")\n",
find_thread(NULL), this,
ConstSocketAddress(&gAddressModule, _address).AsString().Data());
const sockaddr_un* address = (const sockaddr_un*)_address;
@ -221,7 +229,8 @@ UnixEndpoint::Bind(const struct sockaddr *_address)
status_t
UnixEndpoint::Unbind()
{
TRACE("[%ld] %p->UnixEndpoint::Unbind()\n", find_thread(NULL), this);
TRACE("[%" B_PRId32 "] %p->UnixEndpoint::Unbind()\n", find_thread(NULL),
this);
UnixEndpointLocker endpointLocker(this);
@ -232,8 +241,8 @@ UnixEndpoint::Unbind()
status_t
UnixEndpoint::Listen(int backlog)
{
TRACE("[%ld] %p->UnixEndpoint::Listen(%d)\n", find_thread(NULL), this,
backlog);
TRACE("[%" B_PRId32 "] %p->UnixEndpoint::Listen(%d)\n", find_thread(NULL),
this, backlog);
UnixEndpointLocker endpointLocker(this);
@ -269,7 +278,8 @@ UnixEndpoint::Connect(const struct sockaddr *_address)
if (_address->sa_family != AF_UNIX)
RETURN_ERROR(EAFNOSUPPORT);
TRACE("[%ld] %p->UnixEndpoint::Connect(\"%s\")\n", find_thread(NULL), this,
TRACE("[%" B_PRId32 "] %p->UnixEndpoint::Connect(\"%s\")\n",
find_thread(NULL), this,
ConstSocketAddress(&gAddressModule, _address).AsString().Data());
const sockaddr_un* address = (const sockaddr_un*)_address;
@ -389,7 +399,8 @@ UnixEndpoint::Connect(const struct sockaddr *_address)
status_t
UnixEndpoint::Accept(net_socket **_acceptedSocket)
{
TRACE("[%ld] %p->UnixEndpoint::Accept()\n", find_thread(NULL), this);
TRACE("[%" B_PRId32 "] %p->UnixEndpoint::Accept()\n", find_thread(NULL),
this);
bigtime_t timeout = absolute_timeout(socket->receive.timeout);
if (gStackModule->is_restarted_syscall())
@ -425,8 +436,8 @@ ssize_t
UnixEndpoint::Send(const iovec *vecs, size_t vecCount,
ancillary_data_container *ancillaryData)
{
TRACE("[%ld] %p->UnixEndpoint::Send(%p, %ld, %p)\n", find_thread(NULL),
this, vecs, vecCount, ancillaryData);
TRACE("[%" B_PRId32 "] %p->UnixEndpoint::Send(%p, %ld, %p)\n",
find_thread(NULL), this, vecs, vecCount, ancillaryData);
bigtime_t timeout = absolute_timeout(socket->send.timeout);
if (gStackModule->is_restarted_syscall())
@ -516,8 +527,8 @@ UnixEndpoint::Receive(const iovec *vecs, size_t vecCount,
ancillary_data_container **_ancillaryData, struct sockaddr *_address,
socklen_t *_addressLength)
{
TRACE("[%ld] %p->UnixEndpoint::Receive(%p, %ld)\n", find_thread(NULL),
this, vecs, vecCount);
TRACE("[%" B_PRId32 "] %p->UnixEndpoint::Receive(%p, %ld)\n",
find_thread(NULL), this, vecs, vecCount);
bigtime_t timeout = absolute_timeout(socket->receive.timeout);
if (gStackModule->is_restarted_syscall())
@ -608,7 +619,8 @@ UnixEndpoint::Receive(const iovec *vecs, size_t vecCount,
ssize_t
UnixEndpoint::Sendable()
{
TRACE("[%ld] %p->UnixEndpoint::Sendable()\n", find_thread(NULL), this);
TRACE("[%" B_PRId32 "] %p->UnixEndpoint::Sendable()\n", find_thread(NULL),
this);
UnixEndpointLocker locker(this);
UnixEndpointLocker peerLocker;
@ -628,7 +640,8 @@ UnixEndpoint::Sendable()
ssize_t
UnixEndpoint::Receivable()
{
TRACE("[%ld] %p->UnixEndpoint::Receivable()\n", find_thread(NULL), this);
TRACE("[%" B_PRId32 "] %p->UnixEndpoint::Receivable()\n", find_thread(NULL),
this);
UnixEndpointLocker locker(this);
@ -640,8 +653,10 @@ UnixEndpoint::Receivable()
UnixFifoLocker fifoLocker(fReceiveFifo);
ssize_t readable = fReceiveFifo->Readable();
if (readable == 0 && fReceiveFifo->IsWriteShutdown())
if (readable == 0 && (fReceiveFifo->IsWriteShutdown()
|| fReceiveFifo->IsReadShutdown())) {
RETURN_ERROR(ENOTCONN);
}
RETURN_ERROR(readable);
}
@ -649,7 +664,7 @@ UnixEndpoint::Receivable()
status_t
UnixEndpoint::SetReceiveBufferSize(size_t size)
{
TRACE("[%ld] %p->UnixEndpoint::SetReceiveBufferSize(%lu)\n",
TRACE("[%" B_PRId32 "] %p->UnixEndpoint::SetReceiveBufferSize(%lu)\n",
find_thread(NULL), this, size);
UnixEndpointLocker locker(this);
@ -681,7 +696,7 @@ UnixEndpoint::GetPeerCredentials(ucred* credentials)
status_t
UnixEndpoint::Shutdown(int direction)
{
TRACE("[%ld] %p->UnixEndpoint::Shutdown(%d)\n",
TRACE("[%" B_PRId32 "] %p->UnixEndpoint::Shutdown(%d)\n",
find_thread(NULL), this, direction);
uint32 shutdown;

View File

@ -291,8 +291,8 @@ UnixFifo::Init()
void
UnixFifo::Shutdown(uint32 shutdown)
{
TRACE("[%ld] %p->UnixFifo::Shutdown(0x%lx)\n", find_thread(NULL), this,
shutdown);
TRACE("[%" B_PRId32 "] %p->UnixFifo::Shutdown(0x%" B_PRIx32 ")\n",
find_thread(NULL), this, shutdown);
fShutdown |= shutdown;
@ -308,8 +308,8 @@ ssize_t
UnixFifo::Read(const iovec* vecs, size_t vecCount,
ancillary_data_container** _ancillaryData, bigtime_t timeout)
{
TRACE("[%ld] %p->UnixFifo::Read(%p, %ld, %lld)\n", find_thread(NULL),
this, vecs, vecCount, timeout);
TRACE("[%" B_PRId32 "] %p->UnixFifo::Read(%p, %ld, %" B_PRIdBIGTIME ")\n",
find_thread(NULL), this, vecs, vecCount, timeout);
if (IsReadShutdown() && fBuffer.Readable() == 0)
RETURN_ERROR(UNIX_FIFO_SHUTDOWN);
@ -353,8 +353,9 @@ ssize_t
UnixFifo::Write(const iovec* vecs, size_t vecCount,
ancillary_data_container* ancillaryData, bigtime_t timeout)
{
TRACE("[%ld] %p->UnixFifo::Write(%p, %ld, %p, %lld)\n", find_thread(NULL),
this, vecs, vecCount, ancillaryData, timeout);
TRACE("[%" B_PRId32 "] %p->UnixFifo::Write(%p, %ld, %p, %" B_PRIdBIGTIME
")\n", find_thread(NULL), this, vecs, vecCount, ancillaryData,
timeout);
if (IsWriteShutdown())
RETURN_ERROR(UNIX_FIFO_SHUTDOWN);