You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ta...@apache.org on 2010/04/27 19:59:35 UTC

svn commit: r938581 - in /activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf: internal/net/tcp/TcpSocket.cpp internal/net/tcp/TcpSocket.h net/ServerSocket.cpp net/ServerSocket.h net/Socket.cpp net/Socket.h net/SocketImpl.h

Author: tabish
Date: Tue Apr 27 17:59:34 2010
New Revision: 938581

URL: http://svn.apache.org/viewvc?rev=938581&view=rev
Log:
More work on adding new Socket tests, additional fixes to Socket connect to deal with timeout options for connect.  Removed some work in ServerSocket, APR can't seem to handle timeout on accept without the use of the polling mechanism which can't seem to be interrupted from another thread which can lead to segfaults in close operations if the accept hasn't timed out.

Modified:
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/net/tcp/TcpSocket.cpp
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/net/tcp/TcpSocket.h
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/ServerSocket.cpp
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/ServerSocket.h
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/Socket.cpp
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/Socket.h
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/SocketImpl.h

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/net/tcp/TcpSocket.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/net/tcp/TcpSocket.cpp?rev=938581&r1=938580&r2=938581&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/net/tcp/TcpSocket.cpp (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/net/tcp/TcpSocket.cpp Tue Apr 27 17:59:34 2010
@@ -63,7 +63,6 @@ TcpSocket::TcpSocket() throw ( SocketExc
   : socketHandle( NULL ),
     localAddress( NULL ),
     remoteAddress( NULL ),
-    pollSet( NULL ),
     inputStream( NULL ),
     outputStream( NULL ),
     inputShutdown( false ),
@@ -110,9 +109,6 @@ void TcpSocket::create() throw( decaf::i
         // Create the actual socket.
         checkResult( apr_socket_create( &socketHandle, AF_INET, SOCK_STREAM,
                                         APR_PROTO_TCP, apr_pool.getAprPool() ) );
-
-        // Create the pollset for the socket.
-        checkResult( apr_pollset_create( &pollSet, 1, apr_pool.getAprPool(), APR_POLLSET_NOCOPY ) );
     }
     DECAF_CATCH_RETHROW( decaf::io::IOException )
     DECAF_CATCH_EXCEPTION_CONVERT( Exception, decaf::io::IOException )
@@ -120,7 +116,8 @@ void TcpSocket::create() throw( decaf::i
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-void TcpSocket::accept( SocketImpl* socket ) throw( decaf::io::IOException ) {
+void TcpSocket::accept( SocketImpl* socket )
+    throw( decaf::io::IOException ) {
 
     try{
 
@@ -137,49 +134,6 @@ void TcpSocket::accept( SocketImpl* sock
 
         apr_status_t result = APR_SUCCESS;
 
-        if( this->soTimeout == -1 ) {
-
-            // ensure we are in a blocking accept mode.
-            apr_socket_opt_set( socketHandle, APR_SO_NONBLOCK, 0 );
-            apr_socket_timeout_set( socketHandle, -1 );
-
-        } else {
-
-            // ensure we are in a non-blocking accept mode.
-            apr_socket_opt_set( socketHandle, APR_SO_NONBLOCK, 1 );
-            apr_socket_timeout_set( socketHandle, 0 );
-
-            int num = 0;
-            const apr_pollfd_t* signalled = NULL;
-            apr_pollfd_t pfd = { apr_pool.getAprPool(),
-                                 APR_POLL_SOCKET,
-                                 APR_POLLIN | APR_POLLERR,
-                                 0, { NULL }, NULL };
-
-            pfd.desc.s = socketHandle;
-
-            // Add the socket to pollset to check APR_POLLOUT(writable)
-            apr_pollset_add( pollSet, &pfd );
-
-            // Poll for the specified timeout, the value in APR is taken as Microseconds.
-            result = apr_pollset_poll( pollSet, soTimeout * 1000, &num, &signalled );
-
-            // Check for async close event.
-            if( closed ) {
-                return;
-            }
-
-            // Remove the socket from the pollset now.
-            apr_pollset_remove( pollSet, &pfd );
-
-            if( result == APR_TIMEUP ) {
-                close();
-                throw SocketTimeoutException(
-                     __FILE__, __LINE__,
-                     "Timed out while waiting for Socket to Connect." );
-            }
-        }
-
         // Loop to ignore any signal interruptions that occur during the operation.
         do {
             result = apr_socket_accept( &impl->socketHandle, socketHandle, apr_pool.getAprPool() );
@@ -226,7 +180,7 @@ void TcpSocket::bind( const std::string&
                   SocketError::getErrorString().c_str() );
         }
 
-        // Set the socket to reuse the address and default as blocking
+        // Set the socket to reuse the address and default as blocking with no timeout.
         apr_socket_opt_set( socketHandle, APR_SO_REUSEADDR, 1 );
         apr_socket_opt_set( socketHandle, APR_SO_NONBLOCK, 0 );
         apr_socket_timeout_set( socketHandle, -1 );
@@ -259,7 +213,6 @@ void TcpSocket::bind( const std::string&
 ////////////////////////////////////////////////////////////////////////////////
 void TcpSocket::connect( const std::string& hostname, int port, int timeout )
     throw( decaf::io::IOException,
-           decaf::net::SocketTimeoutException,
            decaf::lang::exceptions::IllegalArgumentException ) {
 
     try{
@@ -285,59 +238,19 @@ void TcpSocket::connect( const std::stri
         apr_socket_opt_get( socketHandle, APR_SO_NONBLOCK, &oldNonblockSetting );
         apr_socket_timeout_get( socketHandle, &oldTimeoutSetting );
 
+        // Temporarily make it what we want, blocking.
+        apr_socket_opt_set( socketHandle, APR_SO_NONBLOCK, 0 );
+
         // Timeout and non-timeout case require very different logic.
         if( timeout <= 0 ) {
-
-            // Temporarily make it what we want, blocking with no timeout.
-            apr_socket_opt_set( socketHandle, APR_SO_NONBLOCK, 0 );
             apr_socket_timeout_set( socketHandle, -1 );
-
-            // try to Connect to the provided address.
-            checkResult( apr_socket_connect( socketHandle, remoteAddress ) );
-
         } else {
-
-            // Temporarily make it what we want, blocking with no timeout.
-            apr_socket_opt_set( socketHandle, APR_SO_NONBLOCK, 1 );
-            apr_socket_timeout_set( socketHandle, 0 );
-
-            apr_status_t result = apr_socket_connect( socketHandle, remoteAddress );
-
-            // Special case, it connected, usually doesn't happen.
-            if( result == APR_SUCCESS ) {
-                return;
-            } else if( APR_STATUS_IS_EINPROGRESS( result ) ) {
-
-                int num = 0;
-                const apr_pollfd_t* signalled = NULL;
-                apr_pollfd_t pfd = { apr_pool.getAprPool(), APR_POLL_SOCKET, APR_POLLOUT, 0, { NULL }, NULL };
-
-                pfd.desc.s = socketHandle;
-
-                // Add the socket to pollset to check APR_POLLOUT(writable)
-                apr_pollset_add( pollSet, &pfd );
-
-                // Poll for the specified timeout, the value in APR is taken as Microseconds.
-                result = apr_pollset_poll( pollSet, timeout * 1000, &num, &signalled );
-
-                // Remove the socket from the pollset now.
-                apr_pollset_remove( pollSet, &pfd );
-
-                if( result != APR_SUCCESS || num == 0 ) {
-                    close();
-                    throw SocketTimeoutException(
-                         __FILE__, __LINE__,
-                         "Timed out while waiting for Socket to Connect." );
-                }
-
-            } else {
-                close();
-                throw SocketException(
-                    __FILE__, __LINE__, "Error while attempting to connect to remote host.",
-                    SocketError::getErrorString().c_str() );
-            }
+            apr_socket_timeout_set( socketHandle, timeout * 1000 );
         }
 
+        // try to Connect to the provided address.
+        checkResult( apr_socket_connect( socketHandle, remoteAddress ) );
+
         // Now that we are connected, we want to go back to old settings.
         apr_socket_opt_set( socketHandle, APR_SO_NONBLOCK, oldNonblockSetting );
         apr_socket_timeout_set( socketHandle, oldTimeoutSetting );
@@ -494,12 +407,6 @@ void TcpSocket::close() throw( decaf::io
             apr_socket_close( socketHandle );
             socketHandle = NULL;
         }
-
-        // Destroy the pollset
-        if( pollSet != NULL ) {
-            apr_pollset_destroy( pollSet );
-            pollSet = NULL;
-        }
     }
     DECAF_CATCH_RETHROW( decaf::io::IOException )
     DECAF_CATCH_EXCEPTION_CONVERT( Exception, decaf::io::IOException )
@@ -584,6 +491,7 @@ void TcpSocket::setOption( int option, i
         apr_int32_t aprId = 0;
 
         if( option == SocketOptions::SOCKET_OPTION_TIMEOUT ) {
+            checkResult( apr_socket_opt_set( socketHandle, APR_SO_NONBLOCK, 0 ) );
             // Time in APR for sockets is in microseconds so multiply by 1000.
             checkResult( apr_socket_timeout_set( socketHandle, value * 1000 ) );
             this->soTimeout = value;

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/net/tcp/TcpSocket.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/net/tcp/TcpSocket.h?rev=938581&r1=938580&r2=938581&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/net/tcp/TcpSocket.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/net/tcp/TcpSocket.h Tue Apr 27 17:59:34 2010
@@ -25,7 +25,6 @@
 #include <decaf/internal/AprPool.h>
 
 #include <apr_network_io.h>
-#include <apr_poll.h>
 
 #include <decaf/io/IOException.h>
 #include <decaf/net/SocketTimeoutException.h>
@@ -80,11 +79,6 @@ namespace tcp {
         SocketAddress remoteAddress;
 
         /**
-         * APR Pollset used for connect and accept when soTimeout is set.
-         */
-        apr_pollset_t* pollSet;
-
-        /**
          * The input stream for reading this socket.
          */
         TcpSocketInputStream* inputStream;
@@ -168,7 +162,8 @@ namespace tcp {
         /**
          * {@inheritDoc}
          */
-        virtual void accept( SocketImpl* socket ) throw( decaf::io::IOException );
+        virtual void accept( SocketImpl* socket )
+            throw( decaf::io::IOException );
 
         /**
          * {@inheritDoc}
@@ -181,7 +176,6 @@ namespace tcp {
          */
         virtual void connect( const std::string& hostname, int port, int timeout )
             throw( decaf::io::IOException,
-                   decaf::net::SocketTimeoutException,
                    decaf::lang::exceptions::IllegalArgumentException );
 
         /**

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/ServerSocket.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/ServerSocket.cpp?rev=938581&r1=938580&r2=938581&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/ServerSocket.cpp (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/ServerSocket.cpp Tue Apr 27 17:59:34 2010
@@ -196,7 +196,7 @@ bool ServerSocket::isClosed() const {
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-Socket* ServerSocket::accept() throw( decaf::io::IOException, decaf::net::SocketTimeoutException ) {
+Socket* ServerSocket::accept() throw( decaf::io::IOException ) {
 
     checkClosed();
 

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/ServerSocket.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/ServerSocket.h?rev=938581&r1=938580&r2=938581&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/ServerSocket.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/ServerSocket.h Tue Apr 27 17:59:34 2010
@@ -205,10 +205,10 @@ namespace net{
          *         the caller and must be explicitly freed by them.
          *
          * @throws IOException if an I/O error occurs while binding the socket.
+         * @throws SocketException if an error occurs while blocking on the accept call.
          * @throws SocketTimeoutException if the SO_TIMEOUT option was used and the accept timed out.
          */
-        Socket* accept()
-            throw( decaf::io::IOException, decaf::net::SocketTimeoutException );
+        Socket* accept() throw( decaf::io::IOException );
 
         /**
          * Closes the server socket, causing any Threads blocked on an accept call to

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/Socket.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/Socket.cpp?rev=938581&r1=938580&r2=938581&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/Socket.cpp (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/Socket.cpp Tue Apr 27 17:59:34 2010
@@ -222,7 +222,6 @@ void Socket::connect( const std::string&
 ////////////////////////////////////////////////////////////////////////////////
 void Socket::connect( const std::string& host, int port, int timeout )
     throw( decaf::io::IOException,
-           decaf::net::SocketTimeoutException,
            decaf::lang::exceptions::IllegalArgumentException ) {
 
     checkClosed();
@@ -261,7 +260,6 @@ void Socket::connect( const std::string&
             throw ex;
         }
     }
-    DECAF_CATCH_RETHROW( SocketTimeoutException )
     DECAF_CATCH_RETHROW( IOException )
     DECAF_CATCH_RETHROW( IllegalArgumentException )
     DECAF_CATCH_EXCEPTION_CONVERT( Exception, IOException )

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/Socket.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/Socket.h?rev=938581&r1=938580&r2=938581&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/Socket.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/Socket.h Tue Apr 27 17:59:34 2010
@@ -179,7 +179,6 @@ namespace net{
          */
         virtual void connect( const std::string& host, int port, int timeout )
             throw( decaf::io::IOException,
-                   decaf::net::SocketTimeoutException,
                    decaf::lang::exceptions::IllegalArgumentException );
 
         /**

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/SocketImpl.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/SocketImpl.h?rev=938581&r1=938580&r2=938581&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/SocketImpl.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/SocketImpl.h Tue Apr 27 17:59:34 2010
@@ -25,6 +25,7 @@
 #include <decaf/io/OutputStream.h>
 
 #include <decaf/net/SocketException.h>
+#include <decaf/net/SocketTimeoutException.h>
 #include <decaf/net/SocketOptions.h>
 
 #include <string>
@@ -67,8 +68,13 @@ namespace net {
          *      The accepted connection.
          *
          * @throws IOException if an I/O error occurs while attempting this operation.
+         * @throws SocketException if an error occurs while performing an Accept on the socket.
+         * @throws SocketTimeoutException if the accept call times out due to SO_TIMEOUT being set.
          */
-        virtual void accept( SocketImpl* socket ) throw( decaf::io::IOException ) = 0;
+        virtual void accept( SocketImpl* socket )
+            throw( decaf::io::IOException,
+                   decaf::net::SocketException,
+                   decaf::net::SocketTimeoutException ) = 0;
 
         /**
          * Connects this socket to the given host and port.
@@ -81,10 +87,12 @@ namespace net {
          *      Time in milliseconds to wait for a connection, 0 indicates forever.
          *
          * @throws IOException if an I/O error occurs while attempting this operation.
+         * @throws SocketTimeoutException if the connect call times out due to timeout being set.
          * @throws IllegalArguementException if a parameter has an illegal value.
          */
         virtual void connect( const std::string& hostname, int port, int timeout )
             throw( decaf::io::IOException,
+                   decaf::net::SocketTimeoutException,
                    decaf::lang::exceptions::IllegalArgumentException ) = 0;
 
         /**