From f58cf973adf37e0d0752762a8b459b179482d6e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sun, 5 Aug 2007 23:38:31 +0000 Subject: [PATCH] mmlr+bonefish(+axeld - I put the bug in there ;-)): * Inode::MayReleaseWriter() would release the semaphore too often; therefore, Inode::WriteDataToBuffer() now loops in case it still couldn't write anything instead of failing - this fixes a race condition (ie. a device is full message). * In case the read request got filled two times (while adding the request, and after waiting for it to become filled), ReadRequest::PutBuffer() overwrote the output data. This fixes bug #1331. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21830 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/fs/pipefs.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/system/kernel/fs/pipefs.cpp b/src/system/kernel/fs/pipefs.cpp index c53216b9e7..30f7f4df9e 100644 --- a/src/system/kernel/fs/pipefs.cpp +++ b/src/system/kernel/fs/pipefs.cpp @@ -626,17 +626,19 @@ Inode::WriteDataToBuffer(const void **_data, size_t *_bytesLeft, // still come in and we don't block the whole inode data transfer // to prevent deadlocks from happening - if (!nonBlocking) + while (fBuffer.Writable() == 0) { + if (nonBlocking) + return B_WOULD_BLOCK; + benaphore_unlock(&fRequestLock); - status_t status = acquire_sem_etc(fWriteLock, 1, - (nonBlocking ? B_TIMEOUT : 0) | B_CAN_INTERRUPT, 0); + status_t status = acquire_sem_etc(fWriteLock, 1, B_CAN_INTERRUPT, 0); - if (!nonBlocking) benaphore_lock(&fRequestLock); - if (status != B_OK) - return status; + if (status != B_OK) + return status; + } // ensure that we don't write more than PIPEFS_MAX_BUFFER_SIZE // into a pipe without blocking @@ -1007,7 +1009,7 @@ ReadRequest::PutBuffer(RingBuffer &buffer, size_t *_bytesRead, if (length == 0) return B_OK; - if (buffer.UserRead(fBuffer, length) < B_OK) { + if (buffer.UserRead((char*)fBuffer + fBytesRead, length) < B_OK) { // if the buffer is just invalid, we release the reader as well release_sem(fLock); return B_BAD_ADDRESS;