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 21 TargetHostInterfaceRoster::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 33 TargetHostInterfaceRoster::~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* 49 TargetHostInterfaceRoster::Default() 50 { 51 return sDefaultInstance; 52 } 53 54 55 /*static*/ status_t 56 TargetHostInterfaceRoster::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 81 TargetHostInterfaceRoster::DeleteDefault() 82 { 83 TargetHostInterfaceRoster* roster = sDefaultInstance; 84 sDefaultInstance = NULL; 85 delete roster; 86 } 87 88 89 status_t 90 TargetHostInterfaceRoster::Init(Listener* listener) 91 { 92 fListener = listener; 93 return fLock.InitCheck(); 94 } 95 96 97 status_t 98 TargetHostInterfaceRoster::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 122 int32 123 TargetHostInterfaceRoster::CountInterfaceInfos() const 124 { 125 return fInterfaceInfos.CountItems(); 126 } 127 128 129 TargetHostInterfaceInfo* 130 TargetHostInterfaceRoster::InterfaceInfoAt(int32 index) const 131 { 132 return fInterfaceInfos.ItemAt(index); 133 } 134 135 136 status_t 137 TargetHostInterfaceRoster::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 162 int32 163 TargetHostInterfaceRoster::CountActiveInterfaces() const 164 { 165 return fActiveInterfaces.CountItems(); 166 } 167 168 169 TargetHostInterface* 170 TargetHostInterfaceRoster::ActiveInterfaceAt(int32 index) const 171 { 172 return fActiveInterfaces.ItemAt(index); 173 } 174 175 176 void 177 TargetHostInterfaceRoster::TeamDebuggerStarted(TeamDebugger* debugger) 178 { 179 fRunningTeamDebuggers++; 180 fListener->TeamDebuggerCountChanged(fRunningTeamDebuggers); 181 } 182 183 184 void 185 TargetHostInterfaceRoster::TeamDebuggerQuit(TeamDebugger* debugger) 186 { 187 fRunningTeamDebuggers--; 188 fListener->TeamDebuggerCountChanged(fRunningTeamDebuggers); 189 } 190 191 192 void 193 TargetHostInterfaceRoster::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 205 TargetHostInterfaceRoster::Listener::~Listener() 206 { 207 } 208 209 210 void 211 TargetHostInterfaceRoster::Listener::TeamDebuggerCountChanged(int32 count) 212 { 213 } 214