1/* 2 * Copyright 2001-2009, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5#ifndef USERLAND_FS_REQUEST_ALLOCATOR_H 6#define USERLAND_FS_REQUEST_ALLOCATOR_H 7 8#include <new> 9 10#include <OS.h> 11 12#include "Debug.h" 13#include "Requests.h" 14 15namespace UserlandFSUtil { 16 17class Port; 18 19// RequestAllocator 20class RequestAllocator { 21public: 22 RequestAllocator(Port* port); 23 ~RequestAllocator(); 24 25 status_t Init(Port* port); 26 void Uninit(); 27 28 status_t Error() const; 29 30 void FinishDeferredInit(); 31 32 status_t AllocateRequest(int32 size); 33 status_t ReadRequest(bigtime_t timeout); 34 35 Request* GetRequest() const; 36 int32 GetRequestSize() const; 37 38 status_t AllocateAddress(Address& address, int32 size, 39 int32 align, void** data, 40 bool deferredInit = false); 41 status_t AllocateData(Address& address, const void* data, 42 int32 size, int32 align, 43 bool deferredInit = false); 44 status_t AllocateString(Address& address, 45 const char* data, 46 bool deferredInit = false); 47// status_t SetAddress(Address& address, void* data, 48// int32 size = 0); 49 50private: 51 struct DeferredInitInfo { 52 Address* target; 53 uint8* data; // only if in port buffer 54 area_id area; // only if in area, otherwise -1 55 int32 offset; 56 int32 size; 57 bool inPortBuffer; 58 }; 59 60 status_t fError; 61 Port* fPort; 62 Request* fRequest; 63 int32 fRequestSize; 64 int32 fPortReservedOffset; 65 int32 fRequestOffset; 66 area_id fAllocatedAreas[MAX_REQUEST_ADDRESS_COUNT]; 67 int32 fAllocatedAreaCount; 68 DeferredInitInfo fDeferredInitInfos[MAX_REQUEST_ADDRESS_COUNT]; 69 int32 fDeferredInitInfoCount; 70 bool fRequestInPortBuffer; 71}; 72 73// AllocateRequest 74// Should be a member, but we don't have member templates on PPC. 75// TODO: Actually we seem to have. Check! 76template<typename SpecificRequest> 77status_t 78AllocateRequest(RequestAllocator& allocator, SpecificRequest** request) 79{ 80 if (!request) 81 RETURN_ERROR(B_BAD_VALUE); 82 status_t error = allocator.AllocateRequest(sizeof(SpecificRequest)); 83 if (error == B_OK) 84 *request = new(allocator.GetRequest()) SpecificRequest; 85 return error; 86} 87 88} // namespace UserlandFSUtil 89 90using UserlandFSUtil::RequestAllocator; 91using UserlandFSUtil::AllocateRequest; 92 93#endif // USERLAND_FS_REQUEST_ALLOCATOR_H 94