int Bind2Backend::s_first=1;
bool Bind2Backend::s_ignore_broken_records=false;
-pthread_rwlock_t Bind2Backend::s_state_lock=PTHREAD_RWLOCK_INITIALIZER;
-pthread_mutex_t Bind2Backend::s_supermaster_config_lock=PTHREAD_MUTEX_INITIALIZER; // protects writes to config file
-pthread_mutex_t Bind2Backend::s_startup_lock=PTHREAD_MUTEX_INITIALIZER;
+ReadWriteLock Bind2Backend::s_state_lock;
+std::mutex Bind2Backend::s_supermaster_config_lock; // protects writes to config file
+std::mutex Bind2Backend::s_startup_lock;
string Bind2Backend::s_binddirectory;
template <typename T>
(*ips).insert(str);
}
}
- ReadLock rl(&s_state_lock);
+ ReadLock rl(&s_state_lock);
for(state_t::const_iterator i = s_state.begin(); i != s_state.end() ; ++i) {
if(i->d_name == domain) {
for(set<string>::iterator it = i->d_also_notify.begin(); it != i->d_also_notify.end(); it++) {
if (!loadZones && d_hybrid)
return;
- Lock l(&s_startup_lock);
+ std::lock_guard<std::mutex> l(s_startup_lock);
setupDNSSEC();
if(!s_first) {
<< "' from supermaster " << ip << endl;
{
- Lock l2(&s_supermaster_config_lock);
+ std::lock_guard<std::mutex> l2(s_supermaster_config_lock);
ofstream c_of(getArg("supermaster-config").c_str(), std::ios::app);
if (!c_of) {
void getAllDomains(vector<DomainInfo> *domains, bool include_disabled=false) override;
static DNSBackend *maker();
- static pthread_mutex_t s_startup_lock;
+ static std::mutex s_startup_lock;
void setFresh(uint32_t domain_id) override;
void setNotified(uint32_t id, uint32_t serial) override;
ordered_unique<tag<NameTag>, member<BB2DomainInfo, DNSName, &BB2DomainInfo::d_name> >
> > state_t;
static state_t s_state;
- static pthread_rwlock_t s_state_lock;
+ static ReadWriteLock s_state_lock;
void parseZoneFile(BB2DomainInfo *bbd);
void rediscover(string *status=nullptr) override;
// for supermaster support
bool superMasterBackend(const string &ip, const DNSName &domain, const vector<DNSResourceRecord>&nsset, string *nameserver, string *account, DNSBackend **db) override;
- static pthread_mutex_t s_supermaster_config_lock;
+ static std::mutex s_supermaster_config_lock;
bool createSlaveDomain(const string &ip, const DNSName &domain, const string &nameserver, const string &account) override;
private:
#include <fstream>
#include <yaml-cpp/yaml.h>
-pthread_rwlock_t GeoIPBackend::s_state_lock=PTHREAD_RWLOCK_INITIALIZER;
+ReadWriteLock GeoIPBackend::s_state_lock;
struct GeoIPDNSResourceRecord: DNSResourceRecord {
int weight;
bool unpublishDomainKey(const DNSName& name, unsigned int id) override;
private:
- static pthread_rwlock_t s_state_lock;
+ static ReadWriteLock s_state_lock;
void initialize();
string format2str(string format, const Netmask &addr, GeoIPNetmask& gl);
static thread_local MySQLThreadCloser threadcloser;
bool SMySQL::s_dolog;
-pthread_mutex_t SMySQL::s_myinitlock = PTHREAD_MUTEX_INITIALIZER;
+std::mutex SMySQL::s_myinitlock;
class SMySQLStatement: public SSqlStatement
{
{
int retry=1;
- Lock l(&s_myinitlock);
+ std::lock_guard<std::mutex> l(s_myinitlock);
if (d_threadCleanup) {
threadcloser.enable();
}
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#pragma once
+#include <mutex>
+
#include <mysql.h>
#include "pdns/backends/gsql/ssql.hh"
#include "pdns/utility.hh"
void connect();
static bool s_dolog;
- static pthread_mutex_t s_myinitlock;
+ static std::mutex s_myinitlock;
MYSQL d_db;
std::string d_database;
}
LdapGssapiAuthenticator::LdapGssapiAuthenticator( const std::string& kt, const std::string &ccache, int tmout )
- : d_logPrefix( "[LDAP GSSAPI] " ), d_keytabFile( kt ), d_cCacheFile( ccache ), d_timeout( tmout )
+ : d_logPrefix( "[LDAP GSSAPI] " ), d_keytabFile( kt ), d_cCacheFile( ccache )
{
krb5_error_code code;
std::string d_logPrefix;
std::string d_keytabFile;
std::string d_cCacheFile;
- int d_timeout;
std::string d_lastError;
krb5_context d_context;
static string backendname="[TinyDNSBackend] ";
uint32_t TinyDNSBackend::s_lastId;
-pthread_mutex_t TinyDNSBackend::s_domainInfoLock=PTHREAD_MUTEX_INITIALIZER;
+std::mutex TinyDNSBackend::s_domainInfoLock;
TinyDNSBackend::TDI_suffix_t TinyDNSBackend::s_domainInfo;
vector<string> TinyDNSBackend::getLocations()
}
void TinyDNSBackend::getUpdatedMasters(vector<DomainInfo>* retDomains) {
- Lock l(&s_domainInfoLock); //TODO: We could actually lock less if we do it per suffix.
+ std::lock_guard<std::mutex> l(s_domainInfoLock); //TODO: We could actually lock less if we do it per suffix.
if (! s_domainInfo.count(d_suffix)) {
TDI_t tmp;
}
void TinyDNSBackend::setNotified(uint32_t id, uint32_t serial) {
- Lock l(&s_domainInfoLock);
+ std::lock_guard<std::mutex> l(s_domainInfoLock);
if (!s_domainInfo.count(d_suffix)) {
throw PDNSException("Can't get list of domains to set the serial.");
}
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/member.hpp>
+#include <mutex>
using namespace ::boost;
using namespace ::boost::multi_index;
string d_suffix;
// Statics
- static pthread_mutex_t s_domainInfoLock;
+ static std::mutex s_domainInfoLock;
static TDI_suffix_t s_domainInfo;
static uint32_t s_lastId; // used to give a domain an id.
};
AuthPacketCache::~AuthPacketCache()
{
try {
- vector<WriteLock*> locks;
+ vector<WriteLock> locks;
for(auto& mc : d_maps) {
- locks.push_back(new WriteLock(&mc.d_mut));
- }
- for(auto wl : locks) {
- delete wl;
+ locks.push_back(WriteLock(mc.d_mut));
}
+ locks.clear();
}
catch(...) {
}
struct MapCombo
{
MapCombo() {
- pthread_rwlock_init(&d_mut, nullptr);
}
~MapCombo() {
- pthread_rwlock_destroy(&d_mut);
}
MapCombo(const MapCombo&) = delete;
MapCombo& operator=(const MapCombo&) = delete;
void reserve(size_t numberOfEntries);
- pthread_rwlock_t d_mut;
+ ReadWriteLock d_mut;
cmap_t d_map;
};
AuthQueryCache::~AuthQueryCache()
{
try {
- vector<WriteLock*> locks;
+ vector<WriteLock> locks;
for(auto& mc : d_maps) {
- locks.push_back(new WriteLock(&mc.d_mut));
- }
- for(auto wl : locks) {
- delete wl;
+ locks.push_back(WriteLock(mc.d_mut));
}
+ locks.clear();
}
catch(...) {
}
struct MapCombo
{
MapCombo() {
- pthread_rwlock_init(&d_mut, nullptr);
}
~MapCombo() {
- pthread_rwlock_destroy(&d_mut);
}
MapCombo(const MapCombo &) = delete;
MapCombo & operator=(const MapCombo &) = delete;
void reserve(size_t numberOfEntries);
- pthread_rwlock_t d_mut;
+ ReadWriteLock d_mut;
cmap_t d_map;
};
_exit(1);
}
-static void* dummyThread(void *)
+static void dummyThread()
{
- void* ignore=0;
- pthread_exit(ignore);
}
static void triggerLoadOfLibraries()
{
- pthread_t tid;
- pthread_create(&tid, 0, dummyThread, 0);
- void* res;
- pthread_join(tid, &res);
+ std::thread dummy(dummyThread);
+ dummy.join();
}
void mainthread()
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+
+#include <set>
+#include <thread>
+#include <boost/utility.hpp>
+
#include "packetcache.hh"
#include "utility.hh"
#include "communicator.hh"
-#include <set>
-#include <boost/utility.hpp>
#include "dnsbackend.hh"
#include "ueberbackend.hh"
#include "packethandler.hh"
d_suck_sem.wait();
SuckRequest sr;
{
- Lock l(&d_lock);
+ std::lock_guard<std::mutex> l(d_lock);
if(d_suckdomains.empty())
continue;
_exit(1);
}
- pthread_t tid;
- pthread_create(&tid,0,&launchhelper,this); // Starts CommunicatorClass::mainloop()
- for(int n=0; n < ::arg().asNum("retrieval-threads", 1); ++n)
- pthread_create(&tid, 0, &retrieveLaunchhelper, this); // Starts CommunicatorClass::retrievalLoopThread()
+ std::thread mainT(std::bind(&CommunicatorClass::mainloop, this));
+ mainT.detach();
+
+ for(int n=0; n < ::arg().asNum("retrieval-threads", 1); ++n) {
+ std::thread retrieve(std::bind(&CommunicatorClass::retrievalLoopThread, this));
+ retrieve.detach();
+ }
d_preventSelfNotification = ::arg().mustDo("prevent-self-notification");
bool extraSlaveRefresh = false;
Utility::sleep(1);
{
- Lock l(&d_lock);
+ std::lock_guard<std::mutex> l(d_lock);
if (d_tocheck.size())
extraSlaveRefresh = true;
}
public:
CommunicatorClass()
{
- pthread_mutex_init(&d_lock,0);
- pthread_mutex_init(&d_holelock,0);
-
d_tickinterval=60;
d_masterschanged=d_slaveschanged=true;
d_nsock4 = -1;
void mainloop();
void retrievalLoopThread();
void sendNotification(int sock, const DNSName &domain, const ComboAddress& remote, uint16_t id, UeberBackend* B);
-
- static void *launchhelper(void *p)
- {
- static_cast<CommunicatorClass *>(p)->mainloop();
- return 0;
- }
- static void *retrieveLaunchhelper(void *p)
- {
- static_cast<CommunicatorClass *>(p)->retrievalLoopThread();
- return 0;
- }
bool notifyDomain(const DNSName &domain, UeberBackend* B);
private:
void loadArgsIntoSet(const char *listname, set<string> &listset);
void queueNotifyDomain(const DomainInfo& di, UeberBackend* B);
int d_nsock4, d_nsock6;
map<pair<DNSName,string>,time_t>d_holes;
- pthread_mutex_t d_holelock;
+ std::mutex d_holelock;
void suck(const DNSName &domain, const ComboAddress& remote);
void ixfrSuck(const DNSName &domain, const TSIGTriplet& tt, const ComboAddress& laddr, const ComboAddress& remote, std::unique_ptr<AuthLua4>& pdl,
ZoneStatus& zs, vector<DNSRecord>* axfr);
void slaveRefresh(PacketHandler *P);
void masterUpdateCheck(PacketHandler *P);
- pthread_mutex_t d_lock;
+ std::mutex d_lock;
UniQueue d_suckdomains;
set<DNSName> d_inprogress;
~RemoveSentinel()
{
try {
- Lock l(&d_cc->d_lock);
+ std::lock_guard<std::mutex> l(d_cc->d_lock);
d_cc->d_inprogress.erase(d_dn);
}
catch(...) {
DNSSECKeeper::keycache_t DNSSECKeeper::s_keycache;
DNSSECKeeper::metacache_t DNSSECKeeper::s_metacache;
-pthread_rwlock_t DNSSECKeeper::s_metacachelock = PTHREAD_RWLOCK_INITIALIZER;
-pthread_rwlock_t DNSSECKeeper::s_keycachelock = PTHREAD_RWLOCK_INITIALIZER;
+ReadWriteLock DNSSECKeeper::s_metacachelock;
+ReadWriteLock DNSSECKeeper::s_keycachelock;
AtomicCounter DNSSECKeeper::s_ops;
time_t DNSSECKeeper::s_last_prune;
size_t DNSSECKeeper::s_maxEntries = 0;
uint64_t DNSSECKeeper::dbdnssecCacheSizes(const std::string& str)
{
if(str=="meta-cache-size") {
- ReadLock l(&s_metacachelock);
+ ReadLock l(&s_metacachelock);
return s_metacache.size();
}
else if(str=="key-cache-size") {
#include <deque>
#include <queue>
#include <vector>
+#include <thread>
#include <pthread.h>
#include "threadname.hh"
#include <unistd.h>
MultiThreadDistributor(int n);
typedef std::function<void(std::unique_ptr<Answer>&)> callback_t;
int question(Question&, callback_t callback) override; //!< Submit a question to the Distributor
- static void* makeThread(void *); //!< helper function to create our n threads
+ void distribute(int n);
int getQueueSize() override {
return d_queued;
}
time_t d_last_started;
unsigned int d_overloadQueueLength, d_maxQueueLength;
int d_num_threads;
- std::atomic<unsigned int> d_queued{0}, d_running{0};
+ std::atomic<unsigned int> d_queued{0};
std::vector<std::pair<int,int>> d_pipes;
};
g_log<<Logger::Error<<"Distributor caught fatal exception: "<<AE.reason<<endl;
_exit(1);
}
+ catch(const std::exception& e) {
+ g_log<<Logger::Error<<"Distributor caught fatal exception: "<<e.what()<<endl;
+ _exit(1);
+ }
catch(...) {
g_log<<Logger::Error<<"Caught an unknown exception when creating backend, probably"<<endl;
_exit(1);
nextid=0;
d_last_started=time(0);
- pthread_t tid;
-
-
for(int i=0; i < n; ++i) {
int fds[2];
if(pipe(fds) < 0)
g_log<<Logger::Warning<<"About to create "<<n<<" backend threads for UDP"<<endl;
for(int i=0;i<n;i++) {
- pthread_create(&tid,0,&makeThread,static_cast<void *>(this));
+ std::thread t(std::bind(&MultiThreadDistributor<Answer,Question,Backend>::distribute, this, i));
+ t.detach();
Utility::usleep(50000); // we've overloaded mysql in the past :-)
}
g_log<<Logger::Warning<<"Done launching threads, ready to distribute questions"<<endl;
// start of a new thread
-template<class Answer, class Question, class Backend>void *MultiThreadDistributor<Answer,Question,Backend>::makeThread(void *p)
+template<class Answer, class Question, class Backend>void MultiThreadDistributor<Answer,Question,Backend>::distribute(int ournum)
{
setThreadName("pdns/distributo");
- pthread_detach(pthread_self());
- MultiThreadDistributor *us=static_cast<MultiThreadDistributor *>(p);
- int ournum=us->d_running++;
try {
std::unique_ptr<Backend> b= make_unique<Backend>(); // this will answer our questions
for(;;) {
QuestionData* tempQD = nullptr;
- if(read(us->d_pipes[ournum].first, &tempQD, sizeof(tempQD)) != sizeof(tempQD))
+ if(read(d_pipes.at(ournum).first, &tempQD, sizeof(tempQD)) != sizeof(tempQD))
unixDie("read");
- --us->d_queued;
+ --d_queued;
std::unique_ptr<QuestionData> QD = std::unique_ptr<QuestionData>(tempQD);
tempQD = nullptr;
std::unique_ptr<Answer> a = nullptr;
g_log<<Logger::Error<<"Distributor caught fatal exception: "<<AE.reason<<endl;
_exit(1);
}
+ catch(const std::exception& e) {
+ g_log<<Logger::Error<<"Distributor caught fatal exception: "<<e.what()<<endl;
+ _exit(1);
+ }
catch(...) {
g_log<<Logger::Error<<"Caught an unknown exception when creating backend, probably"<<endl;
_exit(1);
}
- return 0;
}
template<class Answer, class Question, class Backend>int SingleThreadDistributor<Answer,Question,Backend>::question(Question& q, callback_t callback)
QD->callback=callback;
++d_queued;
- if(write(d_pipes[QD->id % d_pipes.size()].second, &QD, sizeof(QD)) != sizeof(QD)) {
+ if(write(d_pipes.at(QD->id % d_pipes.size()).second, &QD, sizeof(QD)) != sizeof(QD)) {
--d_queued;
delete QD;
unixDie("write");
vector<string> parts;
stringtok(parts,instr,", ");
- for (const auto part : parts)
+ for (const auto& part : parts)
if (count(parts.begin(), parts.end(), part) > 1)
throw ArgException("Refusing to launch multiple backends with the same name '" + part + "', verify all 'launch' statements in your configuration");
#include "dolog.hh"
#include "dnscrypt.hh"
#include "dnswriter.hh"
-#include "lock.hh"
DNSCryptPrivateKey::DNSCryptPrivateKey()
{
DNSCryptContext::~DNSCryptContext() {
- pthread_rwlock_destroy(&d_lock);
}
DNSCryptContext::DNSCryptContext(const std::string& pName, const std::vector<CertKeyPaths>& certKeys): d_certKeyPaths(certKeys), providerName(pName)
{
- pthread_rwlock_init(&d_lock, 0);
-
reloadCertificates();
}
DNSCryptContext::DNSCryptContext(const std::string& pName, const DNSCryptCert& certificate, const DNSCryptPrivateKey& pKey): providerName(pName)
{
- pthread_rwlock_init(&d_lock, 0);
-
addNewCertificate(certificate, pKey);
}
#include <sodium.h>
#include "dnsname.hh"
+#include "lock.hh"
#define DNSCRYPT_PROVIDER_PUBLIC_KEY_SIZE (crypto_sign_ed25519_PUBLICKEYBYTES)
#define DNSCRYPT_PROVIDER_PRIVATE_KEY_SIZE (crypto_sign_ed25519_SECRETKEYBYTES)
void addNewCertificate(std::shared_ptr<DNSCryptCertificatePair>& newCert, bool reload=false);
- pthread_rwlock_t d_lock;
+ ReadWriteLock d_lock;
std::vector<std::shared_ptr<DNSCryptCertificatePair>> d_certs;
std::vector<CertKeyPaths> d_certKeyPaths;
DNSName providerName;
public:
CacheShard(): d_entriesCount(0)
{
- pthread_rwlock_init(&d_lock, nullptr);
}
CacheShard(const CacheShard& old): d_entriesCount(0)
{
- pthread_rwlock_init(&d_lock, nullptr);
- }
- ~CacheShard() {
- pthread_rwlock_destroy(&d_lock);
}
+
void setSize(size_t maxSize)
{
d_map.reserve(maxSize);
}
std::unordered_map<uint32_t,CacheValue> d_map;
- pthread_rwlock_t d_lock;
+ ReadWriteLock d_lock;
std::atomic<uint64_t> d_entriesCount;
};
}
// Latency histogram buckets
- output << "# HELP dnsdist_latency Histogram of responses by latency\n";
+ output << "# HELP dnsdist_latency Histogram of responses by latency (in miliseconds)\n";
output << "# TYPE dnsdist_latency histogram\n";
uint64_t latency_amounts = g_stats.latency0_1;
output << "dnsdist_latency_bucket{le=\"1\"} " << latency_amounts << "\n";
struct QueryCount {
QueryCount()
{
- pthread_rwlock_init(&queryLock, nullptr);
}
~QueryCount()
{
- pthread_rwlock_destroy(&queryLock);
}
QueryCountRecords records;
QueryCountFilter filter;
- pthread_rwlock_t queryLock;
+ ReadWriteLock queryLock;
bool enabled{false};
};
fd = -1;
}
}
- pthread_rwlock_destroy(&d_lock);
}
boost::uuids::uuid id;
std::vector<unsigned int> hashes;
- mutable pthread_rwlock_t d_lock;
+ mutable ReadWriteLock d_lock;
std::vector<int> sockets;
const std::string sourceItfName;
std::mutex socketsLock;
{
ServerPool()
{
- pthread_rwlock_init(&d_lock, nullptr);
}
~ServerPool()
{
- pthread_rwlock_destroy(&d_lock);
}
const std::shared_ptr<DNSDistPacketCache> getCache() const { return packetCache; };
private:
ServerPolicy::NumberedServerVector d_servers;
- pthread_rwlock_t d_lock;
+ ReadWriteLock d_lock;
bool d_useECS{false};
};
DownstreamState::DownstreamState(const ComboAddress& remote_, const ComboAddress& sourceAddr_, unsigned int sourceItf_, const std::string& sourceItfName_, size_t numberOfSockets, bool connect=true): sourceItfName(sourceItfName_), remote(remote_), sourceAddr(sourceAddr_), sourceItf(sourceItf_), name(remote_.toStringWithPort()), nameWithAddr(remote_.toStringWithPort())
{
- pthread_rwlock_init(&d_lock, nullptr);
id = getUniqueID();
threadStarted.clear();
CDBKVStore::CDBKVStore(const std::string& fname, time_t refreshDelay): d_fname(fname), d_refreshDelay(refreshDelay)
{
- pthread_rwlock_init(&d_lock, nullptr);
d_refreshing.clear();
time_t now = time(nullptr);
}
CDBKVStore::~CDBKVStore() {
- pthread_rwlock_destroy(&d_lock);
}
bool CDBKVStore::reload(const struct stat& st)
std::unique_ptr<CDB> d_cdb{nullptr};
std::string d_fname;
- pthread_rwlock_t d_lock;
+ ReadWriteLock d_lock;
time_t d_mtime{0};
time_t d_nextCheck{0};
time_t d_refreshDelay{0};
public:
TimedIPSetRule()
{
- pthread_rwlock_init(&d_lock4, 0);
- pthread_rwlock_init(&d_lock6, 0);
}
~TimedIPSetRule()
{
- pthread_rwlock_destroy(&d_lock4);
- pthread_rwlock_destroy(&d_lock6);
}
bool matches(const DNSQuestion* dq) const override
{
void cleanup()
{
- time_t now=time(0);
+ time_t now = time(nullptr);
{
WriteLock rl(&d_lock4);
};
std::unordered_map<IPv6, time_t, IPv6Hash> d_ip6s;
std::unordered_map<uint32_t, time_t> d_ip4s;
- mutable pthread_rwlock_t d_lock4;
- mutable pthread_rwlock_t d_lock6;
+ mutable ReadWriteLock d_lock4;
+ mutable ReadWriteLock d_lock6;
};
#include <atomic>
#include <fstream>
#include <cstring>
+#include <mutex>
#include <pthread.h>
#include <openssl/conf.h>
#if (OPENSSL_VERSION_NUMBER < 0x1010000fL || (defined LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2090100fL)
/* OpenSSL < 1.1.0 needs support for threading/locking in the calling application. */
-static pthread_mutex_t *openssllocks{nullptr};
+
+#include "lock.hh"
+static std::vector<std::mutex> openssllocks;
extern "C" {
static void openssl_pthreads_locking_callback(int mode, int type, const char *file, int line)
{
if (mode & CRYPTO_LOCK) {
- pthread_mutex_lock(&(openssllocks[type]));
+ openssllocks.at(type).lock();
} else {
- pthread_mutex_unlock(&(openssllocks[type]));
+ openssllocks.at(type).unlock();
}
}
static void openssl_thread_setup()
{
- openssllocks = (pthread_mutex_t*)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
-
- for (int i = 0; i < CRYPTO_num_locks(); i++)
- pthread_mutex_init(&(openssllocks[i]), NULL);
-
- CRYPTO_set_id_callback(openssl_pthreads_id_callback);
- CRYPTO_set_locking_callback(openssl_pthreads_locking_callback);
+ openssllocks = std::vector<std::mutex>(CRYPTO_num_locks());
+ CRYPTO_set_id_callback(&openssl_pthreads_id_callback);
+ CRYPTO_set_locking_callback(&openssl_pthreads_locking_callback);
}
static void openssl_thread_cleanup()
{
- CRYPTO_set_locking_callback(NULL);
-
- for (int i=0; i<CRYPTO_num_locks(); i++) {
- pthread_mutex_destroy(&(openssllocks[i]));
- }
-
- OPENSSL_free(openssllocks);
+ CRYPTO_set_locking_callback(nullptr);
+ openssllocks.clear();
}
#endif /* (OPENSSL_VERSION_NUMBER < 0x1010000fL || (defined LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2090100fL) */
OpenSSLTLSTicketKeysRing::OpenSSLTLSTicketKeysRing(size_t capacity)
{
- pthread_rwlock_init(&d_lock, nullptr);
d_ticketKeys.set_capacity(capacity);
}
OpenSSLTLSTicketKeysRing::~OpenSSLTLSTicketKeysRing()
{
- pthread_rwlock_destroy(&d_lock);
}
void OpenSSLTLSTicketKeysRing::addKey(std::shared_ptr<OpenSSLTLSTicketKey> newKey)
throw std::runtime_error("Error setting up TLS cipher preferences to '" + fe.d_tlsConfig.d_ciphers + "' (" + gnutls_strerror(rc) + ") on " + fe.d_addr.toStringWithPort());
}
- pthread_rwlock_init(&d_lock, nullptr);
-
try {
if (fe.d_tlsConfig.d_ticketKeyFile.empty()) {
handleTicketsKeyRotation(time(nullptr));
}
}
catch(const std::runtime_error& e) {
- pthread_rwlock_destroy(&d_lock);
throw std::runtime_error("Error generating tickets key for TLS context on " + fe.d_addr.toStringWithPort() + ": " + e.what());
}
}
virtual ~GnuTLSIOCtx() override
{
- pthread_rwlock_destroy(&d_lock);
-
d_creds.reset();
if (d_priorityCache) {
std::unique_ptr<gnutls_certificate_credentials_st, void(*)(gnutls_certificate_credentials_t)> d_creds;
gnutls_priority_t d_priorityCache{nullptr};
std::shared_ptr<GnuTLSTicketsKey> d_ticketsKey{nullptr};
- pthread_rwlock_t d_lock;
+ ReadWriteLock d_lock;
bool d_enableTickets{true};
};
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+
+#include <sys/types.h>
+#include <thread>
+
#include "packetcache.hh"
#include "utility.hh"
#include "dnsproxy.hh"
#include "pdnsexception.hh"
-#include <sys/types.h>
#include "dns.hh"
#include "logger.hh"
#include "statbag.hh"
DNSProxy::DNSProxy(const string &remote)
{
- pthread_mutex_init(&d_lock,0);
d_resanswers=S.getPointer("recursing-answers");
d_resquestions=S.getPointer("recursing-questions");
d_udpanswers=S.getPointer("udp-answers");
void DNSProxy::go()
{
- pthread_t tid;
- pthread_create(&tid,0,&launchhelper,this);
+ std::thread t(std::bind(&DNSProxy::mainloop, this));
+ t.detach();
}
//! look up qname target with r->qtype, plonk it in the answer section of 'r' with name aname
uint16_t id;
uint16_t qtype = r->qtype.getCode();
{
- Lock l(&d_lock);
+ std::lock_guard<std::mutex> l(d_lock);
id=getID_locked();
ConntrackEntry ce;
dnsheader d;
memcpy(&d,buffer,sizeof(d));
{
- Lock l(&d_lock);
+ std::lock_guard<std::mutex> l(d_lock);
#if BYTE_ORDER == BIG_ENDIAN
// this is needed because spoof ID down below does not respect the native byteorder
d.id = ( 256 * (uint16_t)buffer[1] ) + (uint16_t)buffer[0];
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#pragma once
-#include <pthread.h>
#include <map>
+#include <mutex>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
bool completePacket(std::unique_ptr<DNSPacket>& r, const DNSName& target,const DNSName& aname, const uint8_t scopeMask);
void mainloop(); //!< this is the main loop that receives reply packets and sends them out again
- static void *launchhelper(void *p)
- {
- static_cast<DNSProxy *>(p)->mainloop();
- return 0;
- }
bool recurseFor(DNSPacket* p);
private:
struct ConntrackEntry
AtomicCounter* d_resanswers;
AtomicCounter* d_udpanswers;
AtomicCounter* d_resquestions;
- pthread_mutex_t d_lock;
+ std::mutex d_lock;
map_t d_conntrack;
int d_sock;
int getID_locked();
#include "dnssecinfra.hh"
#include "dnsrecords.hh"
#include "ueberbackend.hh"
+#include "lock.hh"
using namespace ::boost::multi_index;
static keycache_t s_keycache;
static metacache_t s_metacache;
- static pthread_rwlock_t s_metacachelock;
- static pthread_rwlock_t s_keycachelock;
+ static ReadWriteLock s_metacachelock;
+ static ReadWriteLock s_keycachelock;
static AtomicCounter s_ops;
static time_t s_last_prune;
static size_t s_maxEntries;
#include "statbag.hh"
extern StatBag S;
-static pthread_rwlock_t g_signatures_lock = PTHREAD_RWLOCK_INITIALIZER;
+static ReadWriteLock g_signatures_lock;
typedef map<pair<string, string>, string> signaturecache_t;
static signaturecache_t g_signatures;
static int g_cacheweekno;
#include <boost/accumulators/statistics.hpp>
+#include <thread>
+
#include "dnsparser.hh"
#include "sstuff.hh"
#include "misc.hh"
vector<BenchQuery> g_queries;
-static void* worker(void*)
+static void worker()
{
setThreadName("dnstcpb/worker");
for(;;) {
doQuery(&g_queries[pos]); // this is safe as long as nobody *inserts* to g_queries
}
- return 0;
}
static void usage(po::options_description &desc) {
}
- std::vector<pthread_t> workers(numworkers);
+ std::vector<std::thread> workers;
+ workers.reserve(numworkers);
FILE* fp;
if(!g_vm.count("file"))
}
fclose(fp);
- for(unsigned int n = 0; n < numworkers; ++n) {
- pthread_create(&workers[n], 0, worker, 0);
+ for (unsigned int n = 0; n < numworkers; ++n) {
+ workers.push_back(std::thread(worker));
}
- for(unsigned int n = 0; n < numworkers; ++n) {
- void* status;
- pthread_join(workers[n], &status);
+ for (auto& w : workers) {
+ w.join();
}
using namespace boost::accumulators;
#include <sys/types.h>
#include <sys/un.h>
#include <dlfcn.h>
-#include <pthread.h>
#include <unistd.h>
#include <boost/algorithm/string.hpp>
#include <fcntl.h>
#include <unistd.h>
#include <boost/algorithm/string.hpp>
+#include <thread>
+
#include "misc.hh"
#include "dns.hh"
#include "arguments.hh"
void DynListener::go()
{
d_ppid=getpid();
- pthread_create(&d_tid,0,&DynListener::theListenerHelper,this);
-}
-
-void *DynListener::theListenerHelper(void *p)
-{
- setThreadName("pdns/ctrlListen");
- DynListener *us=static_cast<DynListener *>(p);
- us->theListener();
- g_log<<Logger::Error<<"Control listener aborted, please file a bug!"<<endl;
- return 0;
+ std::thread listener(std::bind(&DynListener::theListener,this));
+ listener.detach();
}
string DynListener::getLine()
void DynListener::theListener()
{
+ setThreadName("pdns/ctrlListen");
+
try {
signal(SIGPIPE,SIG_IGN);
#pragma once
#include <string>
#include <vector>
-#include <pthread.h>
#include <sys/types.h>
#include <errno.h>
#include <iostream>
~DynListener();
void go();
void theListener();
- static void *theListenerHelper(void *p);
typedef string g_funk_t(const vector<string> &parts, Utility::pid_t ppid); // guido!
typedef struct { g_funk_t *func; string args; string usage; } g_funkwithusage_t;
NetmaskGroup d_tcprange;
int d_s{-1};
int d_client{-1};
- pthread_t d_tid{0};
bool d_nonlocal;
bool d_tcp{false};
pid_t d_ppid{0};
dumpNamedPolicy(fp, pair.first + DNSName("rpz-nsdname.") + d_domain, pair.second);
}
- for (const auto pair : d_qpolAddr) {
+ for (const auto& pair : d_qpolAddr) {
dumpAddrPolicy(fp, pair.first, DNSName("rpz-client-ip.") + d_domain, pair.second);
}
- for (const auto pair : d_propolNSAddr) {
+ for (const auto& pair : d_propolNSAddr) {
dumpAddrPolicy(fp, pair.first, DNSName("rpz-nsip.") + d_domain, pair.second);
}
- for (const auto pair : d_postpolAddr) {
+ for (const auto& pair : d_postpolAddr) {
dumpAddrPolicy(fp, pair.first, DNSName("rpz-ip.") + d_domain, pair.second);
}
}
// we turn left on 0 and right on 1
int bits = 0;
- for(; node && bits < key.getBits(); bits++) {
+ for(; bits < key.getBits(); bits++) {
bool vall = key.getBit(-1-bits);
if (bits >= node->d_bits) {
private:
boost::circular_buffer<std::shared_ptr<OpenSSLTLSTicketKey> > d_ticketKeys;
- pthread_rwlock_t d_lock;
+ ReadWriteLock d_lock;
};
void* libssl_get_ticket_key_callback_data(SSL* s);
#include "misc.hh"
#include "pdnsexception.hh"
-extern bool g_singleThreaded;
-
-class Lock
+class ReadWriteLock
{
- pthread_mutex_t *d_lock;
public:
- Lock(const Lock& rhs) = delete;
- Lock& operator=(const Lock& rhs) = delete;
-
- Lock(pthread_mutex_t *lock) : d_lock(lock)
+ ReadWriteLock()
{
- if(g_singleThreaded)
- return;
-
- int err;
- if((err = pthread_mutex_lock(d_lock))) {
- errno = err;
- throw PDNSException("error acquiring lock: "+stringerror());
+ if (pthread_rwlock_init(&d_lock, nullptr) != 0) {
+ throw std::runtime_error("Error creating a read-write lock: " + stringerror());
}
}
- ~Lock()
- {
- if(g_singleThreaded)
- return;
- pthread_mutex_unlock(d_lock);
+ ~ReadWriteLock() {
+ /* might have been moved */
+ pthread_rwlock_destroy(&d_lock);
}
+
+ ReadWriteLock(const ReadWriteLock& rhs) = delete;
+ ReadWriteLock& operator=(const ReadWriteLock& rhs) = delete;
+
+ pthread_rwlock_t* getLock()
+ {
+ return &d_lock;
+ }
+
+private:
+ pthread_rwlock_t d_lock;
};
-class WriteLock
+class ReadLock
{
- pthread_rwlock_t *d_lock;
public:
+ ReadLock(ReadWriteLock& lock): ReadLock(lock.getLock())
+ {
+ }
- WriteLock(pthread_rwlock_t *lock) : d_lock(lock)
+ ReadLock(ReadWriteLock* lock): ReadLock(lock->getLock())
{
- if(g_singleThreaded)
- return;
+ }
+ ~ReadLock()
+ {
+ if(d_lock) // may have been moved
+ pthread_rwlock_unlock(d_lock);
+ }
+
+ ReadLock(ReadLock&& rhs)
+ {
+ d_lock = rhs.d_lock;
+ rhs.d_lock = nullptr;
+ }
+ ReadLock(const ReadLock& rhs) = delete;
+ ReadLock& operator=(const ReadLock& rhs) = delete;
+
+private:
+ ReadLock(pthread_rwlock_t *lock) : d_lock(lock)
+ {
int err;
- if((err = pthread_rwlock_wrlock(d_lock))) {
- throw PDNSException("error acquiring rwlock wrlock: "+stringerror(err));
+ if((err = pthread_rwlock_rdlock(d_lock))) {
+ throw PDNSException("error acquiring rwlock readlock: "+stringerror(err));
}
}
- ~WriteLock()
+
+ pthread_rwlock_t *d_lock;
+};
+
+class WriteLock
+{
+public:
+ WriteLock(ReadWriteLock& lock): WriteLock(lock.getLock())
+ {
+ }
+
+ WriteLock(ReadWriteLock* lock): WriteLock(lock->getLock())
{
- if(g_singleThreaded)
- return;
- if(d_lock) // might have been moved
- pthread_rwlock_unlock(d_lock);
}
WriteLock(WriteLock&& rhs)
d_lock = rhs.d_lock;
rhs.d_lock=0;
}
+
+ ~WriteLock()
+ {
+ if(d_lock) // might have been moved
+ pthread_rwlock_unlock(d_lock);
+ }
+
WriteLock(const WriteLock& rhs) = delete;
WriteLock& operator=(const WriteLock& rhs) = delete;
+private:
+ WriteLock(pthread_rwlock_t *lock) : d_lock(lock)
+ {
+ int err;
+ if((err = pthread_rwlock_wrlock(d_lock))) {
+ throw PDNSException("error acquiring rwlock wrlock: "+stringerror(err));
+ }
+ }
+
+ pthread_rwlock_t *d_lock;
};
-class TryWriteLock
+class TryReadLock
{
- pthread_rwlock_t *d_lock;
- bool d_havelock;
public:
- TryWriteLock(const TryWriteLock& rhs) = delete;
- TryWriteLock& operator=(const TryWriteLock& rhs) = delete;
-
- TryWriteLock(pthread_rwlock_t *lock) : d_lock(lock)
+ TryReadLock(ReadWriteLock& lock): TryReadLock(lock.getLock())
{
- if(g_singleThreaded) {
- d_havelock=true;
- return;
- }
+ }
- d_havelock=false;
- int err;
- if((err = pthread_rwlock_trywrlock(d_lock)) && err!=EBUSY) {
- throw PDNSException("error acquiring rwlock tryrwlock: "+stringerror(err));
- }
- d_havelock=(err==0);
+ TryReadLock(ReadWriteLock* lock): TryReadLock(lock->getLock())
+ {
}
- TryWriteLock(TryWriteLock&& rhs)
+ TryReadLock(TryReadLock&& rhs)
{
d_lock = rhs.d_lock;
rhs.d_lock = nullptr;
rhs.d_havelock = false;
}
-
- ~TryWriteLock()
+ ~TryReadLock()
{
- if(g_singleThreaded)
- return;
-
- if(d_havelock && d_lock) // we might be moved
+ if(d_havelock && d_lock)
pthread_rwlock_unlock(d_lock);
}
+
+ TryReadLock(const TryReadLock& rhs) = delete;
+ TryReadLock& operator=(const TryReadLock& rhs) = delete;
+
bool gotIt()
{
- if(g_singleThreaded)
- return true;
-
return d_havelock;
}
-};
-
-class TryReadLock
-{
- pthread_rwlock_t *d_lock;
- bool d_havelock;
-public:
- TryReadLock(const TryReadLock& rhs) = delete;
- TryReadLock& operator=(const TryReadLock& rhs) = delete;
+private:
TryReadLock(pthread_rwlock_t *lock) : d_lock(lock)
{
- if(g_singleThreaded) {
- d_havelock=true;
- return;
- }
-
int err;
if((err = pthread_rwlock_tryrdlock(d_lock)) && err!=EBUSY) {
throw PDNSException("error acquiring rwlock tryrdlock: "+stringerror(err));
}
d_havelock=(err==0);
}
- TryReadLock(TryReadLock&& rhs)
+
+ pthread_rwlock_t *d_lock;
+ bool d_havelock;
+};
+
+class TryWriteLock
+{
+public:
+ TryWriteLock(ReadWriteLock& lock): TryWriteLock(lock.getLock())
+ {
+ }
+
+ TryWriteLock(ReadWriteLock* lock): TryWriteLock(lock->getLock())
+ {
+ }
+
+ TryWriteLock(TryWriteLock&& rhs)
{
d_lock = rhs.d_lock;
rhs.d_lock = nullptr;
rhs.d_havelock = false;
}
- ~TryReadLock()
+ ~TryWriteLock()
{
- if(g_singleThreaded)
- return;
-
- if(d_havelock && d_lock)
+ if(d_havelock && d_lock) // we might be moved
pthread_rwlock_unlock(d_lock);
}
+
+ TryWriteLock(const TryWriteLock& rhs) = delete;
+ TryWriteLock& operator=(const TryWriteLock& rhs) = delete;
+
bool gotIt()
{
- if(g_singleThreaded)
- return true;
-
return d_havelock;
}
-};
-
-class ReadLock
-{
- pthread_rwlock_t *d_lock;
-public:
-
- ReadLock(pthread_rwlock_t *lock) : d_lock(lock)
+private:
+ TryWriteLock(pthread_rwlock_t *lock) : d_lock(lock)
{
- if(g_singleThreaded)
- return;
-
+ d_havelock=false;
int err;
- if((err = pthread_rwlock_rdlock(d_lock))) {
- throw PDNSException("error acquiring rwlock readlock: "+stringerror(err));
+ if((err = pthread_rwlock_trywrlock(d_lock)) && err!=EBUSY) {
+ throw PDNSException("error acquiring rwlock tryrwlock: "+stringerror(err));
}
- }
- ~ReadLock()
- {
- if(g_singleThreaded)
- return;
- if(d_lock) // may have been moved
- pthread_rwlock_unlock(d_lock);
+ d_havelock=(err==0);
}
- ReadLock(ReadLock&& rhs)
- {
- d_lock = rhs.d_lock;
- rhs.d_lock=0;
- }
- ReadLock(const ReadLock& rhs) = delete;
- ReadLock& operator=(const ReadLock& rhs) = delete;
+ pthread_rwlock_t *d_lock;
+ bool d_havelock;
};
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+
+#include <mutex>
+
#include "logger.hh"
#include "misc.hh"
#ifndef RECURSOR
#include "statbag.hh"
extern StatBag S;
#endif
-#include "lock.hh"
#include "namespaces.hh"
thread_local Logger::PerThread Logger::t_perThread;
return log;
}
-void Logger::log(const string &msg, Urgency u)
+void Logger::log(const string &msg, Urgency u) noexcept
{
#ifndef RECURSOR
bool mustAccount(false);
}
}
- static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
- Lock l(&m); // the C++-2011 spec says we need this, and OSX actually does
+ static std::mutex m;
+ std::lock_guard<std::mutex> l(m); // the C++-2011 spec says we need this, and OSX actually does
clog << string(buffer) + prefix + msg <<endl;
#ifndef RECURSOR
mustAccount=true;
}
#ifndef RECURSOR
- if(mustAccount)
- S.ringAccount("logmessages",msg);
+ if(mustAccount) {
+ try {
+ S.ringAccount("logmessages",msg);
+ }
+ catch (const runtime_error& e) {
+ cerr << e.what() << endl;
+ }
+ }
#endif
}
\param msg Message you wish to log
\param u Urgency of the message you wish to log
*/
- void log(const string &msg, Urgency u=Notice);
+ void log(const string &msg, Urgency u=Notice) noexcept;
void setFacility(int f){d_facility=f;open();} //!< Choose logging facility
void setFlag(int f){flags|=f;open();} //!< set a syslog flag
std::atomic<time_t> lastAccess{0};
};
- pthread_rwlock_t d_lock;
+ ReadWriteLock d_lock;
public:
IsUpOracle()
{
- pthread_rwlock_init(&d_lock, nullptr);
}
~IsUpOracle()
{
- pthread_rwlock_destroy(&d_lock);
}
bool isUp(const ComboAddress& remote, const opts_t& opts);
bool isUp(const ComboAddress& remote, const std::string& url, const opts_t& opts);
void CommunicatorClass::drillHole(const DNSName &domain, const string &ip)
{
- Lock l(&d_holelock);
+ std::lock_guard<std::mutex> l(d_holelock);
d_holes[make_pair(domain,ip)]=time(0);
}
bool CommunicatorClass::justNotified(const DNSName &domain, const string &ip)
{
- Lock l(&d_holelock);
+ std::lock_guard<std::mutex> l(d_holelock);
if(d_holes.find(make_pair(domain,ip))==d_holes.end()) // no hole
return false;
# include <sched.h>
#endif
-bool g_singleThreaded;
-
size_t writen2(int fd, const void *buf, size_t count)
{
const char *ptr = (char*)buf;
#if (OPENSSL_VERSION_NUMBER < 0x1010000fL || (defined LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2090100fL)
/* OpenSSL < 1.1.0 needs support for threading/locking in the calling application. */
-static pthread_mutex_t *openssllocks;
+
+#include "lock.hh"
+static std::vector<std::mutex> openssllocks;
extern "C" {
void openssl_pthreads_locking_callback(int mode, int type, const char *file, int line)
{
if (mode & CRYPTO_LOCK) {
- pthread_mutex_lock(&(openssllocks[type]));
+ openssllocks.at(type).lock();
- }else {
- pthread_mutex_unlock(&(openssllocks[type]));
+ } else {
+ openssllocks.at(type).unlock();
}
}
void openssl_thread_setup()
{
- openssllocks = (pthread_mutex_t*)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
-
- for (int i = 0; i < CRYPTO_num_locks(); i++)
- pthread_mutex_init(&(openssllocks[i]), NULL);
-
- CRYPTO_set_id_callback(openssl_pthreads_id_callback);
- CRYPTO_set_locking_callback(openssl_pthreads_locking_callback);
+ openssllocks = std::vector<std::mutex>(CRYPTO_num_locks());
+ CRYPTO_set_id_callback(&openssl_pthreads_id_callback);
+ CRYPTO_set_locking_callback(&openssl_pthreads_locking_callback);
}
void openssl_thread_cleanup()
{
- CRYPTO_set_locking_callback(NULL);
-
- for (int i=0; i<CRYPTO_num_locks(); i++) {
- pthread_mutex_destroy(&(openssllocks[i]));
- }
-
- OPENSSL_free(openssllocks);
+ CRYPTO_set_locking_callback(nullptr);
+ openssllocks.clear();
}
#ifndef HAVE_RSA_GET0_KEY
void tkeyHandler(const DNSPacket& p, std::unique_ptr<DNSPacket>& r); //<! process TKEY record, and adds TKEY record to (r)eply, or error code.
static AtomicCounter s_count;
- static pthread_mutex_t s_rfc2136lock;
+ static std::mutex s_rfc2136lock;
bool d_logDNSDetails;
bool d_doIPv6AdditionalProcessing;
bool d_doDNAME;
vector<DomainInfo> domainInfo;
B.getAllDomains(&domainInfo);
bool printHeader = true;
- for (auto const di : domainInfo) {
+ for (const auto& di : domainInfo) {
listKey(di, dk, printHeader);
printHeader = false;
}
cout<<endl;
for(const auto& m : metamap) {
- for(const auto i : m.second)
+ for(const auto& i : m.second)
cout << '\t' << m.first<<'\t' << i <<endl;
}
}
cout<<"DNSKEY algorithms supported by this installation of PowerDNS:"<<endl;
auto algosWithBackend = DNSCryptoKeyEngine::listAllAlgosWithBackend();
- for (auto const algoWithBackend : algosWithBackend){
+ for (const auto& algoWithBackend : algosWithBackend){
string algoName = DNSSECKeeper::algorithm2name(algoWithBackend.first);
cout<<std::to_string(algoWithBackend.first)<<" - "<<algoName;
if (cmds.size() == 2 && cmds[1] == "with-backend")
if (cmds.size() > 2) {
keys.assign(cmds.begin() + 2, cmds.end());
std::cout << "Metadata for '" << zone << "'" << endl;
- for(const string kind : keys) {
+ for(const auto& kind : keys) {
vector<string> meta;
meta.clear();
if (B.getDomainMetadata(zone, kind, meta)) {
#include <boost/format.hpp>
#include <p11-kit/p11-kit.h>
+#include <mutex>
+
#include "pdns/dnssecinfra.hh"
#include "pdns/logger.hh"
#include "pdns/pdnsexception.hh"
CK_SESSION_HANDLE d_session;
CK_SLOT_ID d_slot;
CK_RV d_err;
- pthread_mutex_t d_m;
+ std::mutex d_m;
void logError(const std::string& operation) const {
if (d_err) {
d_err(0)
{
CK_TOKEN_INFO tokenInfo;
- pthread_mutex_init(&(this->d_m), NULL);
- Lock l(&d_m);
+ std::lock_guard<std::mutex> l(d_m);
if ((d_err = d_functions->C_OpenSession(this->d_slot, CKF_SERIAL_SESSION|CKF_RW_SESSION, 0, 0, &(this->d_session)))) {
logError("C_OpenSession");
CK_FUNCTION_LIST* f() { return d_functions; }
- pthread_mutex_t *m() { return &d_m; }
+ std::mutex& m() { return d_m; }
static std::shared_ptr<Pkcs11Slot> GetSlot(const std::string& module, const string& tokenId);
static CK_RV HuntSlot(const string& tokenId, CK_SLOT_ID &slotId, _CK_SLOT_INFO* info, CK_FUNCTION_LIST* functions);
}
void LoadAttributes() {
- Lock l(d_slot->m());
+ std::lock_guard<std::mutex> l(d_slot->m());
std::vector<P11KitAttribute> attr;
std::vector<CK_OBJECT_HANDLE> key;
attr.push_back(P11KitAttribute(CKA_CLASS, (unsigned long)CKO_PRIVATE_KEY));
int GenerateKeyPair(CK_MECHANISM_PTR mechanism, std::vector<P11KitAttribute>& pubAttributes, std::vector<P11KitAttribute>& privAttributes, CK_OBJECT_HANDLE_PTR pubKey, CK_OBJECT_HANDLE_PTR privKey) {
{
- Lock l(d_slot->m());
+ std::lock_guard<std::mutex> l(d_slot->m());
size_t k;
std::unique_ptr<CK_ATTRIBUTE[]> pubAttr(new CK_ATTRIBUTE[pubAttributes.size()]);
}
int Sign(const std::string& data, std::string& result, CK_MECHANISM_PTR mechanism) {
- Lock l(d_slot->m());
+ std::lock_guard<std::mutex> l(d_slot->m());
CK_BYTE buffer[1024];
CK_ULONG buflen = sizeof buffer; // should be enough for most signatures.
}
int Verify(const std::string& data, const std::string& signature, CK_MECHANISM_PTR mechanism) {
- Lock l(d_slot->m());
+ std::lock_guard<std::mutex> l(d_slot->m());
if ((d_err = this->d_slot->f()->C_VerifyInit(d_slot->Session(), mechanism, d_public_key))) { logError("C_VerifyInit"); return d_err; }
d_err = this->d_slot->f()->C_Verify(d_slot->Session(), (unsigned char*)data.c_str(), data.size(), (unsigned char*)signature.c_str(), signature.size());
}
int Digest(const std::string& data, std::string& result, CK_MECHANISM_PTR mechanism) {
- Lock l(d_slot->m());
+ std::lock_guard<std::mutex> l(d_slot->m());
CK_BYTE buffer[1024];
CK_ULONG buflen = sizeof buffer; // should be enough for most digests
}
int DigestKey(std::string& result) {
- Lock l(d_slot->m());
+ std::lock_guard<std::mutex> l(d_slot->m());
CK_MECHANISM mech;
mech.mechanism = CKM_SHA_1;
}
int FindObjects(const std::vector<P11KitAttribute>& attributes, std::vector<CK_OBJECT_HANDLE>& objects, int maxobjects) {
- Lock l(d_slot->m());
+ std::lock_guard<std::mutex> l(d_slot->m());
return FindObjects2(attributes, objects, maxobjects);
}
int GetAttributeValue(const CK_OBJECT_HANDLE& object, std::vector<P11KitAttribute>& attributes)
{
- Lock l(d_slot->m());
+ std::lock_guard<std::mutex> l(d_slot->m());
return GetAttributeValue2(object, attributes);
}
vector<string> carbonServers;
{
- Lock l(&g_carbon_config_lock);
+ std::lock_guard<std::mutex> l(g_carbon_config_lock);
stringtok(carbonServers, arg()["carbon-server"], ", ");
namespace_name=arg()["carbon-namespace"];
hostname=arg()["carbon-ourname"];
enum class StatComponent { API, Carbon, RecControl, SNMP };
std::map<std::string, std::string> getAllStatsMap(StatComponent component);
-extern pthread_mutex_t g_carbon_config_lock;
+extern std::mutex g_carbon_config_lock;
std::vector<std::pair<DNSName, uint16_t> >* pleaseGetQueryRing();
std::vector<std::pair<DNSName, uint16_t> >* pleaseGetServfailQueryRing();
std::vector<std::pair<DNSName, uint16_t> >* pleaseGetBogusQueryRing();
#include "secpoll-recursor.hh"
#include "pubsuffix.hh"
#include "namespaces.hh"
-pthread_mutex_t g_carbon_config_lock=PTHREAD_MUTEX_INITIALIZER;
+std::mutex g_carbon_config_lock;
static map<string, const uint32_t*> d_get32bitpointers;
static map<string, const std::atomic<uint64_t>*> d_getatomics;
static map<string, function< uint64_t() > > d_get64bitmembers;
-static pthread_mutex_t d_dynmetricslock = PTHREAD_MUTEX_INITIALIZER;
+static std::mutex d_dynmetricslock;
static map<string, std::atomic<unsigned long>* > d_dynmetrics;
static std::map<StatComponent, std::set<std::string>> s_blacklistedStats;
std::atomic<unsigned long>* getDynMetric(const std::string& str)
{
- Lock l(&d_dynmetricslock);
+ std::lock_guard<std::mutex> l(d_dynmetricslock);
auto f = d_dynmetrics.find(str);
if(f != d_dynmetrics.end())
return f->second;
if(d_get64bitmembers.count(name))
return d_get64bitmembers.find(name)->second();
- Lock l(&d_dynmetricslock);
+ std::lock_guard<std::mutex> l(d_dynmetricslock);
auto f =rplookup(d_dynmetrics, name);
if(f)
return (*f)->load();
}
{
- Lock l(&d_dynmetricslock);
+ std::lock_guard<std::mutex> l(d_dynmetricslock);
for(const auto& a : d_dynmetrics) {
if (blacklistMap.count(a.first) == 0) {
ret.insert({a.first, std::to_string(*a.second)});
template<typename T>
static string doSetCarbonServer(T begin, T end)
{
- Lock l(&g_carbon_config_lock);
+ std::lock_guard<std::mutex> l(g_carbon_config_lock);
if(begin==end) {
::arg().set("carbon-server").clear();
return "cleared carbon-server setting\n";
int g_fd1[2], g_fd2[2];
FILE *g_fp;
-pthread_mutex_t g_guardian_lock = PTHREAD_MUTEX_INITIALIZER;
+std::mutex g_guardian_lock;
// The next two methods are not in dynhandler.cc because they use a few items declared in this file.
static string DLCycleHandler(const vector<string>&parts, pid_t ppid)
}
line.append(1,'\n');
- Lock l(&g_guardian_lock);
+ std::lock_guard<std::mutex> l(g_guardian_lock);
try {
writen2(g_fd1[1],line.c_str(),line.size()+1);
bool first=true;
cpid=0;
- pthread_mutex_lock(&g_guardian_lock);
+ g_guardian_lock.lock();
for(;;) {
int pid;
writePid();
}
- pthread_mutex_unlock(&g_guardian_lock);
+ g_guardian_lock.unlock();
int status;
cpid=pid;
for(;;) {
}
}
- pthread_mutex_lock(&g_guardian_lock);
+ g_guardian_lock.lock();
close(g_fd1[1]);
fclose(g_fp);
g_fp=0;
}
cerr<<" (";
bool first = true;
- for (auto const c : ::arg().getCommands()) {
+ for (const auto& c : ::arg().getCommands()) {
if (!first) {
cerr<<", ";
}
.. versionadded:: 4.2.0
- Comma separated list of netmasks
-- Default: 0.0.0.0/0, ::, !127.0.0.0/8, !10.0.0.0/8, !100.64.0.0/10, !169.254.0.0/16, !192.168.0.0/16, !172.16.0.0/12, !::1/128, !fc00::/7, !fe80::/10
+- Default: 0.0.0.0/0, ::/0, !127.0.0.0/8, !10.0.0.0/8, !100.64.0.0/10, !169.254.0.0/16, !192.168.0.0/16, !172.16.0.0/12, !::1/128, !fc00::/7, !fe80::/10
List of requestor netmasks for which the requestor IP Address should be used as the :rfc:`EDNS Client Subnet <7871>` for outgoing queries. Outgoing queries for requestors that do not match this list will use the `ecs-scope-zero-address`_ instead.
Valid incoming ECS values from `use-incoming-edns-subnet`_ are not replaced.
const uint16_t type = records[recordsCount - 1].d_type;
sortedRecords_t recordcontents;
- for (const auto record : records) {
+ for (const auto& record : records) {
if (record.d_name == name && record.d_type == type) {
recordcontents.insert(record.d_content);
}
#endif
#include <atomic>
-#include <condition_variable>
#include <queue>
+#include <mutex>
#include <thread>
#include "iputils.hh"
extern StatBag S;
extern CommunicatorClass Communicator;
-pthread_mutex_t PacketHandler::s_rfc2136lock=PTHREAD_MUTEX_INITIALIZER;
+std::mutex PacketHandler::s_rfc2136lock;
// Implement section 3.2.1 and 3.2.2 of RFC2136
int PacketHandler::checkUpdatePrerequisites(const DNSRecord *rr, DomainInfo *di) {
}
- Lock l(&s_rfc2136lock); //TODO: i think this lock can be per zone, not for everything
+ std::lock_guard<std::mutex> l(s_rfc2136lock); //TODO: i think this lock can be per zone, not for everything
g_log<<Logger::Info<<msgPrefix<<"starting transaction."<<endl;
if (!di.backend->startTransaction(p.qdomain, -1)) { // Not giving the domain_id means that we do not delete the existing records.
g_log<<Logger::Error<<msgPrefix<<"Backend for domain "<<p.qdomain<<" does not support transaction. Can't do Update packet."<<endl;
void CommunicatorClass::addSuckRequest(const DNSName &domain, const ComboAddress& master)
{
- Lock l(&d_lock);
+ std::lock_guard<std::mutex> l(d_lock);
SuckRequest sr;
sr.domain = domain;
sr.master = master;
grouped[{x.d_name, x.d_type}].second.push_back(x);
di.backend->startTransaction(domain, -1);
- for(const auto g : grouped) {
+ for(const auto& g : grouped) {
vector<DNSRecord> rrset;
{
DNSZoneRecord zrr;
void CommunicatorClass::suck(const DNSName &domain, const ComboAddress& remote)
{
{
- Lock l(&d_lock);
+ std::lock_guard<std::mutex> l(d_lock);
if(d_inprogress.count(domain)) {
return;
}
}
catch(ResolverException &re) {
{
- Lock l(&d_lock);
+ std::lock_guard<std::mutex> l(d_lock);
// The AXFR probably failed due to a problem on the master server. If SOA-checks against this master
// still succeed, we would constantly try to AXFR the zone. To avoid this, we add the zone to the list of
// failed slave-checks. This will suspend slave-checks (and subsequent AXFR) for this zone for some time.
void CommunicatorClass::addSlaveCheckRequest(const DomainInfo& di, const ComboAddress& remote)
{
- Lock l(&d_lock);
+ std::lock_guard<std::mutex> l(d_lock);
DomainInfo ours = di;
ours.backend = 0;
void CommunicatorClass::addTrySuperMasterRequest(const DNSPacket& p)
{
- Lock l(&d_lock);
+ std::lock_guard<std::mutex> l(d_lock);
DNSPacket ours = p;
if(d_potentialsupermasters.insert(ours).second)
d_any_sem.post(); // kick the loop!
vector<DomainNotificationInfo> sdomains;
set<DNSPacket, cmp> trysuperdomains;
{
- Lock l(&d_lock);
+ std::lock_guard<std::mutex> l(d_lock);
set<DomainInfo> requeue;
rdomains.reserve(d_tocheck.size());
for(const auto& di: d_tocheck) {
sdomains.reserve(rdomains.size());
DNSSECKeeper dk(B); // NOW HEAR THIS! This DK uses our B backend, so no interleaved access!
{
- Lock l(&d_lock);
+ std::lock_guard<std::mutex> l(d_lock);
domains_by_name_t& nameindex=boost::multi_index::get<IDTag>(d_suckdomains);
time_t now = time(0);
if(sdomains.empty())
{
if(d_slaveschanged) {
- Lock l(&d_lock);
+ std::lock_guard<std::mutex> l(d_lock);
g_log<<Logger::Warning<<"No new unfresh slave domains, "<<d_suckdomains.size()<<" queued for AXFR already, "<<d_inprogress.size()<<" in progress"<<endl;
}
d_slaveschanged = !rdomains.empty();
return;
}
else {
- Lock l(&d_lock);
+ std::lock_guard<std::mutex> l(d_lock);
g_log<<Logger::Warning<<sdomains.size()<<" slave domain"<<(sdomains.size()>1 ? "s" : "")<<" need"<<
(sdomains.size()>1 ? "" : "s")<<
" checking, "<<d_suckdomains.size()<<" queued for AXFR"<<endl;
if(!ssr.d_freshness.count(di.id)) { // If we don't have an answer for the domain
uint64_t newCount = 1;
- Lock l(&d_lock);
+ std::lock_guard<std::mutex> l(d_lock);
const auto failedEntry = d_failedSlaveRefresh.find(di.zone);
if (failedEntry != d_failedSlaveRefresh.end())
newCount = d_failedSlaveRefresh[di.zone].first + 1;
}
{
- Lock l(&d_lock);
+ std::lock_guard<std::mutex> l(d_lock);
const auto wasFailedDomain = d_failedSlaveRefresh.find(di.zone);
if (wasFailedDomain != d_failedSlaveRefresh.end())
d_failedSlaveRefresh.erase(di.zone);
}
};
-pthread_mutex_t s_testlock=PTHREAD_MUTEX_INITIALIZER;
+std::mutex s_testlock;
struct GetLockUncontendedTest
{
void operator()() const
{
- pthread_mutex_lock(&s_testlock);
- pthread_mutex_unlock(&s_testlock);
+ s_testlock.lock();
+ s_testlock.unlock();
}
};
void SSQLite3::execute(const string& query) {
char *errmsg;
- int rc;
- if (sqlite3_exec(m_pDB, query.c_str(), NULL, NULL, &errmsg) == SQLITE_BUSY) {
+ std::string errstr1;
+ int rc = sqlite3_exec(m_pDB, query.c_str(), nullptr, nullptr, &errmsg);
+ if (rc != SQLITE_OK) {
+ errstr1 = errmsg;
+ sqlite3_free(errmsg);
+ }
+ if (rc == SQLITE_BUSY) {
if (m_in_transaction) {
- std::string errstr(errmsg);
- sqlite3_free(errmsg);
- throw("Failed to execute query: " + errstr);
+ throw SSqlException("Failed to execute query: " + errstr1);
} else {
- if ((rc = sqlite3_exec(m_pDB, query.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) && rc != SQLITE_DONE && rc != SQLITE_ROW) {
- std::string errstr(errmsg);
+ rc = sqlite3_exec(m_pDB, query.c_str(), NULL, NULL, &errmsg);
+ std::string errstr2;
+ if (rc != SQLITE_OK) {
+ errstr2 = errmsg;
sqlite3_free(errmsg);
- throw("Failed to execute query: " + errstr);
+ throw SSqlException("Failed to execute query: " + errstr2);
}
}
+ } else if (rc != SQLITE_OK) {
+ throw SSqlException("Failed to execute query: " + errstr1);
}
}
// s_resolversForStub contains the ComboAddresses that are used by
// stubDoResolve
static vector<ComboAddress> s_resolversForStub;
-static pthread_rwlock_t s_resolversForStubLock = PTHREAD_RWLOCK_INITIALIZER;
+static ReadWriteLock s_resolversForStubLock;
static bool s_stubResolvConfigured = false;
// /etc/resolv.conf last modification time
\brief This file implements the tcpreceiver that receives and answers questions over TCP/IP
*/
-pthread_mutex_t TCPNameserver::s_plock = PTHREAD_MUTEX_INITIALIZER;
+std::mutex TCPNameserver::s_plock;
std::unique_ptr<Semaphore> TCPNameserver::d_connectionroom_sem{nullptr};
std::unique_ptr<PacketHandler> TCPNameserver::s_P{nullptr};
unsigned int TCPNameserver::d_maxTCPConnections = 0;
catch(PDNSException &ae) {
g_log<<Logger::Error<<"TCP server is unable to launch backends - will try again when questions come in: "<<ae.reason<<endl;
}
- pthread_create(&d_tid, 0, launcher, static_cast<void *>(this));
-}
-void *TCPNameserver::launcher(void *data)
-{
- static_cast<TCPNameserver *>(data)->thread();
- return 0;
+ std::thread th(std::bind(&TCPNameserver::thread, this));
+ th.detach();
}
// throws PDNSException if things didn't go according to plan, returns 0 if really 0 bytes were read
}
}
-void *TCPNameserver::doConnection(void *data)
+void TCPNameserver::doConnection(int fd)
{
setThreadName("pdns/tcpConnect");
std::unique_ptr<DNSPacket> packet;
- // Fix gcc-4.0 error (on AMD64)
- int fd=(int)(long)data; // gotta love C (generates a harmless warning on opteron)
ComboAddress remote;
socklen_t remotelen=sizeof(remote);
size_t transactions = 0;
start = time(NULL);
}
- pthread_detach(pthread_self());
if(getpeername(fd, (struct sockaddr *)&remote, &remotelen) < 0) {
g_log<<Logger::Warning<<"Received question from socket which had no remote address, dropping ("<<stringerror()<<")"<<endl;
d_connectionroom_sem->post();
catch(const PDNSException& e) {
g_log<<Logger::Error<<"Error closing TCP socket: "<<e.reason<<endl;
}
- return 0;
+ return;
}
setNonBlocking(fd);
}
}
{
- Lock l(&s_plock);
+ std::lock_guard<std::mutex> l(s_plock);
if(!s_P) {
g_log<<Logger::Error<<"TCP server is without backend connections, launching"<<endl;
s_P=make_unique<PacketHandler>();
}
}
catch(PDNSException &ae) {
- Lock l(&s_plock);
+ std::lock_guard<std::mutex> l(s_plock);
s_P.reset(); // on next call, backend will be recycled
g_log<<Logger::Error<<"TCP nameserver had error, cycling backend: "<<ae.reason<<endl;
}
g_log<<Logger::Error<<"Error closing TCP socket: "<<e.reason<<endl;
}
decrementClientCount(remote);
-
- return 0;
}
// determine if zone exists and AXFR is allowed using existing backend before spawning a new backend.
SOAData sd;
{
- Lock l(&s_plock);
+ std::lock_guard<std::mutex> l(s_plock);
DLOG(g_log<<"Looking for SOA"<<endl); // find domain_id via SOA and list complete domain. No SOA, no AXFR
if(!s_P) {
g_log<<Logger::Error<<"TCP server is without backend connections in doAXFR, launching"<<endl;
// determine if zone exists and AXFR is allowed using existing backend before spawning a new backend.
SOAData sd;
{
- Lock l(&s_plock);
+ std::lock_guard<std::mutex> l(s_plock);
DLOG(g_log<<"Looking for SOA"<<endl); // find domain_id via SOA and list complete domain. No SOA, no IXFR
if(!s_P) {
g_log<<Logger::Error<<"TCP server is without backend connections in doIXFR, launching"<<endl;
DNSName algorithm=trc.d_algoName; // FIXME400: was toLowerCanonic, compare output
if (algorithm == DNSName("hmac-md5.sig-alg.reg.int"))
algorithm = DNSName("hmac-md5");
- Lock l(&s_plock);
+ std::lock_guard<std::mutex> l(s_plock);
if(!s_P->getBackend()->getTSIGKey(tsigkeyname, &algorithm, &tsig64)) {
g_log<<Logger::Error<<"TSIG key '"<<tsigkeyname<<"' for domain '"<<target<<"' not found"<<endl;
return 0;
// sem_init(&d_connectionroom_sem,0,::arg().asNum("max-tcp-connections"));
d_connectionroom_sem = make_unique<Semaphore>( ::arg().asNum( "max-tcp-connections" ));
d_maxTCPConnections = ::arg().asNum( "max-tcp-connections" );
- d_tid=0;
vector<string>locals;
stringtok(locals,::arg()["local-ipv6"]," ,");
s_clientsCount[remote]++;
}
- pthread_t tid;
d_connectionroom_sem->wait(); // blocks if no connections are available
int room;
if(room<1)
g_log<<Logger::Warning<<"Limit of simultaneous TCP connections reached - raise max-tcp-connections"<<endl;
- int err;
- if((err = pthread_create(&tid, 0, &doConnection, reinterpret_cast<void*>(fd)))) {
- g_log<<Logger::Error<<"Error creating thread: "<<stringerror(err)<<endl;
+ try {
+ std::thread connThread(doConnection, fd);
+ connThread.detach();
+ }
+ catch (std::exception& e) {
+ g_log<<Logger::Error<<"Error creating thread: "<<e.what()<<endl;
d_connectionroom_sem->post();
close(fd);
decrementClientCount(remote);
static int doAXFR(const DNSName &target, std::unique_ptr<DNSPacket>& q, int outsock);
static int doIXFR(std::unique_ptr<DNSPacket>& q, int outsock);
static bool canDoAXFR(std::unique_ptr<DNSPacket>& q);
- static void *doConnection(void *data);
- static void *launcher(void *data);
+ static void doConnection(int fd);
static void decrementClientCount(const ComboAddress& remote);
void thread(void);
- static pthread_mutex_t s_plock;
+ static std::mutex s_plock;
static std::mutex s_clientsCountMutex;
static std::map<ComboAddress,size_t,ComboAddress::addressOnlyLessThan> s_clientsCount;
static std::unique_ptr<PacketHandler> s_P;
- pthread_t d_tid;
static std::unique_ptr<Semaphore> d_connectionroom_sem;
static unsigned int d_maxTCPConnections;
static NetmaskGroup d_ng;
static DNSDistPacketCache g_PC(500000);
-static void *threadMangler(void* off)
+static void threadMangler(unsigned int offset)
{
struct timespec queryTime;
gettime(&queryTime); // does not have to be accurate ("realTime") in tests
try {
ComboAddress remote;
bool dnssecOK = false;
- unsigned int offset=(unsigned int)(unsigned long)off;
for(unsigned int counter=0; counter < 100000; ++counter) {
DNSName a=DNSName("hello ")+DNSName(std::to_string(counter+offset));
vector<uint8_t> query;
cerr<<"Had error: "<<e.reason<<endl;
throw;
}
- return 0;
}
AtomicCounter g_missing;
-static void *threadReader(void* off)
+static void threadReader(unsigned int offset)
{
bool dnssecOK = false;
struct timespec queryTime;
gettime(&queryTime); // does not have to be accurate ("realTime") in tests
try
{
- unsigned int offset=(unsigned int)(unsigned long)off;
vector<DNSResourceRecord> entry;
ComboAddress remote;
for(unsigned int counter=0; counter < 100000; ++counter) {
cerr<<"Had error in threadReader: "<<e.reason<<endl;
throw;
}
- return 0;
}
BOOST_AUTO_TEST_CASE(test_PacketCacheThreaded) {
try {
- pthread_t tid[4];
- for(int i=0; i < 4; ++i)
- pthread_create(&tid[i], 0, threadMangler, (void*)(i*1000000UL));
- void* res;
- for(int i=0; i < 4 ; ++i)
- pthread_join(tid[i], &res);
+ std::vector<std::thread> threads;
+ for (int i = 0; i < 4; ++i) {
+ threads.push_back(std::thread(threadMangler, i*1000000UL));
+ }
+
+ for (auto& t : threads) {
+ t.join();
+ }
+
+ threads.clear();
BOOST_CHECK_EQUAL(g_PC.getSize() + g_PC.getDeferredInserts() + g_PC.getInsertCollisions(), 400000U);
BOOST_CHECK_SMALL(1.0*g_PC.getInsertCollisions(), 10000.0);
- for(int i=0; i < 4; ++i)
- pthread_create(&tid[i], 0, threadReader, (void*)(i*1000000UL));
- for(int i=0; i < 4 ; ++i)
- pthread_join(tid[i], &res);
+ for (int i = 0; i < 4; ++i) {
+ threads.push_back(std::thread(threadReader, i*1000000UL));
+ }
+
+ for (auto& t : threads) {
+ t.join();
+ }
BOOST_CHECK((g_PC.getDeferredInserts() + g_PC.getDeferredLookups() + g_PC.getInsertCollisions()) >= g_missing);
}
BOOST_AUTO_TEST_SUITE(test_lock_hh)
-static std::vector<std::unique_ptr<pthread_rwlock_t> > g_locks;
+static std::vector<ReadWriteLock> g_locks(1000);
static void lthread()
{
std::vector<ReadLock> rlocks;
for(auto& pp : g_locks)
- rlocks.emplace_back(&*pp);
+ rlocks.emplace_back(pp);
}
BOOST_AUTO_TEST_CASE(test_pdns_lock)
{
- for(unsigned int n=0; n < 1000; ++n) {
- auto p = make_unique<pthread_rwlock_t>();
- pthread_rwlock_init(p.get(), 0);
- g_locks.emplace_back(std::move(p));
- }
-
std::vector<ReadLock> rlocks;
for(auto& pp : g_locks)
- rlocks.emplace_back(&*pp);
+ rlocks.emplace_back(pp);
std::thread thr(lthread);
thr.join();
std::vector<WriteLock> wlocks;
for(auto& pp : g_locks)
- wlocks.emplace_back(&*pp);
+ wlocks.emplace_back(pp);
// on macOS, this TryReadLock throws (EDEADLK) instead of simply failing
// so we catch the exception and consider that success for this test
bool gotit = false;
try {
- TryReadLock trl(&*g_locks[0]);
+ TryReadLock trl(g_locks.at(0));
gotit = trl.gotIt();
}
catch(const PDNSException &e) {
wlocks.clear();
{
- TryReadLock trl2(&*g_locks[0]);
+ TryReadLock trl2(g_locks.at(0));
BOOST_CHECK(trl2.gotIt());
}
- for(auto& pp : g_locks) {
- pthread_rwlock_destroy(pp.get());
- }
+ g_locks.clear();
}
BOOST_AUTO_TEST_SUITE_END()
#include "auth-querycache.hh"
#include "arguments.hh"
#include <utility>
+#include <thread>
+
extern StatBag S;
BOOST_AUTO_TEST_SUITE(test_packetcache_cc)
static AuthQueryCache* g_QC;
static AtomicCounter g_QCmissing;
-static void *threadQCMangler(void* a)
+static void threadQCMangler(unsigned int offset)
try
{
vector<DNSZoneRecord> records;
- unsigned int offset=(unsigned int)(unsigned long)a;
for(unsigned int counter=0; counter < 100000; ++counter)
g_QC->insert(DNSName("hello ")+DNSName(std::to_string(counter+offset)), QType(QType::A), vector<DNSZoneRecord>(records), 3600, 1);
- return 0;
}
catch(PDNSException& e) {
cerr<<"Had error: "<<e.reason<<endl;
throw;
}
-static void *threadQCReader(void* a)
+static void threadQCReader(unsigned int offset)
try
{
- unsigned int offset=(unsigned int)(unsigned long)a;
vector<DNSZoneRecord> entry;
for(unsigned int counter=0; counter < 100000; ++counter)
if(!g_QC->getEntry(DNSName("hello ")+DNSName(std::to_string(counter+offset)), QType(QType::A), entry, 1)) {
g_QCmissing++;
}
- return 0;
}
catch(PDNSException& e) {
cerr<<"Had error in threadQCReader: "<<e.reason<<endl;
AuthQueryCache QC;
QC.setMaxEntries(1000000);
g_QC=&QC;
- pthread_t tid[4];
- for(int i=0; i < 4; ++i)
- pthread_create(&tid[i], 0, threadQCMangler, (void*)(i*1000000UL));
- void* res;
- for(int i=0; i < 4 ; ++i)
- pthread_join(tid[i], &res);
+ std::vector<std::thread> manglers;
+ for (int i=0; i < 4; ++i) {
+ manglers.push_back(std::thread(threadQCMangler, i*1000000UL));
+ }
+
+ for (auto& t : manglers) {
+ t.join();
+ }
+ manglers.clear();
BOOST_CHECK_EQUAL(QC.size() + S.read("deferred-cache-inserts"), 400000U);
BOOST_CHECK_SMALL(1.0*S.read("deferred-cache-inserts"), 10000.0);
- for(int i=0; i < 4; ++i)
- pthread_create(&tid[i], 0, threadQCReader, (void*)(i*1000000UL));
- for(int i=0; i < 4 ; ++i)
- pthread_join(tid[i], &res);
+ std::vector<std::thread> readers;
+ for (int i=0; i < 4; ++i) {
+ readers.push_back(std::thread(threadQCReader, i*1000000UL));
+ }
+
+ for (auto& t : readers) {
+ t.join();
+ }
+ readers.clear();
BOOST_CHECK(S.read("deferred-cache-inserts") + S.read("deferred-cache-lookup") >= g_QCmissing);
// BOOST_CHECK_EQUAL(S.read("deferred-cache-lookup"), 0); // cache cleaning invalidates this
static AuthPacketCache* g_PC;
static AtomicCounter g_PCmissing;
-static void *threadPCMangler(void* a)
+static void threadPCMangler(unsigned int offset)
try
{
- unsigned int offset=(unsigned int)(unsigned long)a;
for(unsigned int counter=0; counter < 100000; ++counter) {
vector<uint8_t> pak;
DNSName qname = DNSName("hello ")+DNSName(std::to_string(counter+offset));
const unsigned int maxTTL = 3600;
g_PC->insert(q, r, maxTTL);
}
-
- return 0;
}
catch(PDNSException& e) {
cerr<<"Had error: "<<e.reason<<endl;
throw;
}
-static void *threadPCReader(void* a)
+static void threadPCReader(unsigned int offset)
try
{
- unsigned int offset=(unsigned int)(unsigned long)a;
vector<DNSZoneRecord> entry;
for(unsigned int counter=0; counter < 100000; ++counter) {
vector<uint8_t> pak;
g_PCmissing++;
}
}
-
- return 0;
}
catch(PDNSException& e) {
cerr<<"Had error in threadPCReader: "<<e.reason<<endl;
g_PC=&PC;
g_PCmissing = 0;
- pthread_t tid[4];
- for(int i=0; i < 4; ++i)
- pthread_create(&tid[i], 0, threadPCMangler, (void*)(i*1000000UL));
- void* res;
- for(int i=0; i < 4 ; ++i)
- pthread_join(tid[i], &res);
+ std::vector<std::thread> manglers;
+ for (int i=0; i < 4; ++i) {
+ manglers.push_back(std::thread(threadPCMangler, i*1000000UL));
+ }
+
+ for (auto& t : manglers) {
+ t.join();
+ }
+ manglers.clear();
BOOST_CHECK_EQUAL(PC.size() + S.read("deferred-packetcache-inserts"), 400000UL);
BOOST_CHECK_EQUAL(S.read("deferred-packetcache-lookup"), 0UL);
BOOST_CHECK_SMALL(1.0*S.read("deferred-packetcache-inserts"), 10000.0);
- for(int i=0; i < 4; ++i)
- pthread_create(&tid[i], 0, threadPCReader, (void*)(i*1000000UL));
- for(int i=0; i < 4 ; ++i)
- pthread_join(tid[i], &res);
+ std::vector<std::thread> readers;
+ for (int i=0; i < 4; ++i) {
+ readers.push_back(std::thread(threadPCReader, i*1000000UL));
+ }
+
+ for (auto& t : readers) {
+ t.join();
+ }
+ readers.clear();
/*
cerr<<"Misses: "<<S.read("packetcache-miss")<<endl;
}
bool g_stopCleaning;
-static void *cacheCleaner(void*)
+static void cacheCleaner()
try
{
while(!g_stopCleaning) {
g_QC->cleanup();
}
-
- return 0;
}
catch(PDNSException& e) {
cerr<<"Had error in cacheCleaner: "<<e.reason<<endl;
sleep(1);
g_QC=&QC;
- pthread_t tid[4];
+ std::vector<std::thread> readers;
+ for (int i=0; i < 4; ++i) {
+ if (i < 3) {
+ readers.push_back(std::thread(threadQCReader, i*1000000UL));
+ }
+ else {
+ readers.push_back(std::thread(cacheCleaner));
+ }
+ }
- pthread_create(&tid[0], 0, threadQCReader, (void*)(0*1000000UL));
- pthread_create(&tid[1], 0, threadQCReader, (void*)(1*1000000UL));
- pthread_create(&tid[2], 0, threadQCReader, (void*)(2*1000000UL));
- // pthread_create(&tid[2], 0, threadMangler, (void*)(0*1000000UL));
- pthread_create(&tid[3], 0, cacheCleaner, 0);
+ for (int i = 0; i < 3 ; ++i) {
+ readers.at(i).join();
+ }
- void *res;
- for(int i=0; i < 3 ; ++i)
- pthread_join(tid[i], &res);
g_stopCleaning=true;
- pthread_join(tid[3], &res);
+ readers.at(3).join();
+
+ readers.clear();
}
catch(PDNSException& e) {
cerr<<"Had error in test_QueryCacheClean: "<<e.reason<<endl;
BOOST_AUTO_TEST_CASE(test_generic_signers)
{
- for (const auto signer : signers) {
+ for (const auto& signer : signers) {
DNSKEYRecordContent drc;
auto dcke = DNSCryptoKeyEngine::makeFromISCString(drc, signer.iscMap);
#include <boost/tuple/tuple.hpp>
#include <stdint.h>
+#include <thread>
#include "misc.hh"
#include "dns.hh"
#include "statbag.hh"
using std::string;
-static void *threadMangler(void* a)
+static void threadMangler(AtomicCounter* ac)
{
- AtomicCounter* ac=(AtomicCounter*)a;
for(unsigned int n=0; n < 1000000; ++n)
(*ac)++;
- return 0;
}
-static void *threadMangler2(void* a)
+static void threadMangler2(StatBag* S)
{
- StatBag* S = (StatBag*)a;
for(unsigned int n=0; n < 1000000; ++n)
S->inc("c");
- return 0;
}
BOOST_CHECK_EQUAL(s.read("a"), n+1);
AtomicCounter* acc = s.getPointer("c");
- pthread_t tid[4];
- for(int i=0; i < 4; ++i)
- pthread_create(&tid[i], 0, threadMangler, (void*)acc);
- void* res;
- for(int i=0; i < 4 ; ++i)
- pthread_join(tid[i], &res);
+ std::vector<std::thread> manglers;
+ for (int i=0; i < 4; ++i) {
+ manglers.push_back(std::thread(threadMangler, acc));
+ }
+
+ for (auto& t : manglers) {
+ t.join();
+ }
+ manglers.clear();
BOOST_CHECK_EQUAL(s.read("c"), 4000000U);
s.set("c", 0);
- for(int i=0; i < 4; ++i)
- pthread_create(&tid[i], 0, threadMangler2, (void*)&s);
+ for (int i=0; i < 4; ++i) {
+ manglers.push_back(std::thread(threadMangler2, &s));
+ }
- for(int i=0; i < 4 ; ++i)
- pthread_join(tid[i], &res);
+ for (auto& t : manglers) {
+ t.join();
+ }
+ manglers.clear();
BOOST_CHECK_EQUAL(s.read("c"), 4000000U);
extern StatBag S;
vector<UeberBackend *>UeberBackend::instances;
-pthread_mutex_t UeberBackend::instances_lock=PTHREAD_MUTEX_INITIALIZER;
+std::mutex UeberBackend::instances_lock;
// initially we are blocked
bool UeberBackend::d_go=false;
-pthread_mutex_t UeberBackend::d_mut = PTHREAD_MUTEX_INITIALIZER;
-pthread_cond_t UeberBackend::d_cond = PTHREAD_COND_INITIALIZER;
+std::mutex UeberBackend::d_mut;
+std::condition_variable UeberBackend::d_cond;
//! Loads a module and reports it to all UeberBackend threads
bool UeberBackend::loadmodule(const string &name)
void UeberBackend::go(void)
{
- pthread_mutex_lock(&d_mut);
- d_go=true;
- pthread_cond_broadcast(&d_cond);
- pthread_mutex_unlock(&d_mut);
+ {
+ std::unique_lock<std::mutex> l(d_mut);
+ d_go = true;
+ }
+ d_cond.notify_all();
}
bool UeberBackend::getDomainInfo(const DNSName &domain, DomainInfo &di, bool getSerial)
UeberBackend::UeberBackend(const string &pname)
{
- pthread_mutex_lock(&instances_lock);
- instances.push_back(this); // report to the static list of ourself
- pthread_mutex_unlock(&instances_lock);
+ {
+ std::lock_guard<std::mutex> l(instances_lock);
+ instances.push_back(this); // report to the static list of ourself
+ }
d_negcached=0;
d_ancount=0;
d_cache_ttl = ::arg().asNum("query-cache-ttl");
d_negcache_ttl = ::arg().asNum("negquery-cache-ttl");
- d_tid=pthread_self();
d_stale=false;
backends=BackendMakers().all(pname=="key-only");
void UeberBackend::cleanup()
{
- pthread_mutex_lock(&instances_lock);
-
- remove(instances.begin(),instances.end(),this);
- instances.resize(instances.size()-1);
-
- pthread_mutex_unlock(&instances_lock);
+ {
+ std::lock_guard<std::mutex> l(instances_lock);
+ remove(instances.begin(),instances.end(),this);
+ instances.resize(instances.size()-1);
+ }
for_each(backends.begin(),backends.end(),del);
}
}
DLOG(g_log<<"UeberBackend received question for "<<qtype.getName()<<" of "<<qname<<endl);
- if(!d_go) {
- pthread_mutex_lock(&d_mut);
- while (d_go==false) {
- g_log<<Logger::Error<<"UeberBackend is blocked, waiting for 'go'"<<endl;
- pthread_cond_wait(&d_cond, &d_mut);
- g_log<<Logger::Error<<"Broadcast received, unblocked"<<endl;
- }
- pthread_mutex_unlock(&d_mut);
+ if (!d_go) {
+ g_log<<Logger::Error<<"UeberBackend is blocked, waiting for 'go'"<<endl;
+ std::unique_lock<std::mutex> l(d_mut);
+ d_cond.wait(l, []{ return d_go == true; });
+ g_log<<Logger::Error<<"Broadcast received, unblocked"<<endl;
}
d_domain_id=zoneId;
#include <map>
#include <string>
#include <algorithm>
-#include <pthread.h>
#include <semaphore.h>
+#include <mutex>
+#include <condition_variable>
#include <unistd.h>
#include <sys/stat.h>
existing threads of new modules
*/
static vector<UeberBackend *>instances;
- static pthread_mutex_t instances_lock;
+ static std::mutex instances_lock;
static bool loadmodule(const string &name);
static bool loadModules(const vector<string>& modules, const string& path);
bool searchRecords(const string &pattern, int maxResults, vector<DNSResourceRecord>& result);
bool searchComments(const string &pattern, int maxResults, vector<Comment>& result);
private:
- pthread_t d_tid;
handle d_handle;
vector<DNSZoneRecord> d_answers;
vector<DNSZoneRecord>::const_iterator d_cachehandleiter;
- static pthread_mutex_t d_mut;
- static pthread_cond_t d_cond;
+ static std::mutex d_mut;
+ static std::condition_variable d_cond;
struct Question
{
static const std::set<uint16_t> exclusiveEntryTypes = { QType::CNAME };
AuthWebServer::AuthWebServer() :
- d_tid(0),
d_start(time(nullptr)),
d_min10(0),
d_min5(0),
void AuthWebServer::go()
{
S.doRings();
- pthread_create(&d_tid, 0, webThreadHelper, this);
- pthread_create(&d_tid, 0, statThreadHelper, this);
+ std::thread webT(std::bind(&AuthWebServer::webThread, this));
+ webT.detach();
+ std::thread statT(std::bind(&AuthWebServer::statThread, this));
+ statT.detach();
}
void AuthWebServer::statThread()
}
}
-void *AuthWebServer::statThreadHelper(void *p)
-{
- AuthWebServer *self=static_cast<AuthWebServer *>(p);
- self->statThread();
- return 0; // never reached
-}
-
-void *AuthWebServer::webThreadHelper(void *p)
-{
- AuthWebServer *self=static_cast<AuthWebServer *>(p);
- self->webThread();
- return 0; // never reached
-}
-
static string htmlescape(const string &s) {
string result;
for(string::const_iterator it=s.begin(); it!=s.end(); ++it) {
B.getAllDomains(&domains, true);
- for(const DomainInfo di: domains)
+ for(const DomainInfo& di: domains)
{
if ((objectType == ObjectType::ALL || objectType == ObjectType::ZONE) && ents < maxEnts && sm.match(di.zone)) {
doc.push_back(Json::object {
static string makePercentage(const double& val);
private:
- static void *webThreadHelper(void *);
- static void *statThreadHelper(void *p);
void indexfunction(HttpRequest* req, HttpResponse* resp);
void cssfunction(HttpRequest* req, HttpResponse* resp);
void jsonstat(HttpRequest* req, HttpResponse* resp);
void printargs(ostringstream &ret);
void webThread();
void statThread();
- pthread_t d_tid;
time_t d_start;
double d_min10, d_min5, d_min1;