xref: /haiku/src/add-ons/kernel/file_systems/nfs4/RPCCallbackServer.h (revision 02354704729d38c3b078c696adc1bbbd33cbcf72)
1 /*
2  * Copyright 2012-2013 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 RPCCALLBACKSERVER_H
9 #define RPCCALLBACKSERVER_H
10 
11 
12 #include <string.h>
13 #include <util/AutoLock.h>
14 
15 #include "Connection.h"
16 
17 
18 namespace RPC {
19 
20 class Callback;
21 class Server;
22 
23 struct ConnectionEntry {
24 	Connection*			fConnection;
25 	thread_id			fThread;
26 
27 	ConnectionEntry*	fNext;
28 	ConnectionEntry*	fPrev;
29 };
30 
31 union CallbackSlot {
32 	Callback*	fCallback;
33 	int32		fNext;
34 };
35 
36 class CallbackServer {
37 public:
38 							CallbackServer(int networkFamily);
39 							~CallbackServer();
40 
41 	static	CallbackServer*	Get(Server* server);
42 	static	void			ShutdownAll();
43 
44 			status_t		RegisterCallback(Callback* callback);
45 			status_t		UnregisterCallback(Callback* callback);
46 
47 	inline	PeerAddress		LocalID();
48 
49 protected:
50 			status_t		StartServer();
51 			status_t		StopServer();
52 
53 			status_t		NewConnection(Connection* connection);
54 			status_t		ReleaseConnection(ConnectionEntry* entry);
55 
56 	static	status_t		ListenerThreadLauncher(void* object);
57 			status_t		ListenerThread();
58 
59 	static	status_t		ConnectionThreadLauncher(void* object);
60 			status_t		ConnectionThread(ConnectionEntry* entry);
61 
62 	inline	Callback*		GetCallback(int32 id);
63 
64 private:
65 	static	mutex			fServerCreationLock;
66 	static	CallbackServer*	fServers[2];
67 
68 			mutex			fConnectionLock;
69 			ConnectionEntry*	fConnectionList;
70 			ConnectionListener*	fListener;
71 
72 			mutex			fThreadLock;
73 			thread_id		fThread;
74 			bool			fThreadRunning;
75 
76 			rw_lock			fArrayLock;
77 			CallbackSlot*	fCallbackArray;
78 			uint32			fArraySize;
79 			int32			fFreeSlot;
80 
81 			int				fNetworkFamily;
82 };
83 
84 
85 inline PeerAddress
86 CallbackServer::LocalID()
87 {
88 	PeerAddress address;
89 
90 	ASSERT(fListener != NULL);
91 
92 	memset(&address, 0, sizeof(address));
93 	fListener->GetLocalAddress(&address);
94 	return address;
95 }
96 
97 
98 inline Callback*
99 CallbackServer::GetCallback(int32 id)
100 {
101 	ReadLocker _(fArrayLock);
102 	if (id >= 0 && static_cast<uint32>(id) < fArraySize)
103 		return fCallbackArray[id].fCallback;
104 	return NULL;
105 }
106 
107 
108 }		// namespace RPC
109 
110 #endif	// RPCCALLBACKSERVER_H
111 
112