]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
auth: Wrap pthread_ objects
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 24 Apr 2020 19:02:41 +0000 (21:02 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 28 Apr 2020 13:39:35 +0000 (15:39 +0200)
33 files changed:
modules/bindbackend/bindbackend2.cc
modules/bindbackend/bindbackend2.hh
pdns/auth-packetcache.cc
pdns/auth-packetcache.hh
pdns/auth-querycache.cc
pdns/auth-querycache.hh
pdns/communicator.cc
pdns/communicator.hh
pdns/dbdnsseckeeper.cc
pdns/distributor.hh
pdns/dnsproxy.cc
pdns/dnsproxy.hh
pdns/dnsseckeeper.hh
pdns/dnssecsigner.cc
pdns/dnstcpbench.cc
pdns/lua-record.cc
pdns/mastercommunicator.cc
pdns/packethandler.hh
pdns/pkcs11signers.cc
pdns/receiver.cc
pdns/remote_logger.hh
pdns/rfc2136handler.cc
pdns/slavecommunicator.cc
pdns/speedtest.cc
pdns/stubresolver.cc
pdns/tcpreceiver.cc
pdns/tcpreceiver.hh
pdns/test-packetcache_cc.cc
pdns/test-statbag_cc.cc
pdns/ueberbackend.cc
pdns/ueberbackend.hh
pdns/ws-auth.cc
pdns/ws-auth.hh

index c61d33dc6c439bce2435fc26ffb5672544cdaf21..03e71e0fbaae1bff7ed126ca88fb4f9b2829bdb5 100644 (file)
@@ -77,9 +77,9 @@ Bind2Backend::state_t Bind2Backend::s_state;
 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>
@@ -463,7 +463,7 @@ void Bind2Backend::alsoNotifies(const DNSName& domain, set<string> *ips)
       (*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++) {
@@ -730,7 +730,7 @@ Bind2Backend::Bind2Backend(const string &suffix, bool loadZones)
   if (!loadZones && d_hybrid)
     return;
 
-  Lock l(&s_startup_lock);
+  std::lock_guard<std::mutex> l(s_startup_lock);
   
   setupDNSSEC();
   if(!s_first) {
@@ -1375,7 +1375,7 @@ bool Bind2Backend::createSlaveDomain(const string &ip, const DNSName& domain, co
     << "' 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) {
index 1a33194326ef68b936f758e9f6822148ae31c138..aa38223bd0976ea739d047d813bb1ba40c7c1c5d 100644 (file)
@@ -187,7 +187,7 @@ public:
   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;
@@ -221,7 +221,7 @@ public:
                                               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;
@@ -229,7 +229,7 @@ public:
 
   // 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:
index 71dbf134d50abdddf88086eb070266400d712b8a..759864e58888323b83981edccd7e210e9c004ad7 100644 (file)
@@ -46,13 +46,11 @@ AuthPacketCache::AuthPacketCache(size_t mapsCount): d_maps(mapsCount), d_lastcle
 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(...) {
   }
index 0d3af47a251ef2cc7f85373a86001b424178f8e6..bceab073de59797980e75056d3bea546d68d5e41 100644 (file)
@@ -108,17 +108,15 @@ private:
   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;
   };
 
index d4970bd137a8cd7d6851afebb295861ca00327a0..f98d9b133d875aa8d15222ac17c40d0831ae426a 100644 (file)
@@ -47,13 +47,11 @@ AuthQueryCache::AuthQueryCache(size_t mapsCount): d_maps(mapsCount), d_lastclean
 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(...) {
   }
index c62230b2280f73f2984f0e9fd5e7d5e09bd7ffd9..f0c477e2f08ce59d0ab55d4c2457658f06399d26 100644 (file)
@@ -91,17 +91,15 @@ private:
   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;
   };
 
index 816b489673ddd05228c8fd71d22e22fc5a03b4ff..d5ff10eb653c148859a8736417ba521b34781e2a 100644 (file)
 #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"
@@ -45,7 +48,7 @@ void CommunicatorClass::retrievalLoopThread(void)
     d_suck_sem.wait();
     SuckRequest sr;
     {
-      Lock l(&d_lock);
+      std::lock_guard<std::mutex> l(d_lock);
       if(d_suckdomains.empty()) 
         continue;
         
@@ -82,10 +85,13 @@ void CommunicatorClass::go()
     _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");
 
@@ -131,7 +137,7 @@ void CommunicatorClass::mainloop(void)
           bool extraSlaveRefresh = false;
           Utility::sleep(1);
           {
-            Lock l(&d_lock);
+            std::lock_guard<std::mutex> l(d_lock);
             if (d_tocheck.size())
               extraSlaveRefresh = true;
           }
index 0c3d479b112ab69bf6ebeb9fc2276f387896314d..643145c34923767d1f1ed46020d29a43820fde4e 100644 (file)
@@ -149,9 +149,6 @@ class CommunicatorClass
 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;
@@ -171,17 +168,6 @@ public:
   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);
@@ -189,14 +175,14 @@ private:
   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;
@@ -232,7 +218,7 @@ private:
     ~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(...) {
index c2485628249d932353db032a9c54a126cd3dd490..65394273bd6e3115b4e1157fb881c6218d9d7cb8 100644 (file)
@@ -47,8 +47,8 @@ using namespace boost::assign;
 
 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;
@@ -276,7 +276,7 @@ void DNSSECKeeper::getSoaEdit(const DNSName& zname, std::string& value)
 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") {
index c025d897f5db4eecceb3bed22ec7406bd4d6cb40..38f08005ef58a2e61f45e658f64416fc87a9c758 100644 (file)
@@ -24,6 +24,7 @@
 #include <deque>
 #include <queue>
 #include <vector>
+#include <thread>
 #include <pthread.h>
 #include "threadname.hh"
 #include <unistd.h>
@@ -88,7 +89,7 @@ public:
   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;
   }
@@ -114,7 +115,7 @@ private:
   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;
 };
 
@@ -137,6 +138,10 @@ template<class Answer, class Question, class Backend>SingleThreadDistributor<Ans
     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);
@@ -151,9 +156,6 @@ template<class Answer, class Question, class Backend>MultiThreadDistributor<Answ
   nextid=0;
   d_last_started=time(0);
 
-  pthread_t tid;
-  
-
   for(int i=0; i < n; ++i) {
     int fds[2];
     if(pipe(fds) < 0)
@@ -168,7 +170,8 @@ template<class Answer, class Question, class Backend>MultiThreadDistributor<Answ
 
   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;
@@ -176,12 +179,9 @@ template<class Answer, class Question, class Backend>MultiThreadDistributor<Answ
 
 
 // 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
@@ -190,9 +190,9 @@ template<class Answer, class Question, class Backend>void *MultiThreadDistributo
     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;
@@ -251,11 +251,14 @@ retry:
     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)
@@ -312,7 +315,7 @@ template<class Answer, class Question, class Backend>int MultiThreadDistributor<
   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");
index decd631e4f5fa63d22909e53d5450d68cecc94d4..e2dd8e82034187921c2570ec1cb716c1de6d8295 100644 (file)
 #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"
@@ -39,7 +42,6 @@ extern StatBag S;
 
 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");
@@ -83,8 +85,8 @@ DNSProxy::DNSProxy(const string &remote)
 
 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
@@ -129,7 +131,7 @@ bool DNSProxy::completePacket(std::unique_ptr<DNSPacket>& r, const DNSName& targ
   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;
@@ -216,7 +218,7 @@ void DNSProxy::mainloop(void)
       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];  
index e9b5807af49832b362573137820fd20671100352..0adc07af9a4f769044fd2141b2adb58abcece9e2 100644 (file)
@@ -20,8 +20,8 @@
  * 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>
@@ -56,11 +56,6 @@ public:
   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
@@ -84,7 +79,7 @@ private:
   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();
index c2fa1c0ab631b72475da626931492002d9d93ac6..5ec297b0ffb439f07a6540ca30977f38e9b977ce 100644 (file)
@@ -33,6 +33,7 @@
 #include "dnssecinfra.hh"
 #include "dnsrecords.hh"
 #include "ueberbackend.hh"
+#include "lock.hh"
 
 using namespace ::boost::multi_index;
 
@@ -298,8 +299,8 @@ private:
 
   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;
index 7e6f485ee9fa269acfbab56353d7cb06cfd37577..3bb27930c8b183ac4c408ab731ea5b54825f27e0 100644 (file)
@@ -33,7 +33,7 @@
 #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;
index 922c05ff226e8471856e0472b192ebd08a07c6db..4f36ff2e995442c33ea0cc8b3a46a7738230136b 100644 (file)
@@ -28,6 +28,8 @@
 
 #include <boost/accumulators/statistics.hpp>
 
+#include <thread>
+
 #include "dnsparser.hh"
 #include "sstuff.hh"
 #include "misc.hh"
@@ -172,7 +174,7 @@ AtomicCounter g_pos;
 
 vector<BenchQuery> g_queries;
 
-static void* worker(void*)
+static void worker()
 {
   setThreadName("dnstcpb/worker");
   for(;;) {
@@ -182,7 +184,6 @@ static void* worker(void*)
 
     doQuery(&g_queries[pos]); // this is safe as long as nobody *inserts* to g_queries
   }
-  return 0;
 }
 
 static void usage(po::options_description &desc) {
@@ -251,7 +252,8 @@ try
   }
 
 
-  std::vector<pthread_t> workers(numworkers);
+  std::vector<std::thread> workers;
+  workers.reserve(numworkers);
 
   FILE* fp;
   if(!g_vm.count("file"))
@@ -270,12 +272,11 @@ try
   }
   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;
index ea43dcef1cddab2385f55da6896d1aabe397d314..50bbf48e7422c2fb9a5c2bdf5a185c7005d7e175 100644 (file)
@@ -71,15 +71,13 @@ private:
     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);
index 4219e1d356bd0a374ef1e665e4029e232418fd09..7693cec963710379955e84c3ffa791527c24272f 100644 (file)
@@ -280,13 +280,13 @@ void CommunicatorClass::sendNotification(int sock, const DNSName& domain, const
 
 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;
 
index cd41c16259b19d6d8e659601d23f31b856854474..b196d984da35659819161ac071367ec351983bbd 100644 (file)
@@ -102,7 +102,7 @@ private:
   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;
index c999a573934de6c0d40acba6c401713b9c5ca8d6..ddb1506492f606845111878a724df3929885b070 100644 (file)
@@ -8,6 +8,8 @@
 #include <boost/format.hpp>
 #include <p11-kit/p11-kit.h>
 
+#include <mutex>
+
 #include "pdns/dnssecinfra.hh"
 #include "pdns/logger.hh"
 #include "pdns/pdnsexception.hh"
@@ -206,7 +208,7 @@ class Pkcs11Slot {
     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) {
@@ -223,8 +225,7 @@ class Pkcs11Slot {
     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");
@@ -261,7 +262,7 @@ class Pkcs11Slot {
 
     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);
@@ -342,7 +343,7 @@ class Pkcs11Token {
     }
 
     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));
@@ -407,7 +408,7 @@ class Pkcs11Token {
 
     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()]);
@@ -435,7 +436,7 @@ class Pkcs11Token {
     }
 
     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.
@@ -454,7 +455,7 @@ class Pkcs11Token {
     }
 
     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());
@@ -463,7 +464,7 @@ class Pkcs11Token {
     }
 
     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
@@ -490,7 +491,7 @@ class Pkcs11Token {
     }
 
     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;
 
@@ -521,7 +522,7 @@ class Pkcs11Token {
     }
 
     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);
     }
 
@@ -567,7 +568,7 @@ class Pkcs11Token {
 
     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);
     }
 
index 42da510c58e50019997c2473046af64c6c4cfcc1..3e908d320947f4e855bf7cfc7bdedb0446c633eb 100644 (file)
@@ -154,7 +154,7 @@ static void writePid(void)
 
 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)
@@ -176,7 +176,7 @@ static string DLRestHandler(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);
@@ -216,7 +216,7 @@ static int guardian(int argc, char **argv)
   bool first=true;
   cpid=0;
 
-  pthread_mutex_lock(&g_guardian_lock);
+  g_guardian_lock.lock();
 
   for(;;) {
     int pid;
@@ -292,7 +292,7 @@ static int guardian(int argc, char **argv)
 
         writePid();
       }
-      pthread_mutex_unlock(&g_guardian_lock);  
+      g_guardian_lock.unlock();
       int status;
       cpid=pid;
       for(;;) {
@@ -314,7 +314,7 @@ static int guardian(int argc, char **argv)
         }
       }
 
-      pthread_mutex_lock(&g_guardian_lock);
+      g_guardian_lock.lock();
       close(g_fd1[1]);
       fclose(g_fp);
       g_fp=0;
index 70b7af35fdd2b09ac63b58691e49a985e6cbde85..d6cf953c63b1f197d269148201b08a713f6521ff 100644 (file)
@@ -25,8 +25,8 @@
 #endif
 
 #include <atomic>
-#include <condition_variable>
 #include <queue>
+#include <mutex>
 #include <thread>
 
 #include "iputils.hh"
index 50999d9c3d8b1a153804cf7a247f77ae309b6e07..069671a61f7fde70ea74d1afab86e7a1e8e1e50b 100644 (file)
@@ -20,7 +20,7 @@
 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) {
@@ -823,7 +823,7 @@ int PacketHandler::processUpdate(DNSPacket& p) {
   }
 
 
-  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;
index befe6286a6df00d20db40057e7b2908015064d1b..0638c51e1c5f319cb2f06d5e5f1360a4098a726e 100644 (file)
@@ -49,7 +49,7 @@
 
 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;
@@ -295,7 +295,7 @@ static vector<DNSResourceRecord> doAxfr(const ComboAddress& raddr, const DNSName
 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; 
     }
@@ -634,7 +634,7 @@ void CommunicatorClass::suck(const DNSName &domain, const ComboAddress& remote)
   }
   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.
@@ -729,7 +729,7 @@ struct SlaveSenderReceiver
 
 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;
 
@@ -750,7 +750,7 @@ void CommunicatorClass::addSlaveCheckRequest(const DomainInfo& di, const ComboAd
 
 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!
@@ -766,7 +766,7 @@ void CommunicatorClass::slaveRefresh(PacketHandler *P)
   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) {
@@ -806,7 +806,7 @@ void CommunicatorClass::slaveRefresh(PacketHandler *P)
   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);
 
@@ -867,14 +867,14 @@ void CommunicatorClass::slaveRefresh(PacketHandler *P)
   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;
@@ -919,7 +919,7 @@ void CommunicatorClass::slaveRefresh(PacketHandler *P)
 
     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;
@@ -936,7 +936,7 @@ void CommunicatorClass::slaveRefresh(PacketHandler *P)
     }
 
     {
-      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);
index 5d21667afee87b89f148aebc2150c167467e1d96..27205d5ffdfeba27ea81c29c8df72074c15ad12f 100644 (file)
@@ -105,7 +105,7 @@ struct GetTimeTest
   }
 };
 
-pthread_mutex_t s_testlock=PTHREAD_MUTEX_INITIALIZER;
+std::mutex s_testlock;
 
 struct GetLockUncontendedTest
 {
@@ -116,8 +116,8 @@ struct GetLockUncontendedTest
 
   void operator()() const
   {
-    pthread_mutex_lock(&s_testlock);
-    pthread_mutex_unlock(&s_testlock);
+    s_testlock.lock();
+    s_testlock.unlock();
   }
 };
 
index 985d96ea55004c909abbfa0145011ab0f6651d35..98cd70fe546d61fbf84fa5e30d0838b2d07bcd89 100644 (file)
@@ -23,7 +23,7 @@
 // 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
index d8449eb586378faf829f8b2d6b81d88c9afd7266..30314221331e077a11e79cacb6df1b62e81c4da2 100644 (file)
@@ -66,7 +66,7 @@ extern StatBag S;
 \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;
@@ -88,13 +88,9 @@ void TCPNameserver::go()
   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
@@ -225,12 +221,10 @@ void TCPNameserver::decrementClientCount(const ComboAddress& remote)
   }
 }
 
-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;
@@ -239,7 +233,6 @@ void *TCPNameserver::doConnection(void *data)
     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();
@@ -249,7 +242,7 @@ void *TCPNameserver::doConnection(void *data)
     catch(const PDNSException& e) {
       g_log<<Logger::Error<<"Error closing TCP socket: "<<e.reason<<endl;
     }
-    return 0;
+    return;
   }
 
   setNonBlocking(fd);
@@ -352,7 +345,7 @@ void *TCPNameserver::doConnection(void *data)
         }
       }
       {
-        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>();
@@ -368,7 +361,7 @@ void *TCPNameserver::doConnection(void *data)
     }
   }
   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;
   }
@@ -392,8 +385,6 @@ void *TCPNameserver::doConnection(void *data)
     g_log<<Logger::Error<<"Error closing TCP socket: "<<e.reason<<endl;
   }
   decrementClientCount(remote);
-
-  return 0;
 }
 
 
@@ -538,7 +529,7 @@ int TCPNameserver::doAXFR(const DNSName &target, std::unique_ptr<DNSPacket>& q,
   // 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;
@@ -1070,7 +1061,7 @@ int TCPNameserver::doIXFR(std::unique_ptr<DNSPacket>& q, int outsock)
   // 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;
@@ -1124,7 +1115,7 @@ int TCPNameserver::doIXFR(std::unique_ptr<DNSPacket>& q, int outsock)
       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;
@@ -1175,7 +1166,6 @@ TCPNameserver::TCPNameserver()
 //  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"]," ,");
@@ -1284,7 +1274,6 @@ void TCPNameserver::thread()
               s_clientsCount[remote]++;
             }
 
-            pthread_t tid;
             d_connectionroom_sem->wait(); // blocks if no connections are available
 
             int room;
@@ -1292,9 +1281,12 @@ void TCPNameserver::thread()
             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);
index cafe7943312eab80c44ac3138220526dbf09fed7..5220d5b5f2ef8e78cad0641375159506b8657aaf 100644 (file)
@@ -54,15 +54,13 @@ private:
   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;
index 39f5911998ff5d868320b4183132fb5ce0a60366..5fcfff8216aab30b4db38b773d2fb44a5f95c3b0 100644 (file)
@@ -12,6 +12,8 @@
 #include "auth-querycache.hh"
 #include "arguments.hh"
 #include <utility>
+#include <thread>
+
 extern StatBag S;
 
 BOOST_AUTO_TEST_SUITE(test_packetcache_cc)
@@ -71,30 +73,26 @@ BOOST_AUTO_TEST_CASE(test_AuthQueryCacheSimple) {
 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;
@@ -107,20 +105,28 @@ BOOST_AUTO_TEST_CASE(test_QueryCacheThreaded) {
     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
@@ -135,10 +141,9 @@ BOOST_AUTO_TEST_CASE(test_QueryCacheThreaded) {
 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));
@@ -165,18 +170,15 @@ try
     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;
@@ -191,8 +193,6 @@ try
       g_PCmissing++;
     }
   }
-
-  return 0;
 }
 catch(PDNSException& e) {
   cerr<<"Had error in threadPCReader: "<<e.reason<<endl;
@@ -207,21 +207,29 @@ BOOST_AUTO_TEST_CASE(test_PacketCacheThreaded) {
 
     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;
@@ -243,14 +251,12 @@ BOOST_AUTO_TEST_CASE(test_PacketCacheThreaded) {
 }
 
 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;
@@ -270,19 +276,24 @@ BOOST_AUTO_TEST_CASE(test_QueryCacheClean) {
     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;
index a33978540a78b267254a690bd2573c5e142b32de..d551ca6546172327bee860374d36d51f6aec66a2 100644 (file)
@@ -9,26 +9,23 @@
 
 #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;
 }
 
 
@@ -56,22 +53,28 @@ BOOST_AUTO_TEST_CASE(test_StatBagBasic) {
   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);
 
index 4d3e4795d6623bdbaeb212ab145339166d10271e..45cbe9aab13176fdacdb869d5c58c1bfe7e4eed7 100644 (file)
 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)
@@ -94,10 +94,11 @@ bool UeberBackend::loadModules(const vector<string>& modules, const string& path
 
 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)
@@ -463,9 +464,10 @@ bool UeberBackend::superMasterBackend(const string &ip, const DNSName &domain, c
 
 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;
@@ -474,7 +476,6 @@ UeberBackend::UeberBackend(const string &pname)
   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");
@@ -487,12 +488,11 @@ static void del(DNSBackend* d)
 
 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);
 }
@@ -567,14 +567,11 @@ void UeberBackend::lookup(const QType &qtype,const DNSName &qname, int zoneId, D
   }
 
   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;
index 09c3b451b15b585c1e1ed07dca095d11431f5c0a..48db857d9904b85fa37725e07bab6bbb794f5bfa 100644 (file)
@@ -24,8 +24,9 @@
 #include <map>
 #include <string>
 #include <algorithm>
-#include <pthread.h>
 #include <semaphore.h>
+#include <mutex>
+#include <condition_variable>
 
 #include <unistd.h>
 #include <sys/stat.h>
@@ -56,7 +57,7 @@ public:
       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);
@@ -134,13 +135,12 @@ public:
   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
   {
index 22c54dae28d9d3c65f776421960de2a0183ea68c..1d081e3a098d18ecd3ce2f4d687f84550b2ee249 100644 (file)
@@ -62,7 +62,6 @@ static const std::set<uint16_t> onlyOneEntryTypes = { QType::CNAME, QType::DNAME
 static const std::set<uint16_t> exclusiveEntryTypes = { QType::CNAME };
 
 AuthWebServer::AuthWebServer() :
-  d_tid(0),
   d_start(time(nullptr)),
   d_min10(0),
   d_min5(0),
@@ -87,8 +86,10 @@ AuthWebServer::AuthWebServer() :
 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()
@@ -110,20 +111,6 @@ 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) {
index b613174f6216a9fbfdab7450e656515eeb80e43b..79f8f2f6b6fd38af83a687ced2ff21aa43b2a710 100644 (file)
@@ -78,8 +78,6 @@ public:
   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);
@@ -88,7 +86,6 @@ private:
   void printargs(ostringstream &ret);
   void webThread();
   void statThread();
-  pthread_t d_tid;
 
   time_t d_start;
   double d_min10, d_min5, d_min1;