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
This commit is contained in:
Axel Dörfler 2007-08-05 23:38:31 +00:00
parent d1dc70fa5f
commit f58cf973ad

View File

@ -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;
}
// 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;