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