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