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