Browse Source

added workaround for Solaris: if SO_RCVTIMEO is rejected due to EOPNOTSUPP switch to "no wait recv()"

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac448@4056 e5f2f494-b856-4b98-b285-d166d9295462
JINMEI Tatuya 14 years ago
parent
commit
27966638a1
1 changed files with 19 additions and 4 deletions
  1. 19 4
      src/lib/asiolink/tests/asiolink_unittest.cc

+ 19 - 4
src/lib/asiolink/tests/asiolink_unittest.cc

@@ -338,11 +338,21 @@ protected:
         // In order to prevent the test from hanging in such a worst case
         // we add an ad hoc timeout.
         const struct timeval timeo = { 10, 0 };
+        int recv_options = 0;
         if (setsockopt(sock_, SOL_SOCKET, SO_RCVTIMEO, &timeo,
                        sizeof(timeo))) {
-            isc_throw(IOError, "set RCVTIMEO failed: " << strerror(errno));
+            if (errno == EOPNOTSUPP) {
+                // Workaround for Solaris: it doesn't accept SO_RCVTIMEO
+                // with the error of EOPNOTSUPP.  Since this is a workaround
+                // for rare error cases anyway, we simply switch to the
+                // "don't wait" mode.  If we still find an error in recv()
+                // can happen often we'll consider a more complete solution.
+                recv_options = MSG_DONTWAIT;
+            } else {
+                isc_throw(IOError, "set RCVTIMEO failed: " << strerror(errno));
+            }
         }
-        const int ret = recv(sock_, buffer, size, 0);
+        const int ret = recv(sock_, buffer, size, recv_options);
         if (ret < 0) {
             isc_throw(IOError, "recvfrom failed: " << strerror(errno));
         }
@@ -710,13 +720,18 @@ TEST_F(ASIOLinkTest, recursiveTimeout) {
     // Read up to 3 packets.  Use some ad hoc timeout to prevent an infinite
     // block (see also recvUDP()).
     const struct timeval timeo = { 10, 0 };
+    int recv_options = 0;
     if (setsockopt(sock_, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo))) {
-        isc_throw(IOError, "set RCVTIMEO failed: " << strerror(errno));
+        if (errno == EOPNOTSUPP) { // see ASIOLinkTest::recvUDP()
+            recv_options = MSG_DONTWAIT;
+        } else {
+            isc_throw(IOError, "set RCVTIMEO failed: " << strerror(errno));
+        }
     }
     int num = 0;
     do {
         char inbuff[512];
-        if (recv(sock_, inbuff, sizeof(inbuff), 0) < 0) {
+        if (recv(sock_, inbuff, sizeof(inbuff), recv_options) < 0) {
             num = -1;
             break;
         }