* Added B_DELETE_IO_REQUEST flag, which causes the IORequest to be

deleted automatically when it's finished.
* Added IORequest::Create() for creating a IORequest on the heap
  (respectively the VIP heap).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27054 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2008-08-18 22:59:56 +00:00
parent 1dfa5a7d2a
commit 80048d7de3
2 changed files with 17 additions and 3 deletions
@@ -586,6 +586,13 @@ IORequest::~IORequest()
} }
/* static */ IORequest*
IORequest::Create(bool vip)
{
return vip ? new(vip_io_alloc) IORequest : new(std::nothrow) IORequest;
}
status_t status_t
IORequest::Init(off_t offset, void* buffer, size_t length, bool write, IORequest::Init(off_t offset, void* buffer, size_t length, bool write,
uint32 flags) uint32 flags)
@@ -663,13 +670,12 @@ IORequest::CreateSubRequest(off_t parentOffset, off_t offset, size_t length,
} }
// create subrequest // create subrequest
IORequest* subRequest = (fFlags & B_VIP_IO_REQUEST) != 0 IORequest* subRequest = Create((fFlags & B_VIP_IO_REQUEST) != 0);
? new(vip_io_alloc) IORequest : new(std::nothrow) IORequest;
if (subRequest == NULL) if (subRequest == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
status_t error = subRequest->Init(offset, vecOffset, vecs + startVec, status_t error = subRequest->Init(offset, vecOffset, vecs + startVec,
endVec - startVec + 1, length, fIsWrite, fFlags); endVec - startVec + 1, length, fIsWrite, fFlags & ~B_DELETE_IO_REQUEST);
if (error != B_OK) { if (error != B_OK) {
delete subRequest; delete subRequest;
return error; return error;
@@ -781,6 +787,7 @@ IORequest::NotifyFinished()
status_t status = fStatus; status_t status = fStatus;
size_t lastTransferredOffset = fRelativeParentOffset + fTransferSize; size_t lastTransferredOffset = fRelativeParentOffset + fTransferSize;
bool partialTransfer = status != B_OK || fPartialTransfer; bool partialTransfer = status != B_OK || fPartialTransfer;
bool deleteRequest = (fFlags & B_DELETE_IO_REQUEST) != 0;
// unblock waiters // unblock waiters
fFinishedCondition.NotifyAll(); fFinishedCondition.NotifyAll();
@@ -798,6 +805,9 @@ IORequest::NotifyFinished()
parent->SubRequestFinished(this, status, partialTransfer, parent->SubRequestFinished(this, status, partialTransfer,
lastTransferredOffset); lastTransferredOffset);
} }
if (deleteRequest)
delete this;
} }
@@ -22,6 +22,7 @@
#define B_PHYSICAL_IO_REQUEST 0x01 /* buffer points to physical memory */ #define B_PHYSICAL_IO_REQUEST 0x01 /* buffer points to physical memory */
#define B_VIP_IO_REQUEST 0x02 /* used by the page writer -- make sure #define B_VIP_IO_REQUEST 0x02 /* used by the page writer -- make sure
allocations won't fail */ allocations won't fail */
#define B_DELETE_IO_REQUEST 0x04 /* delete request when finished */
struct DMABuffer; struct DMABuffer;
struct IOOperation; struct IOOperation;
@@ -193,6 +194,7 @@ typedef struct IORequest io_request;
typedef status_t (*io_request_finished_callback)(void* data, typedef status_t (*io_request_finished_callback)(void* data,
io_request* request, status_t status, bool partialTransfer, io_request* request, status_t status, bool partialTransfer,
size_t transferEndOffset); size_t transferEndOffset);
// TODO: Return type: status_t -> void
typedef status_t (*io_request_iterate_callback)(void* data, typedef status_t (*io_request_iterate_callback)(void* data,
io_request* request, bool* _partialTransfer); io_request* request, bool* _partialTransfer);
@@ -201,6 +203,8 @@ struct IORequest : IORequestChunk, DoublyLinkedListLinkImpl<IORequest> {
IORequest(); IORequest();
virtual ~IORequest(); virtual ~IORequest();
static IORequest* Create(bool vip);
status_t Init(off_t offset, void* buffer, size_t length, status_t Init(off_t offset, void* buffer, size_t length,
bool write, uint32 flags); bool write, uint32 flags);
status_t Init(off_t offset, const iovec* vecs, status_t Init(off_t offset, const iovec* vecs,