xref: /haiku/src/add-ons/kernel/file_systems/nfs4/RPCServer.h (revision be4c74ead31246bd9b332f83a9e298969385fc4e)
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 "RPCReply.h"
18 
19 
20 namespace RPC {
21 
22 struct Request {
23 	uint32				fXID;
24 	ConditionVariable	fEvent;
25 
26 	bool				fDone;
27 	Reply**				fReply;
28 	status_t			fError;
29 
30 	Request*			fNext;
31 };
32 
33 class RequestManager {
34 public:
35 						RequestManager();
36 						~RequestManager();
37 
38 			void		AddRequest(Request* req);
39 			Request*	FindRequest(uint32 xid);
40 
41 private:
42 			mutex		fLock;
43 			Request*	fQueueHead;
44 			Request*	fQueueTail;
45 
46 };
47 
48 class ProgramData {
49 public:
50 	virtual				~ProgramData() { }
51 };
52 
53 class Server {
54 public:
55 									Server(Connection* conn,
56 										ServerAddress* addr);
57 	virtual							~Server();
58 
59 			status_t				SendCall(Call* call, Reply** reply);
60 
61 			status_t				SendCallAsync(Call* call, Reply** reply,
62 										Request** request);
63 			status_t				ResendCallAsync(Call* call, Request* req);
64 	inline	status_t				WaitCall(Request* request,
65 										bigtime_t time = kWaitTime);
66 	inline	status_t				CancelCall(Request* request);
67 			status_t				WakeCall(Request* request);
68 
69 			status_t				Repair();
70 
71 	inline	const ServerAddress&	ID() const;
72 	inline	ServerAddress			LocalID() const;
73 
74 	inline	ProgramData*			PrivateData();
75 	inline	void					SetPrivateData(ProgramData* priv);
76 
77 private:
78 	inline	uint32					_GetXID();
79 
80 			status_t				_StartListening();
81 
82 			status_t				_Listener();
83 	static	status_t				_ListenerThreadStart(void* ptr);
84 
85 			thread_id				fThread;
86 			bool					fThreadCancel;
87 			status_t				fThreadError;
88 
89 			RequestManager			fRequests;
90 			Connection*				fConnection;
91 			const ServerAddress*	fAddress;
92 
93 			ProgramData*			fPrivateData;
94 
95 			vint32					fXID;
96 	static	const bigtime_t			kWaitTime	= 1000000;
97 };
98 
99 
100 inline status_t
101 Server::WaitCall(Request* request, bigtime_t time)
102 {
103 	if (request->fDone)
104 		return B_OK;
105 	return request->fEvent.Wait(B_RELATIVE_TIMEOUT, time);
106 }
107 
108 
109 inline status_t
110 Server::CancelCall(Request* request)
111 {
112 	fRequests.FindRequest(request->fXID);
113 	return B_OK;
114 }
115 
116 
117 inline const ServerAddress&
118 Server::ID() const
119 {
120 	return *fAddress;
121 }
122 
123 
124 inline ServerAddress
125 Server::LocalID() const
126 {
127 	ServerAddress addr;
128 	memset(&addr, 0, sizeof(addr));
129 	fConnection->GetLocalID(&addr);
130 	return addr;
131 }
132 
133 
134 inline ProgramData*
135 Server::PrivateData()
136 {
137 	return fPrivateData;
138 }
139 
140 
141 inline void
142 Server::SetPrivateData(ProgramData* priv)
143 {
144 	delete fPrivateData;
145 	fPrivateData = priv;
146 }
147 
148 
149 struct ServerNode {
150 	ServerAddress	fID;
151 	Server*			fServer;
152 	int				fRefCount;
153 
154 	ServerNode*		fLeft;
155 	ServerNode* 	fRight;
156 };
157 
158 class ServerManager {
159 public:
160 						ServerManager();
161 						~ServerManager();
162 
163 			status_t	Acquire(Server** pserv, uint32 ip, uint16 port,
164 								Transport proto,
165 								ProgramData* (*createPriv)(Server*));
166 			void		Release(Server* serv);
167 
168 private:
169 
170 			ServerNode*	_Find(const ServerAddress& id);
171 			void		_Delete(ServerNode* node);
172 			ServerNode*	_Insert(ServerNode* node);
173 
174 			ServerNode*	fRoot;
175 			mutex		fLock;
176 };
177 
178 }		// namespace RPC
179 
180 
181 #endif	// RPCSERVER_H
182 
183