xref: /haiku/src/add-ons/kernel/network/protocols/unix/UnixAddressManager.h (revision fc1ca2da5cfcb00ffdf791606d5ae97fdd58a638)
1 /*
2  * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef UNIX_ADDRESS_MANAGER_H
6 #define UNIX_ADDRESS_MANAGER_H
7 
8 #include <lock.h>
9 #include <util/OpenHashTable.h>
10 
11 #include "UnixAddress.h"
12 #include "UnixEndpoint.h"
13 
14 
15 struct UnixAddressHashDefinition {
16 	typedef UnixAddress		KeyType;
17 	typedef UnixEndpoint	ValueType;
18 
19 	size_t HashKey(const KeyType& key) const
20 	{
21 		return key.HashCode();
22 	}
23 
24 	size_t Hash(UnixEndpoint* endpoint) const
25 	{
26 		return HashKey(endpoint->Address());
27 	}
28 
29 	bool Compare(const KeyType& key, UnixEndpoint* endpoint) const
30 	{
31 		return key == endpoint->Address();
32 	}
33 
34 	HashTableLink<UnixEndpoint>* GetLink(UnixEndpoint* endpoint) const
35 	{
36 		return endpoint->HashTableLink();
37 	}
38 };
39 
40 
41 class UnixAddressManager {
42 public:
43 	UnixAddressManager()
44 	{
45 		fLock.sem = -1;
46 	}
47 
48 	~UnixAddressManager()
49 	{
50 		if (fLock.sem >= 0)
51 			benaphore_destroy(&fLock);
52 	}
53 
54 	status_t Init()
55 	{
56 		status_t error = fBoundEndpoints.InitCheck();
57 		if (error != B_OK)
58 			return error;
59 
60 		return benaphore_init(&fLock, "unix address manager");
61 	}
62 
63 	bool Lock()
64 	{
65 		return benaphore_lock(&fLock) == B_OK;
66 	}
67 
68 	void Unlock()
69 	{
70 		benaphore_unlock(&fLock);
71 	}
72 
73 	UnixEndpoint* Lookup(const UnixAddress& address) const
74 	{
75 		return fBoundEndpoints.Lookup(address);
76 	}
77 
78 	void Add(UnixEndpoint* endpoint)
79 	{
80 		fBoundEndpoints.Insert(endpoint);
81 	}
82 
83 	void Remove(UnixEndpoint* endpoint)
84 	{
85 		fBoundEndpoints.Remove(endpoint);
86 	}
87 
88 	int32 NextInternalID()
89 	{
90 		int32 id = fNextInternalID;
91 		fNextInternalID = (id + 1) & 0xfffff;
92 		return id;
93 	}
94 
95 	int32 NextUnusedInternalID()
96 	{
97 		for (int32 i = 0xfffff; i >= 0; i--) {
98 			int32 id = NextInternalID();
99 			UnixAddress address(id);
100 			if (Lookup(address) == NULL)
101 				return id;
102 		}
103 
104 		return ENOBUFS;
105 	}
106 
107 private:
108 	typedef OpenHashTable<UnixAddressHashDefinition, false> EndpointTable;
109 
110 	benaphore		fLock;
111 	EndpointTable	fBoundEndpoints;
112 	int32			fNextInternalID;
113 };
114 
115 
116 typedef AutoLocker<UnixAddressManager> UnixAddressManagerLocker;
117 
118 
119 #endif	// UNIX_ADDRESS_MANAGER_H
120