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
18namespace RPC {
19
20class Callback;
21class Server;
22
23struct ConnectionEntry {
24	Connection*			fConnection;
25	thread_id			fThread;
26
27	ConnectionEntry*	fNext;
28	ConnectionEntry*	fPrev;
29};
30
31union CallbackSlot {
32	Callback*	fCallback;
33	int32		fNext;
34};
35
36class CallbackServer {
37public:
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
49protected:
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
64private:
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
85inline PeerAddress
86CallbackServer::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
98inline Callback*
99CallbackServer::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