]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Handle EINTR in DelayPipe 9381/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 11 Aug 2020 12:46:52 +0000 (14:46 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 11 Aug 2020 12:46:52 +0000 (14:46 +0200)
Otherwise the DelayPipe thread might stop because the read() operation
has been interrupted by a signal (like SIGWINCH, which is quite annoying).
Also remove the unused `read()` operation.

pdns/delaypipe.cc
pdns/delaypipe.hh
pdns/dnsdistdist/test-delaypipe_hh.cc

index 721b611622acc7125bce1ecfd787f7619d3a2ecc..167f355fd7b8dbf4cb70f39ba539b463c958cf4b 100644 (file)
@@ -59,45 +59,42 @@ void ObjectPipe<T>::write(T& t)
   }
 }
 
-template<class T>
-bool ObjectPipe<T>::read(T* t)
-{
-  T* ptr;
-  int ret = ::read(d_fds[0], &ptr, sizeof(ptr));
-
-  if(ret < 0)
-    unixDie("read");
-  if(ret==0)
-    return false;
-  if(ret != sizeof(ptr))
-    throw std::runtime_error("Partial read, should not happen");    
-  *t=*ptr;
-  delete ptr;
-  return true;
-}
-
 template<class T>
 int ObjectPipe<T>::readTimeout(T* t, double msec)
 {
-  T* ptr;
-
-  int ret = waitForData(d_fds[0], 0, 1000*msec);
-  if(ret < 0)
-    unixDie("waiting for data in object pipe");
-  if(ret == 0) 
-    return -1;
-
-  ret = ::read(d_fds[0], &ptr, sizeof(ptr)); // this is BLOCKING!
-
-  if(ret < 0)
-    unixDie("read");
-  if(ret==0)
-    return false;
-  if(ret != sizeof(ptr))
-    throw std::runtime_error("Partial read, should not happen 2");    
-  *t=*ptr;
-  delete ptr;
-  return 1;
+  while (true) {
+    int ret = waitForData(d_fds[0], 0, 1000*msec);
+    if (ret < 0) {
+      if (errno == EINTR) {
+        continue;
+      }
+      unixDie("waiting for data in object pipe");
+    }
+    else if (ret == 0) {
+      return -1;
+    }
+
+    T* ptr = nullptr;
+    ret = ::read(d_fds[0], &ptr, sizeof(ptr)); // this is BLOCKING!
+
+    if (ret < 0) {
+      if (errno == EINTR) {
+        continue;
+      }
+      unixDie("read");
+    }
+    else if (ret == 0) {
+      return false;
+    }
+
+    if (ret != sizeof(ptr)) {
+      throw std::runtime_error("Partial read, should not happen 2");
+    }
+
+    *t = *ptr;
+    delete ptr;
+    return 1;
+  }
 }
 
 
index b44159132b3fe399e9ebea153288ef02a50cc5e6..ad1626a9990eca6727aa5b3794a0e132089f7893 100644 (file)
@@ -43,8 +43,7 @@ public:
   ObjectPipe();
   ~ObjectPipe();
   void write(T& t);
-  bool read(T* t); // returns false on EOF
-  int readTimeout(T* t, double msec); //!< -1 is timeout, 0 is no data, 1 is data. msec<0 waits infinitely wrong. msec==0 = undefined
+  int readTimeout(T* t, double msec); //!< -1 is timeout, 0 is no data, 1 is data. msec<0 waits infinitely long. msec==0 = undefined
   void close(); 
 private:
   int d_fds[2];
index 3d1c1b00dfac00e3d323a84dcc4f1ef23305ca35..e376cb93309cba0e2dc624d0ac3ebc5183deb9e5 100644 (file)
@@ -15,13 +15,13 @@ BOOST_AUTO_TEST_CASE(test_object_pipe) {
 
   int i;
   for(int n=0; n < 100; ++n) {
-    bool res=op.read(&i);
-    BOOST_CHECK_EQUAL(res, true);
+    int res=op.readTimeout(&i, -1);
+    BOOST_CHECK_EQUAL(res, 1);
     BOOST_CHECK_EQUAL(n, i);
   }
 
   op.close();
-  BOOST_CHECK_EQUAL(op.read(&i), false);
+  BOOST_CHECK_EQUAL(op.readTimeout(&i, 1), 0);
 
 };