xref: /haiku/src/add-ons/kernel/file_systems/nfs4/RPCServer.h (revision d0f2d8282f3f59a1af7fe2d340d2af0cb36a9b20)
1 /*
2  * Copyright 2012 Haiku, Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Paweł Dziepak, pdziepak@quarnos.org
7  */
8 #ifndef RPCSERVER_H
9 #define RPCSERVER_H
10 
11 
12 #include <condition_variable.h>
13 #include <lock.h>
14 
15 #include "Connection.h"
16 #include "RPCCall.h"
17 #include "RPCCallback.h"
18 #include "RPCReply.h"
19 
20 
21 namespace RPC {
22 
23 struct Request {
24 	uint32				fXID;
25 	ConditionVariable	fEvent;
26 
27 	bool				fDone;
28 	Reply**				fReply;
29 	status_t			fError;
30 
31 	Request*			fNext;
32 };
33 
34 class RequestManager {
35 public:
36 						RequestManager();
37 						~RequestManager();
38 
39 			void		AddRequest(Request* request);
40 			Request*	FindRequest(uint32 xid);
41 
42 private:
43 			mutex		fLock;
44 
45 			// Neither SinglyLinkedList nor DoublyLinkedList is what we want
46 			// here. And DoublyLinkedQueue is not even a queue.
47 			Request*	fQueueHead;
48 			Request*	fQueueTail;
49 
50 };
51 
52 class ProgramData {
53 public:
54 	virtual	status_t	ProcessCallback(CallbackRequest* request,
55 							Connection* connection) = 0;
56 
~ProgramData()57 	virtual				~ProgramData() { }
58 };
59 
60 class Server {
61 public:
62 									Server(Connection* connection,
63 										PeerAddress* address);
64 	virtual							~Server();
65 
66 			status_t				SendCallAsync(Call* call, Reply** reply,
67 										Request** request);
68 			status_t				ResendCallAsync(Call* call,
69 										Request* request);
70 
71 	inline	status_t				WaitCall(Request* request,
72 										bigtime_t time);
73 	inline	status_t				CancelCall(Request* request);
74 			status_t				WakeCall(Request* request);
75 
76 			status_t				Repair();
77 
78 	inline	const PeerAddress&		ID() const;
79 	inline	PeerAddress				LocalID() const;
80 
81 	inline	ProgramData*			PrivateData();
82 	inline	void					SetPrivateData(ProgramData* privateData);
83 
84 			Callback*				GetCallback();
85 
86 private:
87 	inline	uint32					_GetXID();
88 
89 			status_t				_StartListening();
90 
91 			status_t				_Listener();
92 	static	status_t				_ListenerThreadStart(void* object);
93 
94 			thread_id				fThread;
95 			bool					fThreadCancel;
96 			status_t				fThreadError;
97 
98 			RequestManager			fRequests;
99 			Connection*				fConnection;
100 			const PeerAddress*		fAddress;
101 
102 			ProgramData*			fPrivateData;
103 
104 			mutex					fCallbackLock;
105 			Callback*				fCallback;
106 
107 			uint32					fRepairCount;
108 			mutex					fRepairLock;
109 
110 			int32					fXID;
111 };
112 
113 
114 inline status_t
WaitCall(Request * request,bigtime_t time)115 Server::WaitCall(Request* request, bigtime_t time)
116 {
117 	if (request->fDone)
118 		return B_OK;
119 	return request->fEvent.Wait(B_RELATIVE_TIMEOUT, time);
120 }
121 
122 
123 inline status_t
CancelCall(Request * request)124 Server::CancelCall(Request* request)
125 {
126 	fRequests.FindRequest(request->fXID);
127 	return B_OK;
128 }
129 
130 
131 inline const PeerAddress&
ID()132 Server::ID() const
133 {
134 	return *fAddress;
135 }
136 
137 
138 inline PeerAddress
LocalID()139 Server::LocalID() const
140 {
141 	PeerAddress addr;
142 	memset(&addr, 0, sizeof(addr));
143 	fConnection->GetLocalAddress(&addr);
144 	return addr;
145 }
146 
147 
148 inline ProgramData*
PrivateData()149 Server::PrivateData()
150 {
151 	return fPrivateData;
152 }
153 
154 
155 inline void
SetPrivateData(ProgramData * privateData)156 Server::SetPrivateData(ProgramData* privateData)
157 {
158 	delete fPrivateData;
159 	fPrivateData = privateData;
160 }
161 
162 
163 struct ServerNode {
164 	PeerAddress	fID;
165 	Server*			fServer;
166 	int				fRefCount;
167 
168 	ServerNode*		fLeft;
169 	ServerNode* 	fRight;
170 };
171 
172 class ServerManager {
173 public:
174 						ServerManager();
175 						~ServerManager();
176 
177 			status_t	Acquire(Server** _server, AddressResolver* resolver,
178 								ProgramData* (*createPrivateData)(Server*));
179 			void		Release(Server* server);
180 
181 private:
182 			status_t	_Acquire(Server** _server, const PeerAddress& address,
183 								ProgramData* (*createPrivateData)(Server*));
184 
185 			ServerNode*	_Find(const PeerAddress& address);
186 			void		_Delete(ServerNode* node);
187 			ServerNode*	_Insert(ServerNode* node);
188 
189 			ServerNode*	fRoot;
190 			mutex		fLock;
191 };
192 
193 }		// namespace RPC
194 
195 
196 #endif	// RPCSERVER_H
197 
198