1/* 2 * Copyright 2016-2017, Rene Gollent, rene@gollent.com. 3 * Distributed under the terms of the MIT License. 4 */ 5#include "TargetHostInterfaceRoster.h" 6 7#include <new> 8 9#include <AutoDeleter.h> 10#include <AutoLocker.h> 11 12#include "LocalTargetHostInterfaceInfo.h" 13#include "NetworkTargetHostInterfaceInfo.h" 14#include "TargetHostInterfaceInfo.h" 15 16 17/*static*/ TargetHostInterfaceRoster* 18 TargetHostInterfaceRoster::sDefaultInstance = NULL; 19 20 21TargetHostInterfaceRoster::TargetHostInterfaceRoster() 22 : 23 TargetHostInterface::Listener(), 24 fLock(), 25 fRunningTeamDebuggers(0), 26 fInterfaceInfos(20, false), 27 fActiveInterfaces(20, false), 28 fListener(NULL) 29{ 30} 31 32 33TargetHostInterfaceRoster::~TargetHostInterfaceRoster() 34{ 35 for (int32 i = 0; TargetHostInterfaceInfo* info 36 = fInterfaceInfos.ItemAt(i); i++) { 37 info->ReleaseReference(); 38 } 39 40 for (int32 i = 0; TargetHostInterface* interface 41 = fActiveInterfaces.ItemAt(i); i++) { 42 if (interface->Lock()) 43 interface->Quit(); 44 } 45} 46 47 48/*static*/ TargetHostInterfaceRoster* 49TargetHostInterfaceRoster::Default() 50{ 51 return sDefaultInstance; 52} 53 54 55/*static*/ status_t 56TargetHostInterfaceRoster::CreateDefault(Listener* listener) 57{ 58 if (sDefaultInstance != NULL) 59 return B_OK; 60 61 TargetHostInterfaceRoster* roster 62 = new(std::nothrow) TargetHostInterfaceRoster; 63 if (roster == NULL) 64 return B_NO_MEMORY; 65 ObjectDeleter<TargetHostInterfaceRoster> rosterDeleter(roster); 66 67 status_t error = roster->Init(listener); 68 if (error != B_OK) 69 return error; 70 71 error = roster->RegisterInterfaceInfos(); 72 if (error != B_OK) 73 return error; 74 75 sDefaultInstance = rosterDeleter.Detach(); 76 return B_OK; 77} 78 79 80/*static*/ void 81TargetHostInterfaceRoster::DeleteDefault() 82{ 83 TargetHostInterfaceRoster* roster = sDefaultInstance; 84 sDefaultInstance = NULL; 85 delete roster; 86} 87 88 89status_t 90TargetHostInterfaceRoster::Init(Listener* listener) 91{ 92 fListener = listener; 93 return fLock.InitCheck(); 94} 95 96 97status_t 98TargetHostInterfaceRoster::RegisterInterfaceInfos() 99{ 100 TargetHostInterfaceInfo* info = NULL; 101 BReference<TargetHostInterfaceInfo> interfaceReference; 102 103 #undef REGISTER_INTERFACE_INFO 104 #define REGISTER_INTERFACE_INFO(type) \ 105 info = new(std::nothrow) type##TargetHostInterfaceInfo; \ 106 if (info == NULL) \ 107 return B_NO_MEMORY; \ 108 interfaceReference.SetTo(info, true); \ 109 if (info->Init() != B_OK) \ 110 return B_NO_MEMORY; \ 111 if (!fInterfaceInfos.AddItem(info)) \ 112 return B_NO_MEMORY; \ 113 interfaceReference.Detach(); 114 115 REGISTER_INTERFACE_INFO(Local) 116 REGISTER_INTERFACE_INFO(Network) 117 118 return B_OK; 119} 120 121 122int32 123TargetHostInterfaceRoster::CountInterfaceInfos() const 124{ 125 return fInterfaceInfos.CountItems(); 126} 127 128 129TargetHostInterfaceInfo* 130TargetHostInterfaceRoster::InterfaceInfoAt(int32 index) const 131{ 132 return fInterfaceInfos.ItemAt(index); 133} 134 135 136status_t 137TargetHostInterfaceRoster::CreateInterface(TargetHostInterfaceInfo* info, 138 Settings* settings, TargetHostInterface*& _interface) 139{ 140 // TODO: this should eventually verify that an active interface with 141 // matching settings/type doesn't already exist, and if so, return that 142 // directly rather than instantiating a new one, since i.e. the interface 143 // for the local host only requires one instance. 144 AutoLocker<TargetHostInterfaceRoster> locker(this); 145 TargetHostInterface* interface; 146 status_t error = info->CreateInterface(settings, interface); 147 if (error != B_OK) 148 return error; 149 150 error = interface->Run(); 151 if (error < B_OK || !fActiveInterfaces.AddItem(interface)) { 152 delete interface; 153 return B_NO_MEMORY; 154 } 155 156 interface->AddListener(this); 157 _interface = interface; 158 return B_OK; 159} 160 161 162int32 163TargetHostInterfaceRoster::CountActiveInterfaces() const 164{ 165 return fActiveInterfaces.CountItems(); 166} 167 168 169TargetHostInterface* 170TargetHostInterfaceRoster::ActiveInterfaceAt(int32 index) const 171{ 172 return fActiveInterfaces.ItemAt(index); 173} 174 175 176void 177TargetHostInterfaceRoster::TeamDebuggerStarted(TeamDebugger* debugger) 178{ 179 fRunningTeamDebuggers++; 180 fListener->TeamDebuggerCountChanged(fRunningTeamDebuggers); 181} 182 183 184void 185TargetHostInterfaceRoster::TeamDebuggerQuit(TeamDebugger* debugger) 186{ 187 fRunningTeamDebuggers--; 188 fListener->TeamDebuggerCountChanged(fRunningTeamDebuggers); 189} 190 191 192void 193TargetHostInterfaceRoster::TargetHostInterfaceQuit( 194 TargetHostInterface* interface) 195{ 196 AutoLocker<TargetHostInterfaceRoster> locker(this); 197 fActiveInterfaces.RemoveItem(interface); 198 199} 200 201 202// #pragma mark - TargetHostInterfaceRoster::Listener 203 204 205TargetHostInterfaceRoster::Listener::~Listener() 206{ 207} 208 209 210void 211TargetHostInterfaceRoster::Listener::TeamDebuggerCountChanged(int32 count) 212{ 213} 214