xref: /haiku/headers/private/userlandfs/private/RequestAllocator.h (revision b19ee1e164ffad53dff3600cdac7e9781c636581)
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 
15 namespace UserlandFSUtil {
16 
17 class Port;
18 
19 // RequestAllocator
20 class RequestAllocator {
21 public:
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 
50 private:
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!
76 template<typename SpecificRequest>
77 status_t
AllocateRequest(RequestAllocator & allocator,SpecificRequest ** request)78 AllocateRequest(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 
90 using UserlandFSUtil::RequestAllocator;
91 using UserlandFSUtil::AllocateRequest;
92 
93 #endif	// USERLAND_FS_REQUEST_ALLOCATOR_H
94