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:
parent
d1dc70fa5f
commit
f58cf973ad
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user