VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/HostDnsService.cpp@ 49241

Last change on this file since 49241 was 49235, checked in by vboxsync, 11 years ago

Main/HostDnsService: splits HostDnsService on "singleton" HostDnsMonitor
which monitors host changes and share DnsInformation to per HostImpl/VirtualBoxImpl objects
HostDnsMonitorProxy.

TODO: Win/Darwin parts might burn (not tested)
TODO: find good place to call HostDnsMonitor::shutdown() to stop
monitoring thread. (ref counting could be used on
HostDnsMonitor::addMonitorProxy and HostDnsMonitor::releaseMonitorProxy,
but it better to pausing monitoring on no --auto-shutdown launches of VBoxSVC).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.8 KB
Line 
1/* $Id: HostDnsService.cpp 49235 2013-10-22 18:56:03Z vboxsync $ */
2/** @file
3 * Base class fo Host DNS & Co services.
4 */
5
6/*
7 * Copyright (C) 2013 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#include <VBox/com/array.h>
19#include <VBox/com/ptr.h>
20#include <VBox/com/string.h>
21
22#include <iprt/cpp/utils.h>
23
24#include "VirtualBoxImpl.h"
25#include <iprt/thread.h>
26#include <iprt/semaphore.h>
27#include <iprt/critsect.h>
28
29#include <algorithm>
30#include <string>
31#include <vector>
32#include "HostDnsService.h"
33
34
35static HostDnsMonitor *g_monitor;
36
37
38/* Lockee */
39Lockee::Lockee(){ RTCritSectInit(&mLock);}
40
41
42Lockee::~Lockee(){RTCritSectDelete(&mLock);}
43
44
45const RTCRITSECT* Lockee::lock() const {return &mLock;}
46
47/* ALock */
48ALock::ALock(const Lockee *l):lck(l)
49{
50 RTCritSectEnter(const_cast<PRTCRITSECT>(lck->lock()));
51}
52
53ALock::~ALock()
54{
55 RTCritSectLeave(const_cast<PRTCRITSECT>(lck->lock()));
56}
57
58
59
60inline static void detachVectorOfString(const std::vector<std::string>& v,
61 ComSafeArrayOut(BSTR, aBstrArray))
62{
63 com::SafeArray<BSTR> aBstr(v.size());
64
65 std::vector<std::string>::const_iterator it;
66
67 int i = 0;
68 it = v.begin();
69 for (; it != v.end(); ++it, ++i)
70 Utf8Str(it->c_str()).cloneTo(&aBstr[i]);
71
72 aBstr.detachTo(ComSafeArrayOutArg(aBstrArray));
73}
74
75
76struct HostDnsMonitor::Data
77{
78 std::vector<HostDnsMonitorProxy> proxies;
79 HostDnsInformation info;
80};
81
82
83struct HostDnsMonitorProxy::Data
84{
85 Data(const HostDnsMonitor* mon, const VirtualBox* vbox):
86 info(NULL), virtualbox(vbox), monitor(mon), fModified(true){}
87
88 virtual ~Data() {if (info) delete info;}
89
90 HostDnsInformation *info;
91 const VirtualBox *virtualbox;
92 const HostDnsMonitor* monitor;
93 bool fModified;
94};
95
96
97HostDnsMonitor::HostDnsMonitor():m(NULL){}
98
99
100HostDnsMonitor::~HostDnsMonitor(){if (m) delete m;}
101
102
103const HostDnsMonitor* HostDnsMonitor::getHostDnsMonitor()
104{
105 /* XXX: Moved initialization from HostImpl.cpp */
106 if (!g_monitor)
107 {
108 g_monitor =
109# if defined (RT_OS_DARWIN)
110 new HostDnsServiceDarwin();
111# elif defined(RT_OS_WINDOWS)
112 new HostDnsServiceWin();
113# elif defined(RT_OS_LINUX)
114 new HostDnsServiceLinux();
115# elif defined(RT_OS_SOLARIS)
116 new HostDnsServiceSolaris();
117# elif defined(RT_OS_OS2)
118 new HostDnsServiceOs2();
119# else
120 new HostDnsService();
121# endif
122 g_monitor->init();
123 }
124 return g_monitor;
125}
126
127
128void HostDnsMonitor::addMonitorProxy(const HostDnsMonitorProxy& proxy) const
129{
130 ALock l(this);
131 m->proxies.push_back(proxy);
132
133 proxy.notify();
134}
135
136
137void HostDnsMonitor::releaseMonitorProxy(const HostDnsMonitorProxy& proxy) const
138{
139 ALock l(this);
140 std::vector<HostDnsMonitorProxy>::iterator it;
141 it = std::find(m->proxies.begin(), m->proxies.end(), proxy);
142
143 if (it == m->proxies.end())
144 return;
145
146 m->proxies.erase(it);
147}
148
149
150void HostDnsMonitor::shutdown()
151{
152 if (g_monitor)
153 {
154 delete g_monitor;
155 g_monitor = NULL;
156 }
157}
158
159
160const HostDnsInformation& HostDnsMonitor::getInfo() const
161{
162 ALock l(this);
163 return m->info;
164}
165
166
167void HostDnsMonitor::notifyAll() const
168{
169 ALock l(this);
170 std::vector<HostDnsMonitorProxy>::const_iterator it;
171 for (it = m->proxies.begin(); it != m->proxies.end(); ++it)
172 it->notify();
173}
174
175
176void HostDnsMonitor::setInfo(const HostDnsInformation& info)
177{
178 ALock l(this);
179 m->info = info;
180}
181
182
183HRESULT HostDnsMonitor::init()
184{
185 m = new HostDnsMonitor::Data();
186 return S_OK;
187}
188
189/* HostDnsMonitorProxy */
190HostDnsMonitorProxy::HostDnsMonitorProxy():m(NULL){}
191
192HostDnsMonitorProxy::~HostDnsMonitorProxy()
193{
194 if (m && m->monitor)
195 {
196 m->monitor->releaseMonitorProxy(*this);
197 delete m;
198 }
199}
200
201
202void HostDnsMonitorProxy::init(const HostDnsMonitor* mon, const VirtualBox* aParent)
203{
204 m = new HostDnsMonitorProxy::Data(mon, aParent);
205 m->monitor->addMonitorProxy(*this);
206 updateInfo();
207}
208
209
210void HostDnsMonitorProxy::notify() const
211{
212 m->fModified = true;
213 const_cast<VirtualBox *>(m->virtualbox)->onHostNameResolutionConfigurationChange();
214}
215
216
217STDMETHODIMP HostDnsMonitorProxy::COMGETTER(NameServers)(ComSafeArrayOut(BSTR, aNameServers))
218{
219 AssertReturn(m && m->info, E_FAIL);
220 ALock l(this);
221
222 if (m->fModified)
223 updateInfo();
224
225 detachVectorOfString(m->info->servers, ComSafeArrayOutArg(aNameServers));
226
227 return S_OK;
228}
229
230
231STDMETHODIMP HostDnsMonitorProxy::COMGETTER(DomainName)(BSTR *aDomainName)
232{
233 AssertReturn(m && m->info, E_FAIL);
234 ALock l(this);
235
236 if (m->fModified)
237 updateInfo();
238
239 Utf8Str(m->info->domain.c_str()).cloneTo(aDomainName);
240
241 return S_OK;
242}
243
244
245STDMETHODIMP HostDnsMonitorProxy::COMGETTER(SearchStrings)(ComSafeArrayOut(BSTR, aSearchStrings))
246{
247 AssertReturn(m && m->info, E_FAIL);
248 ALock l(this);
249
250 if (m->fModified)
251 updateInfo();
252
253 detachVectorOfString(m->info->searchList, ComSafeArrayOutArg(aSearchStrings));
254
255 return S_OK;
256}
257
258
259bool HostDnsMonitorProxy::operator==(const HostDnsMonitorProxy& rhs)
260{
261 if (!m || rhs.m) return false;
262
263 /**
264 * we've assigned to the same instance of VirtualBox.
265 */
266 return m->virtualbox == rhs.m->virtualbox;
267}
268
269void HostDnsMonitorProxy::updateInfo()
270{
271 HostDnsInformation *i = new HostDnsInformation(m->monitor->getInfo());
272 HostDnsInformation *old = m->info;
273
274 if (old)
275 {
276 m->info = i;
277 delete old;
278 }
279 else
280 m->info = i;
281
282 m->fModified = false;
283}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette