From 80048d7de375bf1a9f709393651c9d83844d655c Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Mon, 18 Aug 2008 22:59:56 +0000 Subject: [PATCH] * 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 --- src/system/kernel/device_manager/io_requests.cpp | 16 +++++++++++++--- src/system/kernel/device_manager/io_requests.h | 4 ++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/system/kernel/device_manager/io_requests.cpp b/src/system/kernel/device_manager/io_requests.cpp index b07e0aa58d..3fe8c62d64 100644 --- a/src/system/kernel/device_manager/io_requests.cpp +++ b/src/system/kernel/device_manager/io_requests.cpp @@ -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 IORequest::Init(off_t offset, void* buffer, size_t length, bool write, uint32 flags) @@ -663,13 +670,12 @@ IORequest::CreateSubRequest(off_t parentOffset, off_t offset, size_t length, } // create subrequest - IORequest* subRequest = (fFlags & B_VIP_IO_REQUEST) != 0 - ? new(vip_io_alloc) IORequest : new(std::nothrow) IORequest; + IORequest* subRequest = Create((fFlags & B_VIP_IO_REQUEST) != 0); if (subRequest == NULL) return B_NO_MEMORY; 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) { delete subRequest; return error; @@ -781,6 +787,7 @@ IORequest::NotifyFinished() status_t status = fStatus; size_t lastTransferredOffset = fRelativeParentOffset + fTransferSize; bool partialTransfer = status != B_OK || fPartialTransfer; + bool deleteRequest = (fFlags & B_DELETE_IO_REQUEST) != 0; // unblock waiters fFinishedCondition.NotifyAll(); @@ -798,6 +805,9 @@ IORequest::NotifyFinished() parent->SubRequestFinished(this, status, partialTransfer, lastTransferredOffset); } + + if (deleteRequest) + delete this; } diff --git a/src/system/kernel/device_manager/io_requests.h b/src/system/kernel/device_manager/io_requests.h index d26ad8fa26..c8018c9fd9 100644 --- a/src/system/kernel/device_manager/io_requests.h +++ b/src/system/kernel/device_manager/io_requests.h @@ -22,6 +22,7 @@ #define B_PHYSICAL_IO_REQUEST 0x01 /* buffer points to physical memory */ #define B_VIP_IO_REQUEST 0x02 /* used by the page writer -- make sure allocations won't fail */ +#define B_DELETE_IO_REQUEST 0x04 /* delete request when finished */ struct DMABuffer; struct IOOperation; @@ -193,6 +194,7 @@ typedef struct IORequest io_request; typedef status_t (*io_request_finished_callback)(void* data, io_request* request, status_t status, bool partialTransfer, size_t transferEndOffset); + // TODO: Return type: status_t -> void typedef status_t (*io_request_iterate_callback)(void* data, io_request* request, bool* _partialTransfer); @@ -201,6 +203,8 @@ struct IORequest : IORequestChunk, DoublyLinkedListLinkImpl { IORequest(); virtual ~IORequest(); + static IORequest* Create(bool vip); + status_t Init(off_t offset, void* buffer, size_t length, bool write, uint32 flags); status_t Init(off_t offset, const iovec* vecs,