/* * 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 #include #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(); } HashTableLink* GetLink(UnixEndpoint* endpoint) const { return endpoint->HashTableLink(); } }; class UnixAddressManager { public: UnixAddressManager() { fLock.sem = -1; } ~UnixAddressManager() { if (fLock.sem >= 0) benaphore_destroy(&fLock); } status_t Init() { status_t error = fBoundEndpoints.InitCheck(); if (error != B_OK) return error; return benaphore_init(&fLock, "unix address manager"); } bool Lock() { return benaphore_lock(&fLock) == B_OK; } void Unlock() { benaphore_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 OpenHashTable EndpointTable; benaphore fLock; EndpointTable fBoundEndpoints; int32 fNextInternalID; }; typedef AutoLocker UnixAddressManagerLocker; #endif // UNIX_ADDRESS_MANAGER_H