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