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 TRACE(args...) UNIX_DEBUG_PRINT(args)
# define PRINT_ERROR(error) \ # define PRINT_ERROR(error) \
do { \ 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__, \ find_thread(NULL), __LINE__, __PRETTY_FUNCTION__, \
strerror(error)); \ strerror(error)); \
} while (false) } while (false)

View File

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

View File

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