[WSD] Make QP destruction asynchronous to speed up socket closure.
authorftillier <ftillier@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Tue, 27 Sep 2005 00:48:36 +0000 (00:48 +0000)
committerftillier <ftillier@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Tue, 27 Sep 2005 00:48:36 +0000 (00:48 +0000)
Cleanup socket creation by consolitdating operations into create_socket_info.

Signed-off-by: Fab Tillier (ftillier@silverstorm.com)
git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@96 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

ulp/wsd/user/ibsp_duplicate.c
ulp/wsd/user/ibsp_iblow.c
ulp/wsd/user/ibspdll.c
ulp/wsd/user/ibspproto.h
ulp/wsd/user/sockinfo.c

index e7108f5..9258da4 100644 (file)
@@ -79,19 +79,17 @@ setup_duplicate_socket(
                                                  fname );      // name of map object\r
        if( h == NULL )\r
        {\r
-               IBSP_ERROR(\r
-                       ("CreateFileMapping failed with %d\n", GetLastError()) );\r
+               IBSP_ERROR( ("CreateFileMapping failed with %d\n", GetLastError()) );\r
                ret = WSAENETDOWN;\r
-               goto done;\r
+               goto err1;\r
        }\r
 \r
        /* Make sure this file already existed. */\r
        if( GetLastError() != ERROR_ALREADY_EXISTS )\r
        {\r
-               CloseHandle( h );\r
                IBSP_ERROR( ("not mapping for socket duplicate info\n") );\r
                ret = WSAENETDOWN;\r
-               goto done;\r
+               goto err1;\r
        }\r
 \r
        /* Get a pointer to the file-mapped shared memory. */\r
@@ -102,34 +100,9 @@ setup_duplicate_socket(
                                                         0 );   // default: map entire file\r
        if( dup_info == NULL )\r
        {\r
-               IBSP_ERROR(\r
-                       ("MapViewOfFile failed with %d\n", GetLastError()) );\r
+               IBSP_ERROR( ("MapViewOfFile failed with %d\n", GetLastError()) );\r
                ret = WSAENETDOWN;\r
-               goto done;\r
-       }\r
-\r
-       /* Check if we already have a switch socket handle. We can have both cases \r
-        * if the two processes are calling IBSPDuplicate back and forth. */\r
-       if( socket_info->switch_socket == INVALID_SOCKET )\r
-       {\r
-               socket_info->switch_socket =\r
-                       g_ibsp.up_call_table.lpWPUCreateSocketHandle(0,\r
-                                                                                                                (DWORD_PTR) socket_info, &ret );\r
-\r
-               if( socket_info->switch_socket == INVALID_SOCKET )\r
-               {\r
-                       IBSP_ERROR(\r
-                               ("WPUCreateSocketHandle() failed: %d", ret) );\r
-                       goto done;\r
-               }\r
-               else\r
-               {\r
-                       fzprint(("%s():%d:0x%x:0x%x: socket_info=0x%p switch_socket=0x%p \n",\r
-                                        __FUNCTION__, __LINE__, GetCurrentProcessId(), GetCurrentThreadId(),\r
-                                        socket_info, socket_info->switch_socket));\r
-\r
-                       STAT_INC( wpusocket_num );\r
-               }\r
+               goto err1;\r
        }\r
 \r
        socket_info->peer_addr = dup_info->peer_addr;\r
@@ -143,32 +116,21 @@ setup_duplicate_socket(
        socket_info->port = get_port_from_ip_address( dup_info->local_addr.sin_addr );\r
        if( socket_info->port == NULL )\r
        {\r
-               IBSP_ERROR(\r
-                       ("incoming destination IP address not local (%s)\n",\r
+               IBSP_ERROR( ("incoming destination IP address not local (%s)\n",\r
                        inet_ntoa( dup_info->local_addr.sin_addr )) );\r
                ret = WSAENETDOWN;\r
-               goto done;\r
-       }\r
-\r
-       ret = ib_create_socket( socket_info );\r
-       if( ret )\r
-       {\r
-               IBSP_ERROR_EXIT(\r
-                       ("ib_create socket failed with %d\n", ret) );\r
-               ret = WSAENOBUFS;\r
-               goto done;\r
+               goto err1;\r
        }\r
 \r
        /* Get the GUID for the remote IP address. */\r
        ret = query_guid_address( socket_info->port,\r
-                                                        socket_info->peer_addr.sin_addr.S_un.S_addr,\r
-                                                        &dest_port_guid );\r
+               socket_info->peer_addr.sin_addr.S_un.S_addr, &dest_port_guid );\r
        if( ret )\r
        {\r
                IBSP_ERROR( ("query_guid_address failed for IP %08x\n",\r
                        socket_info->peer_addr.sin_addr.s_addr) );\r
-               ret = WSAEHOSTUNREACH;\r
-               goto done;\r
+               ret = WSAENETDOWN;\r
+               goto err1;\r
        }\r
 \r
        /* Get the path record */\r
@@ -177,39 +139,51 @@ setup_duplicate_socket(
        {\r
                IBSP_ERROR( ("query_pr failed for IP %08x\n",\r
                        socket_info->peer_addr.sin_addr.s_addr) );\r
-               ret = WSAEHOSTUNREACH;\r
-               goto done;\r
+               ret = WSAENETDOWN;\r
+               goto err1;\r
        }\r
 \r
        IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_DUPLICATING_NEW );\r
        socket_info->h_event = CreateEvent( NULL, FALSE, FALSE, NULL );\r
+       if( !socket_info->h_event )\r
+       {\r
+               IBSP_ERROR( ("CreateEvent failed (%d)\n", GetLastError()) );\r
+               goto err1;\r
+       }\r
+\r
+       ret = ib_create_socket( socket_info );\r
+       if( ret )\r
+       {\r
+               IBSP_ERROR( ("ib_create socket failed with %d\n", ret) );\r
+               goto err1;\r
+       }\r
 \r
        /* Connects the QP. */\r
        ret = ib_connect( socket_info, &path_rec );\r
        if( ret != WSAEWOULDBLOCK )\r
        {\r
                IBSP_ERROR( ("ib_connect failed (%d)\n", ret) );\r
-               goto done;\r
+               goto err2;\r
        }\r
 \r
        if( WaitForSingleObject( socket_info->h_event, INFINITE ) != WAIT_OBJECT_0 )\r
-       {\r
                IBSP_ERROR( ("WaitForSingleObject failed\n") );\r
-       }\r
 \r
        cl_spinlock_acquire( &socket_info->mutex );\r
        if( socket_info->socket_state != IBSP_CONNECTED )\r
        {\r
                cl_spinlock_release( &socket_info->mutex );\r
                IBSP_ERROR( ("Failed to connect\n") );\r
-               ret = WSAEHOSTUNREACH;\r
-               goto done;\r
+               ret = WSAENETDOWN;\r
+err2:\r
+               ib_destroy_socket( socket_info );\r
+       }\r
+       else\r
+       {\r
+               cl_spinlock_release( &socket_info->mutex );\r
        }\r
-       cl_spinlock_release( &socket_info->mutex );\r
-\r
-       ret = 0;\r
 \r
-done:\r
+err1:\r
        if( h )\r
                CloseHandle( h );\r
 \r
@@ -220,7 +194,6 @@ done:
        }\r
 \r
        IBSP_EXIT( IBSP_DBG_CONN );\r
-\r
        return ret;\r
 }\r
 \r
index a01c3af..1acd063 100644 (file)
@@ -873,23 +873,18 @@ ib_destroy_socket(
 \r
        if( socket_info->qp )\r
        {\r
-               status = ib_destroy_qp( socket_info->qp, ib_sync_destroy );\r
-               if( status )\r
+               cl_atomic_inc( &socket_info->ref_cnt );\r
+               status = ib_destroy_qp( socket_info->qp, deref_socket_info );\r
+               if( status != IB_SUCCESS )\r
                {\r
-                       IBSP_ERROR( ("ib_destroy_qp failed (%d)\n", status) );\r
+                       IBSP_ERROR( ("ib_destroy_qp returned %s\n",\r
+                               ib_get_err_str( status )) );\r
+                       deref_socket_info( socket_info );\r
                }\r
-               else\r
-               {\r
-                       IBSP_TRACE( IBSP_DBG_WQ,\r
-                               ("%s():%d:0x%x:0x%x: ib_destroy_qp() finished\n", __FUNCTION__,\r
-                               __LINE__, GetCurrentProcessId(), GetCurrentThreadId()) );\r
-\r
-                       socket_info->qp = NULL;\r
 \r
-                       STAT_DEC( qp_num );\r
+               ib_release_cq_tinfo( socket_info->cq_tinfo );\r
 \r
-                       ib_release_cq_tinfo( socket_info->cq_tinfo );\r
-               }\r
+               socket_info->qp = NULL;\r
        }\r
 \r
        IBSP_EXIT( IBSP_DBG_EP );\r
@@ -938,6 +933,7 @@ ib_create_socket(
                &socket_info->qp );\r
        if( status )\r
        {\r
+               ib_release_cq_tinfo( socket_info->cq_tinfo );\r
                IBSP_ERROR_EXIT(\r
                        ("ib_create_qp returned %s\n", ib_get_err_str( status )) );\r
                return WSAENOBUFS;\r
index 7933df0..e7bf41b 100644 (file)
@@ -242,7 +242,6 @@ IBSPAccept(
        struct ibsp_socket_info *socket_info = (struct ibsp_socket_info *)s;\r
        struct ibsp_socket_info *new_socket_info;\r
        int ret;\r
-       SOCKET new_socket = INVALID_SOCKET;\r
        WSABUF caller_id;\r
        WSABUF callee_id;\r
        struct listen_incoming *incoming;\r
@@ -397,45 +396,24 @@ reject:
        }\r
 \r
        /* Create a new socket here  */\r
-       new_socket_info = create_socket_info();\r
-       if( new_socket_info == NULL )\r
+       new_socket_info = create_socket_info( lpErrno );\r
+       if( !new_socket_info )\r
        {\r
                cl_spinlock_release( &socket_info->mutex );\r
 \r
-               IBSP_ERROR_EXIT( ("create_socket_info return NULL\n") );\r
-               *lpErrno = WSAENOBUFS;\r
-               return INVALID_SOCKET;\r
-       }\r
-\r
-       new_socket = g_ibsp.up_call_table.lpWPUCreateSocketHandle(\r
-               0, (DWORD_PTR)new_socket_info, lpErrno );\r
-\r
-       if( new_socket == INVALID_SOCKET )\r
-       {\r
-               cl_spinlock_release( &socket_info->mutex );\r
-\r
-               IBSP_ERROR_EXIT(\r
-                       ("WPUCreateSocketHandle() failed: %d", *lpErrno) );\r
-               deref_socket_info( new_socket_info );\r
+               IBSP_ERROR_EXIT( ("create_socket_info failed (%d)\n", *lpErrno) );\r
                return INVALID_SOCKET;\r
        }\r
 \r
-       STAT_INC( wpusocket_num );\r
-\r
-       fzprint(("%s():%d:0x%x:0x%x: new_socket_info=0x%p new_socket=0x%p \n", __FUNCTION__,\r
-                        __LINE__, GetCurrentProcessId(), GetCurrentThreadId(), new_socket_info,\r
-                        new_socket));\r
-\r
        /* Time to allocate our IB QP */\r
        new_socket_info->port = port;\r
-       ret = ib_create_socket( new_socket_info );\r
-       if( ret )\r
+       *lpErrno = ib_create_socket( new_socket_info );\r
+       if( *lpErrno )\r
        {\r
                cl_spinlock_release( &socket_info->mutex );\r
+               deref_socket_info( new_socket_info );\r
 \r
-               IBSP_ERROR_EXIT(\r
-                       ("ib_create socket failed with %d\n", ret) );\r
-               *lpErrno = WSAENOBUFS;\r
+               IBSP_ERROR_EXIT( ("ib_create socket failed with %d\n", *lpErrno) );\r
                return INVALID_SOCKET;\r
        }\r
 \r
@@ -456,11 +434,11 @@ reject:
        memcpy( addr, &incoming->params.source, sizeof(struct sockaddr_in) );\r
        *addrlen = sizeof(struct sockaddr_in);\r
 \r
-       IBSP_TRACE( IBSP_DBG_CONN, ("The socket address of connecting entity is\n") );\r
+       IBSP_TRACE( IBSP_DBG_CONN,\r
+               ("The socket address of connecting entity is\n") );\r
        DebugPrintSockAddr( IBSP_DBG_CONN, gdbg_lvl, &incoming->params.source );\r
 \r
        new_socket_info->peer_addr = incoming->params.source;\r
-       new_socket_info->switch_socket = new_socket;\r
 \r
        new_socket_info->h_event = CreateEvent( NULL, FALSE, FALSE, NULL );\r
 \r
@@ -473,10 +451,6 @@ reject:
        {\r
                IBSP_CHANGE_SOCKET_STATE( new_socket_info, IBSP_CREATE );\r
                cl_spinlock_release( &new_socket_info->mutex );\r
-               /* Free the socket descriptor */\r
-               fzprint(("%s():%d:0x%x:0x%x: socket=0x%p calling lpWPUCloseSocketHandle=0x%p\n",\r
-                                __FUNCTION__, __LINE__, GetCurrentProcessId(), GetCurrentThreadId(),\r
-                                socket_info, socket_info->switch_socket));\r
 \r
                if( g_ibsp.up_call_table.lpWPUCloseSocketHandle(\r
                        new_socket_info->switch_socket, &ret ) == SOCKET_ERROR )\r
@@ -536,8 +510,6 @@ reject:
                                /* The accept failed (by a REJ for instance). */\r
 \r
                                /* Free the socket descriptor */\r
-                               fzprint(("%s():%d:0x%x:0x%x: socket=0x%p calling lpWPUCloseSocketHandle=0x%p\n", __FUNCTION__, __LINE__, GetCurrentProcessId(), GetCurrentThreadId(), socket_info, socket_info->switch_socket));\r
-\r
                                if( g_ibsp.up_call_table.lpWPUCloseSocketHandle(\r
                                        new_socket_info->switch_socket, lpErrno ) == SOCKET_ERROR )\r
                                {\r
@@ -558,8 +530,8 @@ reject:
                                new_socket_info = (struct ibsp_socket_info *)INVALID_SOCKET;\r
                        }\r
 \r
-                       CL_TRACE_EXIT(IBSP_DBG_CONN, gdbg_lvl,\r
-                               ("returns new SocketID (0x%x)\n", new_socket) );\r
+                       IBSP_TRACE_EXIT( IBSP_DBG_CONN,\r
+                               ("returns new SocketID (0x%x)\n", new_socket_info) );\r
 \r
                        return (SOCKET) new_socket_info;\r
                }\r
@@ -2095,86 +2067,69 @@ IBSPSocket(
 \r
        if( af != AF_INET )\r
        {\r
-               IBSP_ERROR(\r
+               IBSP_ERROR_EXIT(\r
                        ("bad family %d instead of %d\n", af, AF_INET) );\r
                *lpErrno = WSAEAFNOSUPPORT;\r
-               goto error;\r
+               return INVALID_SOCKET;\r
        }\r
 \r
        if( type != SOCK_STREAM )\r
        {\r
-               IBSP_ERROR(\r
+               IBSP_ERROR_EXIT(\r
                        ("bad type %d instead of %d\n", type, SOCK_STREAM) );\r
                *lpErrno = WSAEPROTOTYPE;\r
-               goto error;\r
+               return INVALID_SOCKET;\r
        }\r
 \r
        if( protocol != IPPROTO_TCP )\r
        {\r
-               IBSP_ERROR(\r
+               IBSP_ERROR_EXIT(\r
                        ("bad protocol %d instead of %d\n", protocol, IPPROTO_TCP) );\r
                *lpErrno = WSAEPROTONOSUPPORT;\r
-               goto error;\r
+               return INVALID_SOCKET;\r
        }\r
 \r
        if( (dwFlags != WSA_FLAG_OVERLAPPED) )\r
        {\r
-               IBSP_ERROR(\r
+               IBSP_ERROR_EXIT(\r
                        ("dwFlags is not WSA_FLAG_OVERLAPPED (%x)\n", dwFlags) );\r
                *lpErrno = WSAEINVAL;\r
-               goto error;\r
+               return INVALID_SOCKET;\r
        }\r
 \r
-       socket_info = create_socket_info();\r
+       socket_info = create_socket_info( lpErrno );\r
        if( socket_info == NULL )\r
        {\r
-               IBSP_ERROR( ("create_socket_info return NULL\n") );\r
-               *lpErrno = WSAENOBUFS;\r
-               goto error;\r
+               IBSP_ERROR_EXIT( ("create_socket_info return NULL\n") );\r
+               return INVALID_SOCKET;\r
        }\r
 \r
        if( lpProtocolInfo->dwProviderReserved != 0 )\r
        {\r
                /* This is a duplicate socket. */\r
-               int ret;\r
-\r
-               ret = setup_duplicate_socket( socket_info, lpProtocolInfo->dwProviderReserved );\r
-               if( ret )\r
-               {\r
-                       IBSP_ERROR(\r
-                               ("setup_duplicate_socket failed with %d\n",ret) );\r
-                       *lpErrno = ret;\r
-                       goto error;\r
-               }\r
-       }\r
-       else\r
-       {\r
-               socket_info->switch_socket =\r
-                       g_ibsp.up_call_table.lpWPUCreateSocketHandle( 0,\r
-                                                                                                                (DWORD_PTR) socket_info,\r
-                                                                                                                lpErrno );\r
-\r
-               if( socket_info->switch_socket != INVALID_SOCKET )\r
+               *lpErrno = setup_duplicate_socket(\r
+                       socket_info, lpProtocolInfo->dwProviderReserved );\r
+               if( *lpErrno )\r
                {\r
-                       IBSP_TRACE1( IBSP_DBG_SI, ("socket_info=0x%p switch_socket=0x%p \n",\r
-                               socket_info, socket_info->switch_socket) );\r
+                       int error;\r
 \r
-                       STAT_INC( wpusocket_num );\r
-               }\r
-       }\r
+                       if( g_ibsp.up_call_table.lpWPUCloseSocketHandle(\r
+                               socket_info->switch_socket, &error ) == SOCKET_ERROR )\r
+                       {\r
+                               IBSP_ERROR( ("WPUCloseSocketHandle failed: %d\n", error) );\r
+                       }\r
+                       else\r
+                       {\r
+                               STAT_DEC( wpusocket_num );\r
+                       }\r
 \r
-       if( socket_info->switch_socket == INVALID_SOCKET )\r
-       {\r
-               IBSP_ERROR(\r
-                       ("WPUCreateSocketHandle() failed: %d\n", *lpErrno) );\r
-               /* lpErrno has just been set */\r
-               goto error;\r
-       }\r
+                       socket_info->switch_socket = INVALID_SOCKET;\r
 \r
-       /* Success */\r
-       if( lpProtocolInfo->dwProviderReserved != 0 )\r
-       {\r
-               CL_ASSERT( socket_info->socket_state == IBSP_CONNECTED );\r
+                       deref_socket_info( socket_info );\r
+                       IBSP_ERROR(\r
+                               ("setup_duplicate_socket failed with %d\n", *lpErrno) );\r
+                       return INVALID_SOCKET;\r
+               }\r
        }\r
        else\r
        {\r
@@ -2199,16 +2154,6 @@ IBSPSocket(
                ("returning socket handle %p\n", socket_info) );\r
 \r
        return (SOCKET) socket_info;\r
-\r
-error:\r
-       if( socket_info )\r
-               deref_socket_info( socket_info );\r
-\r
-       CL_ASSERT( *lpErrno != 0 );\r
-\r
-       IBSP_ERROR_EXIT( ("Returning error %d\n", *lpErrno) );\r
-\r
-       return INVALID_SOCKET;\r
 }\r
 \r
 \r
index eb84bd0..a0ea72b 100644 (file)
@@ -31,7 +31,8 @@
 \r
 /* protos from socketinfo.c */\r
 struct ibsp_socket_info *\r
-create_socket_info( void );\r
+create_socket_info(\r
+       OUT                             LPINT                                           lpErrno );\r
 \r
 void AL_API\r
 deref_socket_info(\r
index 883a9bc..b73f8c8 100644 (file)
 #include "ibspdll.h"\r
 \r
 \r
+static void\r
+free_socket_info(\r
+       IN                              struct ibsp_socket_info         *socket_info );\r
+\r
 /* \r
  * Function: create_socket_info\r
  * \r
@@ -39,7 +43,8 @@
  *    Allocates a new socket info context structure and initializes some fields.\r
 */\r
 struct ibsp_socket_info *\r
-create_socket_info(void)\r
+create_socket_info(\r
+       OUT                             LPINT                                           lpErrno )\r
 {\r
        struct ibsp_socket_info *socket_info;\r
 \r
@@ -51,18 +56,28 @@ create_socket_info(void)
        {\r
                IBSP_TRACE_EXIT( IBSP_DBG_SI,\r
                        ("HeapAlloc() failed: %d\n", GetLastError()) );\r
+               *lpErrno = WSAENOBUFS;\r
                return NULL;\r
        }\r
 \r
-       cl_spinlock_init( &socket_info->mutex );\r
-\r
+       cl_spinlock_construct( &socket_info->mutex );\r
+       cl_spinlock_construct( &socket_info->buf_mem_list.mutex );\r
+       cl_spinlock_construct( &socket_info->send_lock );\r
+       cl_spinlock_construct( &socket_info->recv_lock );\r
        cl_qlist_init( &socket_info->buf_mem_list.list );\r
-       cl_spinlock_init( &socket_info->buf_mem_list.mutex );\r
-\r
        cl_qlist_init( &socket_info->listen.list );\r
 \r
-       cl_spinlock_init( &socket_info->send_lock );\r
-       cl_spinlock_init( &socket_info->recv_lock );\r
+       if( cl_spinlock_init( &socket_info->mutex ) != CL_SUCCESS )\r
+               goto err;\r
+\r
+       if( cl_spinlock_init( &socket_info->buf_mem_list.mutex ) != CL_SUCCESS )\r
+               goto err;\r
+\r
+       if( cl_spinlock_init( &socket_info->send_lock ) != CL_SUCCESS )\r
+               goto err;\r
+\r
+       if( cl_spinlock_init( &socket_info->recv_lock ) != CL_SUCCESS )\r
+               goto err;\r
 \r
 #ifdef _DEBUG_\r
        memset( socket_info->recv_wr, 0x38, sizeof(socket_info->send_wr) );\r
@@ -70,20 +85,76 @@ create_socket_info(void)
        memset( socket_info->recv_wr, 0x38, sizeof(socket_info->dup_wr) );\r
 #endif\r
 \r
-       socket_info->switch_socket = INVALID_SOCKET;\r
+       socket_info->switch_socket =\r
+               g_ibsp.up_call_table.lpWPUCreateSocketHandle(\r
+               0, (DWORD_PTR)socket_info, lpErrno );\r
+\r
+       if( socket_info->switch_socket == INVALID_SOCKET )\r
+       {\r
+               IBSP_ERROR(\r
+                       ("WPUCreateSocketHandle() failed: %d", *lpErrno) );\r
+err:\r
+               free_socket_info( socket_info );\r
+               IBSP_EXIT( IBSP_DBG_SI );\r
+               return NULL;\r
+       }\r
+\r
+       STAT_INC( wpusocket_num );\r
+\r
        /*\r
         * Preset to 1, IBSPCloseSocket will decrement it, and switch socket\r
         * will be freed once it goes to zero.\r
         */\r
        socket_info->ref_cnt = 1;\r
 \r
-       IBSP_TRACE( IBSP_DBG_SI, ("socket_info (%p)\n", socket_info) );\r
+       IBSP_TRACE( IBSP_DBG_SI, ("socket_info (%p), switch socket (%p)\n",\r
+               socket_info, socket_info->switch_socket) );\r
 \r
        IBSP_EXIT( IBSP_DBG_SI );\r
        return socket_info;\r
 }\r
 \r
 \r
+static void\r
+free_socket_info(\r
+       IN                              struct ibsp_socket_info         *p_socket )\r
+{\r
+       int             ret, error;\r
+\r
+       if( p_socket->switch_socket != INVALID_SOCKET )\r
+       {\r
+               /* ref_cnt hit zero - destroy the switch socket. */\r
+               IBSP_TRACE1( IBSP_DBG_SI,\r
+                       ("socket=0x%p calling lpWPUCloseSocketHandle=0x%p\n",\r
+                       p_socket, p_socket->switch_socket) );\r
+\r
+               ret = g_ibsp.up_call_table.lpWPUCloseSocketHandle(\r
+                       p_socket->switch_socket, &error );\r
+               if( ret == SOCKET_ERROR )\r
+               {\r
+                       IBSP_ERROR( ("WPUCloseSocketHandle failed: %d\n", error) );\r
+               }\r
+               else\r
+               {\r
+                       STAT_DEC( wpusocket_num );\r
+               }\r
+\r
+               p_socket->switch_socket = INVALID_SOCKET;\r
+       }\r
+\r
+       CL_ASSERT( !p_socket->qp );\r
+       CL_ASSERT( !p_socket->conn_item.p_map );\r
+\r
+       cl_spinlock_destroy( &p_socket->buf_mem_list.mutex );\r
+       cl_spinlock_destroy( &p_socket->mutex );\r
+\r
+       cl_spinlock_destroy( &p_socket->send_lock );\r
+       cl_spinlock_destroy( &p_socket->recv_lock );\r
+\r
+       HeapFree( g_ibsp.heap, 0, p_socket );\r
+}\r
+\r
+\r
 /* \r
  * Function: deref_sock_info\r
  * \r
@@ -95,44 +166,11 @@ void AL_API
 deref_socket_info(\r
        IN                              struct ibsp_socket_info         *p_socket )\r
 {\r
-       int             ret, error;\r
-\r
        IBSP_ENTER( IBSP_DBG_SI );\r
 \r
        if( !cl_atomic_dec( &p_socket->ref_cnt ) )\r
        {\r
-               if( p_socket->switch_socket != INVALID_SOCKET )\r
-               {\r
-                       /* ref_cnt hit zero - destroy the switch socket. */\r
-                       IBSP_TRACE1( IBSP_DBG_SI,\r
-                               ("socket=0x%p calling lpWPUCloseSocketHandle=0x%p\n",\r
-                               p_socket, p_socket->switch_socket) );\r
-\r
-                       ret = g_ibsp.up_call_table.lpWPUCloseSocketHandle(\r
-                               p_socket->switch_socket, &error );\r
-                       if( ret == SOCKET_ERROR )\r
-                       {\r
-                               IBSP_ERROR( ("WPUCloseSocketHandle failed: %d\n", error) );\r
-                       }\r
-                       else\r
-                       {\r
-                               STAT_DEC( wpusocket_num );\r
-                       }\r
-\r
-                       p_socket->switch_socket = INVALID_SOCKET;\r
-               }\r
-\r
-               CL_ASSERT( !p_socket->qp );\r
-               CL_ASSERT( !p_socket->conn_item.p_map );\r
-\r
-               cl_spinlock_destroy( &p_socket->buf_mem_list.mutex );\r
-               cl_spinlock_destroy( &p_socket->mutex );\r
-\r
-               cl_spinlock_destroy( &p_socket->send_lock );\r
-               cl_spinlock_destroy( &p_socket->recv_lock );\r
-\r
-               HeapFree( g_ibsp.heap, 0, p_socket );\r
-\r
+               free_socket_info( p_socket );\r
                IBSP_TRACE( IBSP_DBG_SI, ("Freed socket_info (%p)\n", p_socket) );\r
        }\r
        IBSP_EXIT( IBSP_DBG_SI );\r