xref: /haiku/src/add-ons/kernel/file_systems/nfs4/RPCServer.h (revision ad1a84af93a14af86a18703657150e59da5dffdc)
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 			Request*	fQueueHead;
45 			Request*	fQueueTail;
46 
47 };
48 
49 class ProgramData {
50 public:
51 	virtual	status_t	ProcessCallback(CallbackRequest* request,
52 							Connection* connection) = 0;
53 
54 	virtual				~ProgramData() { }
55 };
56 
57 class Server {
58 public:
59 									Server(Connection* connection,
60 										PeerAddress* address);
61 	virtual							~Server();
62 
63 			status_t				SendCallAsync(Call* call, Reply** reply,
64 										Request** request);
65 			status_t				ResendCallAsync(Call* call,
66 										Request* request);
67 
68 	inline	status_t				WaitCall(Request* request,
69 										bigtime_t time);
70 	inline	status_t				CancelCall(Request* request);
71 			status_t				WakeCall(Request* request);
72 
73 			status_t				Repair();
74 
75 	inline	const PeerAddress&	ID() const;
76 	inline	PeerAddress			LocalID() const;
77 
78 	inline	ProgramData*			PrivateData();
79 	inline	void					SetPrivateData(ProgramData* privateData);
80 
81 			Callback*				GetCallback();
82 
83 private:
84 	inline	uint32					_GetXID();
85 
86 			status_t				_StartListening();
87 
88 			status_t				_Listener();
89 	static	status_t				_ListenerThreadStart(void* object);
90 
91 			thread_id				fThread;
92 			bool					fThreadCancel;
93 			status_t				fThreadError;
94 
95 			RequestManager			fRequests;
96 			Connection*				fConnection;
97 			const PeerAddress*	fAddress;
98 
99 			ProgramData*			fPrivateData;
100 
101 			mutex					fCallbackLock;
102 			Callback*				fCallback;
103 
104 			uint32					fRepairCount;
105 			mutex					fRepairLock;
106 
107 			vint32					fXID;
108 };
109 
110 
111 inline status_t
112 Server::WaitCall(Request* request, bigtime_t time)
113 {
114 	if (request->fDone)
115 		return B_OK;
116 	return request->fEvent.Wait(B_RELATIVE_TIMEOUT, time);
117 }
118 
119 
120 inline status_t
121 Server::CancelCall(Request* request)
122 {
123 	fRequests.FindRequest(request->fXID);
124 	return B_OK;
125 }
126 
127 
128 inline const PeerAddress&
129 Server::ID() const
130 {
131 	return *fAddress;
132 }
133 
134 
135 inline PeerAddress
136 Server::LocalID() const
137 {
138 	PeerAddress addr;
139 	memset(&addr, 0, sizeof(addr));
140 	fConnection->GetLocalAddress(&addr);
141 	return addr;
142 }
143 
144 
145 inline ProgramData*
146 Server::PrivateData()
147 {
148 	return fPrivateData;
149 }
150 
151 
152 inline void
153 Server::SetPrivateData(ProgramData* privateData)
154 {
155 	delete fPrivateData;
156 	fPrivateData = privateData;
157 }
158 
159 
160 struct ServerNode {
161 	PeerAddress	fID;
162 	Server*			fServer;
163 	int				fRefCount;
164 
165 	ServerNode*		fLeft;
166 	ServerNode* 	fRight;
167 };
168 
169 class ServerManager {
170 public:
171 						ServerManager();
172 						~ServerManager();
173 
174 			status_t	Acquire(Server** _server, const PeerAddress& address,
175 								ProgramData* (*createPrivateData)(Server*));
176 			void		Release(Server* server);
177 
178 private:
179 
180 			ServerNode*	_Find(const PeerAddress& address);
181 			void		_Delete(ServerNode* node);
182 			ServerNode*	_Insert(ServerNode* node);
183 
184 			ServerNode*	fRoot;
185 			mutex		fLock;
186 };
187 
188 }		// namespace RPC
189 
190 
191 #endif	// RPCSERVER_H
192 
193