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