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