1 /* 2 * Copyright 2016, 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 (!fInterfaceInfos.AddItem(info)) \ 100 return B_NO_MEMORY; \ 101 interfaceReference.Detach(); 102 103 REGISTER_INTERFACE_INFO(Local) 104 REGISTER_INTERFACE_INFO(Network) 105 106 return B_OK; 107 } 108 109 110 int32 111 TargetHostInterfaceRoster::CountInterfaceInfos() const 112 { 113 return fInterfaceInfos.CountItems(); 114 } 115 116 117 TargetHostInterfaceInfo* 118 TargetHostInterfaceRoster::InterfaceInfoAt(int32 index) const 119 { 120 return fInterfaceInfos.ItemAt(index); 121 } 122 123 124 status_t 125 TargetHostInterfaceRoster::CreateInterface(TargetHostInterfaceInfo* info, 126 Settings* settings, TargetHostInterface*& _interface) 127 { 128 // TODO: this should eventually verify that an active interface with 129 // matching settings/type doesn't already exist, and if so, return that 130 // directly rather than instantiating a new one, since i.e. the interface 131 // for the local host only requires one instance. 132 AutoLocker<TargetHostInterfaceRoster> locker(this); 133 TargetHostInterface* interface; 134 status_t error = info->CreateInterface(settings, interface); 135 if (error != B_OK) 136 return error; 137 138 error = interface->Run(); 139 if (error < B_OK || !fActiveInterfaces.AddItem(interface)) { 140 delete interface; 141 return B_NO_MEMORY; 142 } 143 144 interface->AddListener(this); 145 _interface = interface; 146 return B_OK; 147 } 148 149 150 int32 151 TargetHostInterfaceRoster::CountActiveInterfaces() const 152 { 153 return fActiveInterfaces.CountItems(); 154 } 155 156 157 TargetHostInterface* 158 TargetHostInterfaceRoster::ActiveInterfaceAt(int32 index) const 159 { 160 return fActiveInterfaces.ItemAt(index); 161 } 162 163 164 void 165 TargetHostInterfaceRoster::TeamDebuggerStarted(TeamDebugger* debugger) 166 { 167 fRunningTeamDebuggers++; 168 fListener->TeamDebuggerCountChanged(fRunningTeamDebuggers); 169 } 170 171 172 void 173 TargetHostInterfaceRoster::TeamDebuggerQuit(TeamDebugger* debugger) 174 { 175 fRunningTeamDebuggers--; 176 fListener->TeamDebuggerCountChanged(fRunningTeamDebuggers); 177 } 178 179 180 void 181 TargetHostInterfaceRoster::TargetHostInterfaceQuit( 182 TargetHostInterface* interface) 183 { 184 AutoLocker<TargetHostInterfaceRoster> locker(this); 185 fActiveInterfaces.RemoveItem(interface); 186 } 187 188 189 // #pragma mark - TargetHostInterfaceRoster::Listener 190 191 192 TargetHostInterfaceRoster::Listener::~Listener() 193 { 194 } 195 196 197 void 198 TargetHostInterfaceRoster::Listener::TeamDebuggerCountChanged(int32 count) 199 { 200 } 201