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
15struct 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	UnixEndpoint*& GetLink(UnixEndpoint* endpoint) const
35	{
36		return endpoint->HashTableLink();
37	}
38};
39
40
41class UnixAddressManager {
42public:
43	UnixAddressManager()
44	{
45		mutex_init(&fLock, "unix address manager");
46	}
47
48	~UnixAddressManager()
49	{
50		mutex_destroy(&fLock);
51	}
52
53	status_t Init()
54	{
55		return fBoundEndpoints.Init();
56	}
57
58	bool Lock()
59	{
60		return mutex_lock(&fLock) == B_OK;
61	}
62
63	void Unlock()
64	{
65		mutex_unlock(&fLock);
66	}
67
68	UnixEndpoint* Lookup(const UnixAddress& address) const
69	{
70		return fBoundEndpoints.Lookup(address);
71	}
72
73	void Add(UnixEndpoint* endpoint)
74	{
75		fBoundEndpoints.Insert(endpoint);
76	}
77
78	void Remove(UnixEndpoint* endpoint)
79	{
80		fBoundEndpoints.Remove(endpoint);
81	}
82
83	int32 NextInternalID()
84	{
85		int32 id = fNextInternalID;
86		fNextInternalID = (id + 1) & 0xfffff;
87		return id;
88	}
89
90	int32 NextUnusedInternalID()
91	{
92		for (int32 i = 0xfffff; i >= 0; i--) {
93			int32 id = NextInternalID();
94			UnixAddress address(id);
95			if (Lookup(address) == NULL)
96				return id;
97		}
98
99		return ENOBUFS;
100	}
101
102private:
103	typedef BOpenHashTable<UnixAddressHashDefinition, false> EndpointTable;
104
105	mutex			fLock;
106	EndpointTable	fBoundEndpoints;
107	int32			fNextInternalID;
108};
109
110
111typedef AutoLocker<UnixAddressManager> UnixAddressManagerLocker;
112
113
114#endif	// UNIX_ADDRESS_MANAGER_H
115