/*
 * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
 * Distributed under the terms of the MIT License.
 */
#ifndef UNIX_ADDRESS_MANAGER_H
#define UNIX_ADDRESS_MANAGER_H
 
#include <lock.h>
#include <util/OpenHashTable.h>
 
#include "UnixAddress.h"
#include "UnixEndpoint.h"
 
 
struct UnixAddressHashDefinition {
	typedef UnixAddress		KeyType;
	typedef UnixEndpoint	ValueType;
 
	size_t HashKey(const KeyType& key) const
	{
		return key.HashCode();
	}
 
	size_t Hash(UnixEndpoint* endpoint) const
	{
		return HashKey(endpoint->Address());
	}
 
	bool Compare(const KeyType& key, UnixEndpoint* endpoint) const
	{
		return key == endpoint->Address();
	}
 
	UnixEndpoint*& GetLink(UnixEndpoint* endpoint) const
	{
		return endpoint->HashTableLink();
	}
};
 
 
class UnixAddressManager {
public:
	UnixAddressManager()
	{
		mutex_init(&fLock, "unix address manager");
	}
 
	~UnixAddressManager()
	{
		mutex_destroy(&fLock);
	}
 
	status_t Init()
	{
		return fBoundEndpoints.Init();
	}
 
	bool Lock()
	{
		return mutex_lock(&fLock) == B_OK;
	}
 
	void Unlock()
	{
		mutex_unlock(&fLock);
	}
 
	UnixEndpoint* Lookup(const UnixAddress& address) const
	{
		return fBoundEndpoints.Lookup(address);
	}
 
	void Add(UnixEndpoint* endpoint)
	{
		fBoundEndpoints.Insert(endpoint);
	}
 
	void Remove(UnixEndpoint* endpoint)
	{
		fBoundEndpoints.Remove(endpoint);
	}
 
	int32 NextInternalID()
	{
		int32 id = fNextInternalID;
		fNextInternalID = (id + 1) & 0xfffff;
		return id;
	}
 
	int32 NextUnusedInternalID()
	{
		for (int32 i = 0xfffff; i >= 0; i--) {
			int32 id = NextInternalID();
			UnixAddress address(id);
			if (Lookup(address) == NULL)
				return id;
		}
 
		return ENOBUFS;
	}
 
private:
	typedef BOpenHashTable<UnixAddressHashDefinition, false> EndpointTable;
 
	mutex			fLock;
	EndpointTable	fBoundEndpoints;
	int32			fNextInternalID;
};
 
 
typedef AutoLocker<UnixAddressManager> UnixAddressManagerLocker;
 
 
#endif	// UNIX_ADDRESS_MANAGER_H

V730 Not all members of a class are initialized inside the constructor. Consider inspecting: fNextInternalID.