Moved over to Ingo's new DoublyLinkedList - I miss my static list::Remove() :-))
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@11230 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -44,7 +44,7 @@ class Volume;
|
|||||||
class Inode;
|
class Inode;
|
||||||
struct dir_cookie;
|
struct dir_cookie;
|
||||||
|
|
||||||
class ReadRequest {
|
class ReadRequest : public DoublyLinkedListLinkImpl<ReadRequest> {
|
||||||
public:
|
public:
|
||||||
ReadRequest(void *buffer, size_t bufferSize);
|
ReadRequest(void *buffer, size_t bufferSize);
|
||||||
~ReadRequest();
|
~ReadRequest();
|
||||||
@@ -61,7 +61,8 @@ class ReadRequest {
|
|||||||
size_t BytesRead() const { return fBytesRead; }
|
size_t BytesRead() const { return fBytesRead; }
|
||||||
team_id Team() const { return fTeam; }
|
team_id Team() const { return fTeam; }
|
||||||
|
|
||||||
DoublyLinked::Link fLink;
|
bool IsQueued() const { return fIsQueued; }
|
||||||
|
void SetQueued(bool queued);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sem_id fLock;
|
sem_id fLock;
|
||||||
@@ -69,8 +70,10 @@ class ReadRequest {
|
|||||||
void *fBuffer;
|
void *fBuffer;
|
||||||
size_t fBufferSize;
|
size_t fBufferSize;
|
||||||
size_t fBytesRead;
|
size_t fBytesRead;
|
||||||
|
bool fIsQueued;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef DoublyLinkedList<ReadRequest> RequestList;
|
||||||
|
|
||||||
class Volume {
|
class Volume {
|
||||||
public:
|
public:
|
||||||
@@ -140,7 +143,7 @@ class Inode {
|
|||||||
void SetNext(Inode *inode) { fNext = inode; }
|
void SetNext(Inode *inode) { fNext = inode; }
|
||||||
|
|
||||||
benaphore *RequestLock() { return &fRequestLock; }
|
benaphore *RequestLock() { return &fRequestLock; }
|
||||||
DoublyLinked::List<ReadRequest> &Requests() { return fRequests; }
|
RequestList &Requests() { return fRequests; }
|
||||||
|
|
||||||
status_t WriteBufferToChain(const void **_buffer, size_t *_bytesLeft, bool nonBlocking);
|
status_t WriteBufferToChain(const void **_buffer, size_t *_bytesLeft, bool nonBlocking);
|
||||||
// status_t ReadBufferFromChain(void *buffer, size_t *_bufferSize);
|
// status_t ReadBufferFromChain(void *buffer, size_t *_bufferSize);
|
||||||
@@ -174,8 +177,7 @@ class Inode {
|
|||||||
|
|
||||||
cbuf *fBufferChain;
|
cbuf *fBufferChain;
|
||||||
|
|
||||||
DoublyLinked::List<ReadRequest> fRequests;
|
RequestList fRequests;
|
||||||
DoublyLinked::List<ReadRequest> fDoneRequests;
|
|
||||||
|
|
||||||
benaphore fRequestLock;
|
benaphore fRequestLock;
|
||||||
sem_id fWriteLock;
|
sem_id fWriteLock;
|
||||||
@@ -583,7 +585,7 @@ Inode::FillPendingRequests()
|
|||||||
TRACE(("Inode::FillPendingRequests(): bytesLeft = %lu\n", bytesLeft));
|
TRACE(("Inode::FillPendingRequests(): bytesLeft = %lu\n", bytesLeft));
|
||||||
|
|
||||||
ReadRequest *request;
|
ReadRequest *request;
|
||||||
DoublyLinked::Iterator<ReadRequest> iterator(fRequests);
|
RequestList::Iterator iterator = fRequests.GetIterator();
|
||||||
while (bytesLeft != 0 && (request = iterator.Next()) != NULL) {
|
while (bytesLeft != 0 && (request = iterator.Next()) != NULL) {
|
||||||
// notify the request, so that it can be filled
|
// notify the request, so that it can be filled
|
||||||
size_t space = request->SpaceLeft();
|
size_t space = request->SpaceLeft();
|
||||||
@@ -614,7 +616,7 @@ Inode::FillPendingRequests(const void **_buffer, size_t *_bytesLeft)
|
|||||||
TRACE(("Inode::FillPendingRequests(buffer = %p, bytes = %lu)\n", *_buffer, *_bytesLeft));
|
TRACE(("Inode::FillPendingRequests(buffer = %p, bytes = %lu)\n", *_buffer, *_bytesLeft));
|
||||||
|
|
||||||
ReadRequest *request;
|
ReadRequest *request;
|
||||||
DoublyLinked::Iterator<ReadRequest> iterator(fRequests);
|
RequestList::Iterator iterator = fRequests.GetIterator();
|
||||||
while (*_bytesLeft != 0 && (request = iterator.Next()) != NULL) {
|
while (*_bytesLeft != 0 && (request = iterator.Next()) != NULL) {
|
||||||
// try to fill this request
|
// try to fill this request
|
||||||
size_t bytesRead;
|
size_t bytesRead;
|
||||||
@@ -650,10 +652,11 @@ Inode::AddRequest(ReadRequest &request)
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
if (BytesInChain() > 0 && request.PutBufferChain(fBufferChain) == B_OK) {
|
if (BytesInChain() > 0 && request.PutBufferChain(fBufferChain) == B_OK) {
|
||||||
fDoneRequests.Add(&request);
|
|
||||||
MayReleaseWriter();
|
MayReleaseWriter();
|
||||||
} else
|
} else {
|
||||||
fRequests.Add(&request);
|
fRequests.Add(&request);
|
||||||
|
request.SetQueued(true);
|
||||||
|
}
|
||||||
|
|
||||||
benaphore_unlock(&fRequestLock);
|
benaphore_unlock(&fRequestLock);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -678,7 +681,8 @@ Inode::RemoveRequest(ReadRequest &request)
|
|||||||
if (BytesInChain() > 0 && request.PutBufferChain(fBufferChain) == B_OK)
|
if (BytesInChain() > 0 && request.PutBufferChain(fBufferChain) == B_OK)
|
||||||
release_sem(fWriteLock);
|
release_sem(fWriteLock);
|
||||||
|
|
||||||
DoublyLinked::List<ReadRequest>::Remove(&request);
|
if (request.IsQueued())
|
||||||
|
fRequests.Remove(&request);
|
||||||
|
|
||||||
benaphore_unlock(&fRequestLock);
|
benaphore_unlock(&fRequestLock);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -710,7 +714,7 @@ Inode::Close(int openMode)
|
|||||||
|
|
||||||
if (cbuf_get_length(fBufferChain) == 0) {
|
if (cbuf_get_length(fBufferChain) == 0) {
|
||||||
ReadRequest *request;
|
ReadRequest *request;
|
||||||
DoublyLinked::Iterator<ReadRequest> iterator(fRequests);
|
RequestList::Iterator iterator = fRequests.GetIterator();
|
||||||
while ((request = iterator.Next()) != NULL)
|
while ((request = iterator.Next()) != NULL)
|
||||||
request->Abort();
|
request->Abort();
|
||||||
}
|
}
|
||||||
@@ -764,7 +768,8 @@ ReadRequest::ReadRequest(void *buffer, size_t bufferSize)
|
|||||||
:
|
:
|
||||||
fBuffer(buffer),
|
fBuffer(buffer),
|
||||||
fBufferSize(bufferSize),
|
fBufferSize(bufferSize),
|
||||||
fBytesRead(0)
|
fBytesRead(0),
|
||||||
|
fIsQueued(false)
|
||||||
{
|
{
|
||||||
fLock = create_sem(0, "request lock");
|
fLock = create_sem(0, "request lock");
|
||||||
fTeam = team_get_current_team_id();
|
fTeam = team_get_current_team_id();
|
||||||
@@ -780,7 +785,8 @@ ReadRequest::~ReadRequest()
|
|||||||
status_t
|
status_t
|
||||||
ReadRequest::Wait(bool nonBlocking)
|
ReadRequest::Wait(bool nonBlocking)
|
||||||
{
|
{
|
||||||
TRACE(("pipefs: request@%p waits for data (%sblocking), thread 0x%lx\n", this, nonBlocking ? "non" : "", find_thread(NULL)));
|
TRACE(("pipefs: request@%p waits for data (%sblocking), thread 0x%lx\n",
|
||||||
|
this, nonBlocking ? "non" : "", find_thread(NULL)));
|
||||||
return acquire_sem_etc(fLock, 1, (nonBlocking ? B_TIMEOUT : 0) | B_CAN_INTERRUPT, 0);
|
return acquire_sem_etc(fLock, 1, (nonBlocking ? B_TIMEOUT : 0) | B_CAN_INTERRUPT, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -800,6 +806,13 @@ ReadRequest::Abort()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ReadRequest::SetQueued(bool queued)
|
||||||
|
{
|
||||||
|
fIsQueued = queued;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Reads the contents of the buffer chain to the specified
|
/** Reads the contents of the buffer chain to the specified
|
||||||
* buffer, if any.
|
* buffer, if any.
|
||||||
*/
|
*/
|
||||||
@@ -1193,7 +1206,8 @@ pipefs_read(fs_volume _volume, fs_vnode _node, fs_cookie _cookie, off_t /*pos*/,
|
|||||||
status_t status = request.Wait((cookie->open_mode & O_NONBLOCK) != 0);
|
status_t status = request.Wait((cookie->open_mode & O_NONBLOCK) != 0);
|
||||||
inode->RemoveRequest(request);
|
inode->RemoveRequest(request);
|
||||||
|
|
||||||
if ((status == B_TIMED_OUT || status == B_INTERRUPTED) && request.BytesRead() > 0)
|
if ((status == B_TIMED_OUT || status == B_INTERRUPTED || status == B_WOULD_BLOCK)
|
||||||
|
&& request.BytesRead() > 0)
|
||||||
status = B_OK;
|
status = B_OK;
|
||||||
|
|
||||||
if (status == B_OK)
|
if (status == B_OK)
|
||||||
|
|||||||
Reference in New Issue
Block a user