xref: /haiku/src/kits/debugger/target_host_interface/TargetHostInterfaceRoster.cpp (revision 3995592cdf304335132305e27c40cbb0b1ac46e3)
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