fixed SF# 1985180: Poco::Net::DNS multithreading issue

This commit is contained in:
Guenter Obiltschnig
2008-06-09 14:21:56 +00:00
parent b3d124f14a
commit 076c301460
4 changed files with 131 additions and 40 deletions

View File

@@ -1,7 +1,7 @@
// //
// DNS.h // DNS.h
// //
// $Id: //poco/svn/Net/include/Poco/Net/DNS.h#2 $ // $Id: //poco/Main/Net/include/Poco/Net/DNS.h#3 $
// //
// Library: Net // Library: Net
// Package: NetCore // Package: NetCore
@@ -59,7 +59,7 @@ class Net_API DNS
/// An internal DNS cache is used to speed up name lookups. /// An internal DNS cache is used to speed up name lookups.
{ {
public: public:
static const HostEntry& hostByName(const std::string& hostname); static HostEntry hostByName(const std::string& hostname);
/// Returns a HostEntry object containing the DNS information /// Returns a HostEntry object containing the DNS information
/// for the host with the given name. /// for the host with the given name.
/// ///
@@ -73,7 +73,7 @@ public:
/// ///
/// Throws an IOException in case of any other error. /// Throws an IOException in case of any other error.
static const HostEntry& hostByAddress(const IPAddress& address); static HostEntry hostByAddress(const IPAddress& address);
/// Returns a HostEntry object containing the DNS information /// Returns a HostEntry object containing the DNS information
/// for the host with the given IP address. /// for the host with the given IP address.
/// ///
@@ -84,7 +84,7 @@ public:
/// ///
/// Throws an IOException in case of any other error. /// Throws an IOException in case of any other error.
static const HostEntry& resolve(const std::string& address); static HostEntry resolve(const std::string& address);
/// Returns a HostEntry object containing the DNS information /// Returns a HostEntry object containing the DNS information
/// for the host with the given IP address or host name. /// for the host with the given IP address or host name.
/// ///
@@ -102,7 +102,7 @@ public:
/// Convenience method that calls resolve(address) and returns /// Convenience method that calls resolve(address) and returns
/// the first address from the HostInfo. /// the first address from the HostInfo.
static const HostEntry& thisHost(); static HostEntry thisHost();
/// Returns a HostEntry object containing the DNS information /// Returns a HostEntry object containing the DNS information
/// for this host. /// for this host.
/// ///

View File

@@ -1,7 +1,7 @@
// //
// HostEntry.h // HostEntry.h
// //
// $Id: //poco/svn/Net/include/Poco/Net/HostEntry.h#2 $ // $Id: //poco/Main/Net/include/Poco/Net/HostEntry.h#3 $
// //
// Library: Net // Library: Net
// Package: NetCore // Package: NetCore
@@ -43,6 +43,8 @@
#include "Poco/Net/Net.h" #include "Poco/Net/Net.h"
#include "Poco/Net/SocketDefs.h" #include "Poco/Net/SocketDefs.h"
#include "Poco/Net/IPAddress.h" #include "Poco/Net/IPAddress.h"
#include "Poco/RefCountedObject.h"
#include "Poco/AutoPtr.h"
#include <vector> #include <vector>
@@ -50,14 +52,60 @@ namespace Poco {
namespace Net { namespace Net {
class Net_API HostEntryImpl: public Poco::RefCountedObject
/// This class stores information about a host
/// such as host name, alias names and a list
/// of IP addresses.
///
/// This class is used internally by HostEntry and is not
/// intended for public use.
{
protected:
typedef std::vector<std::string> AliasList;
typedef std::vector<IPAddress> AddressList;
HostEntryImpl();
/// Creates an empty HostEntry.
HostEntryImpl(struct hostent* entry);
/// Creates the HostEntry from the data in a hostent structure.
#if defined(_WIN32) && defined(POCO_HAVE_IPv6)
HostEntryImpl(struct addrinfo* info);
/// Creates the HostEntry from the data in a Windows addrinfo structure.
#endif
~HostEntryImpl();
/// Destroys the HostEntryImpl.
const std::string& name() const;
/// Returns the canonical host name.
const AliasList& aliases() const;
/// Returns a vector containing alias names for
/// the host name.
const AddressList& addresses() const;
/// Returns a vector containing the IPAddresses
/// for the host.
private:
std::string _name;
AliasList _aliases;
AddressList _addresses;
friend class HostEntry;
};
class Net_API HostEntry class Net_API HostEntry
/// This class stores information about a host /// This class stores information about a host
/// such as host name, alias names and a list /// such as host name, alias names and a list
/// of IP addresses. /// of IP addresses.
{ {
public: public:
typedef std::vector<std::string> AliasList; typedef HostEntryImpl::AliasList AliasList;
typedef std::vector<IPAddress> AddressList; typedef HostEntryImpl::AddressList AddressList;
HostEntry(); HostEntry();
/// Creates an empty HostEntry. /// Creates an empty HostEntry.
@@ -94,33 +142,55 @@ public:
/// for the host. /// for the host.
private: private:
std::string _name; Poco::AutoPtr<HostEntryImpl> _pImpl;
AliasList _aliases;
AddressList _addresses;
}; };
// //
// inlines // inlines
// //
inline const std::string& HostEntry::name() const inline const std::string& HostEntryImpl::name() const
{ {
return _name; return _name;
} }
inline const HostEntry::AliasList& HostEntry::aliases() const inline const HostEntryImpl::AliasList& HostEntryImpl::aliases() const
{ {
return _aliases; return _aliases;
} }
inline const HostEntry::AddressList& HostEntry::addresses() const inline const HostEntryImpl::AddressList& HostEntryImpl::addresses() const
{ {
return _addresses; return _addresses;
} }
inline const std::string& HostEntry::name() const
{
return _pImpl->name();
}
inline const HostEntry::AliasList& HostEntry::aliases() const
{
return _pImpl->aliases();
}
inline const HostEntry::AddressList& HostEntry::addresses() const
{
return _pImpl->addresses();
}
inline void HostEntry::swap(HostEntry& other)
{
_pImpl.swap(other._pImpl);
}
inline void swap(HostEntry& h1, HostEntry& h2) inline void swap(HostEntry& h1, HostEntry& h2)
{ {
h1.swap(h2); h1.swap(h2);

View File

@@ -1,7 +1,7 @@
// //
// DNS.cpp // DNS.cpp
// //
// $Id: //poco/svn/Net/src/DNS.cpp#2 $ // $Id: //poco/Main/Net/src/DNS.cpp#9 $
// //
// Library: Net // Library: Net
// Package: NetCore // Package: NetCore
@@ -82,7 +82,7 @@ DNS::DNSCache DNS::_cache;
Poco::FastMutex DNS::_mutex; Poco::FastMutex DNS::_mutex;
const HostEntry& DNS::hostByName(const std::string& hostname) HostEntry DNS::hostByName(const std::string& hostname)
{ {
FastMutex::ScopedLock lock(_mutex); FastMutex::ScopedLock lock(_mutex);
@@ -118,7 +118,7 @@ const HostEntry& DNS::hostByName(const std::string& hostname)
} }
const HostEntry& DNS::hostByAddress(const IPAddress& address) HostEntry DNS::hostByAddress(const IPAddress& address)
{ {
FastMutex::ScopedLock lock(_mutex); FastMutex::ScopedLock lock(_mutex);
@@ -158,7 +158,7 @@ const HostEntry& DNS::hostByAddress(const IPAddress& address)
} }
const HostEntry& DNS::resolve(const std::string& address) HostEntry DNS::resolve(const std::string& address)
{ {
IPAddress ip; IPAddress ip;
if (IPAddress::tryParse(address, ip)) if (IPAddress::tryParse(address, ip))
@@ -170,7 +170,7 @@ const HostEntry& DNS::resolve(const std::string& address)
IPAddress DNS::resolveOne(const std::string& address) IPAddress DNS::resolveOne(const std::string& address)
{ {
const HostEntry& entry = resolve(address); HostEntry entry = resolve(address);
if (!entry.addresses().empty()) if (!entry.addresses().empty())
return entry.addresses()[0]; return entry.addresses()[0];
else else
@@ -178,7 +178,7 @@ IPAddress DNS::resolveOne(const std::string& address)
} }
const HostEntry& DNS::thisHost() HostEntry DNS::thisHost()
{ {
return hostByName(Environment::nodeName()); return hostByName(Environment::nodeName());
} }

View File

@@ -1,7 +1,7 @@
// //
// HostEntry.cpp // HostEntry.cpp
// //
// $Id: //poco/svn/Net/src/HostEntry.cpp#2 $ // $Id: //poco/Main/Net/src/HostEntry.cpp#8 $
// //
// Library: Net // Library: Net
// Package: NetCore // Package: NetCore
@@ -43,12 +43,17 @@ namespace Poco {
namespace Net { namespace Net {
HostEntry::HostEntry() //
// HostEntryImpl
//
HostEntryImpl::HostEntryImpl()
{ {
} }
HostEntry::HostEntry(struct hostent* entry) HostEntryImpl::HostEntryImpl(struct hostent* entry)
{ {
poco_check_ptr (entry); poco_check_ptr (entry);
@@ -77,7 +82,7 @@ HostEntry::HostEntry(struct hostent* entry)
#if defined(_WIN32) && defined(POCO_HAVE_IPv6) #if defined(_WIN32) && defined(POCO_HAVE_IPv6)
HostEntry::HostEntry(struct addrinfo* ainfo) HostEntryImpl::HostEntryImpl(struct addrinfo* ainfo)
{ {
poco_check_ptr (ainfo); poco_check_ptr (ainfo);
@@ -94,37 +99,53 @@ HostEntry::HostEntry(struct addrinfo* ainfo)
#endif #endif
HostEntry::HostEntry(const HostEntry& entry): HostEntryImpl::~HostEntryImpl()
_name(entry._name),
_aliases(entry._aliases),
_addresses(entry._addresses)
{ {
} }
HostEntry& HostEntry::operator = (const HostEntry& entry) //
// HostEntry
//
HostEntry::HostEntry():
_pImpl(new HostEntryImpl)
{ {
if (&entry != this)
{
_name = entry._name;
_aliases = entry._aliases;
_addresses = entry._addresses;
}
return *this;
} }
void HostEntry::swap(HostEntry& hostEntry) HostEntry::HostEntry(struct hostent* entry):
_pImpl(new HostEntryImpl(entry))
{ {
std::swap(_name, hostEntry._name);
std::swap(_aliases, hostEntry._aliases);
std::swap(_addresses, hostEntry._addresses);
} }
#if defined(_WIN32) && defined(POCO_HAVE_IPv6)
HostEntry::HostEntry(struct addrinfo* info):
_pImpl(new HostEntryImpl(info))
{
}
#endif
HostEntry::~HostEntry() HostEntry::~HostEntry()
{ {
} }
HostEntry::HostEntry(const HostEntry& entry):
_pImpl(entry._pImpl)
{
}
HostEntry& HostEntry::operator = (const HostEntry& entry)
{
HostEntry tmp(entry);
tmp.swap(*this);
return *this;
}
} } // namespace Poco::Net } } // namespace Poco::Net