b73f8c8beee9f62e476e3c71d04d0031e983148c
[mirror/winof/.git] / ulp / wsd / user / sockinfo.c
1 /*\r
2  * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
3  *\r
4  * This software is available to you under the OpenIB.org BSD license\r
5  * below:\r
6  *\r
7  *     Redistribution and use in source and binary forms, with or\r
8  *     without modification, are permitted provided that the following\r
9  *     conditions are met:\r
10  *\r
11  *      - Redistributions of source code must retain the above\r
12  *        copyright notice, this list of conditions and the following\r
13  *        disclaimer.\r
14  *\r
15  *      - Redistributions in binary form must reproduce the above\r
16  *        copyright notice, this list of conditions and the following\r
17  *        disclaimer in the documentation and/or other materials\r
18  *        provided with the distribution.\r
19  *\r
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
23  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
24  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
25  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
26  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
27  * SOFTWARE.\r
28  *\r
29  * $Id$\r
30  */\r
31 \r
32 #include "ibspdll.h"\r
33 \r
34 \r
35 static void\r
36 free_socket_info(\r
37         IN                              struct ibsp_socket_info         *socket_info );\r
38 \r
39 /* \r
40  * Function: create_socket_info\r
41  * \r
42  *  Description:\r
43  *    Allocates a new socket info context structure and initializes some fields.\r
44 */\r
45 struct ibsp_socket_info *\r
46 create_socket_info(\r
47         OUT                             LPINT                                           lpErrno )\r
48 {\r
49         struct ibsp_socket_info *socket_info;\r
50 \r
51         IBSP_ENTER( IBSP_DBG_SI );\r
52 \r
53         socket_info = HeapAlloc( g_ibsp.heap,\r
54                 HEAP_ZERO_MEMORY, sizeof(struct ibsp_socket_info) );\r
55         if( socket_info == NULL )\r
56         {\r
57                 IBSP_TRACE_EXIT( IBSP_DBG_SI,\r
58                         ("HeapAlloc() failed: %d\n", GetLastError()) );\r
59                 *lpErrno = WSAENOBUFS;\r
60                 return NULL;\r
61         }\r
62 \r
63         cl_spinlock_construct( &socket_info->mutex );\r
64         cl_spinlock_construct( &socket_info->buf_mem_list.mutex );\r
65         cl_spinlock_construct( &socket_info->send_lock );\r
66         cl_spinlock_construct( &socket_info->recv_lock );\r
67         cl_qlist_init( &socket_info->buf_mem_list.list );\r
68         cl_qlist_init( &socket_info->listen.list );\r
69 \r
70         if( cl_spinlock_init( &socket_info->mutex ) != CL_SUCCESS )\r
71                 goto err;\r
72 \r
73         if( cl_spinlock_init( &socket_info->buf_mem_list.mutex ) != CL_SUCCESS )\r
74                 goto err;\r
75 \r
76         if( cl_spinlock_init( &socket_info->send_lock ) != CL_SUCCESS )\r
77                 goto err;\r
78 \r
79         if( cl_spinlock_init( &socket_info->recv_lock ) != CL_SUCCESS )\r
80                 goto err;\r
81 \r
82 #ifdef _DEBUG_\r
83         memset( socket_info->recv_wr, 0x38, sizeof(socket_info->send_wr) );\r
84         memset( socket_info->recv_wr, 0x38, sizeof(socket_info->recv_wr) );\r
85         memset( socket_info->recv_wr, 0x38, sizeof(socket_info->dup_wr) );\r
86 #endif\r
87 \r
88         socket_info->switch_socket =\r
89                 g_ibsp.up_call_table.lpWPUCreateSocketHandle(\r
90                 0, (DWORD_PTR)socket_info, lpErrno );\r
91 \r
92         if( socket_info->switch_socket == INVALID_SOCKET )\r
93         {\r
94                 IBSP_ERROR(\r
95                         ("WPUCreateSocketHandle() failed: %d", *lpErrno) );\r
96 err:\r
97                 free_socket_info( socket_info );\r
98                 IBSP_EXIT( IBSP_DBG_SI );\r
99                 return NULL;\r
100         }\r
101 \r
102         STAT_INC( wpusocket_num );\r
103 \r
104         /*\r
105          * Preset to 1, IBSPCloseSocket will decrement it, and switch socket\r
106          * will be freed once it goes to zero.\r
107          */\r
108         socket_info->ref_cnt = 1;\r
109 \r
110         IBSP_TRACE( IBSP_DBG_SI, ("socket_info (%p), switch socket (%p)\n",\r
111                 socket_info, socket_info->switch_socket) );\r
112 \r
113         IBSP_EXIT( IBSP_DBG_SI );\r
114         return socket_info;\r
115 }\r
116 \r
117 \r
118 static void\r
119 free_socket_info(\r
120         IN                              struct ibsp_socket_info         *p_socket )\r
121 {\r
122         int             ret, error;\r
123 \r
124         if( p_socket->switch_socket != INVALID_SOCKET )\r
125         {\r
126                 /* ref_cnt hit zero - destroy the switch socket. */\r
127                 IBSP_TRACE1( IBSP_DBG_SI,\r
128                         ("socket=0x%p calling lpWPUCloseSocketHandle=0x%p\n",\r
129                         p_socket, p_socket->switch_socket) );\r
130 \r
131                 ret = g_ibsp.up_call_table.lpWPUCloseSocketHandle(\r
132                         p_socket->switch_socket, &error );\r
133                 if( ret == SOCKET_ERROR )\r
134                 {\r
135                         IBSP_ERROR( ("WPUCloseSocketHandle failed: %d\n", error) );\r
136                 }\r
137                 else\r
138                 {\r
139                         STAT_DEC( wpusocket_num );\r
140                 }\r
141 \r
142                 p_socket->switch_socket = INVALID_SOCKET;\r
143         }\r
144 \r
145         CL_ASSERT( !p_socket->qp );\r
146         CL_ASSERT( !p_socket->conn_item.p_map );\r
147 \r
148         cl_spinlock_destroy( &p_socket->buf_mem_list.mutex );\r
149         cl_spinlock_destroy( &p_socket->mutex );\r
150 \r
151         cl_spinlock_destroy( &p_socket->send_lock );\r
152         cl_spinlock_destroy( &p_socket->recv_lock );\r
153 \r
154         HeapFree( g_ibsp.heap, 0, p_socket );\r
155 }\r
156 \r
157 \r
158 /* \r
159  * Function: deref_sock_info\r
160  * \r
161  * Description:\r
162  *      This routine decrements a socket context's reference count, and if\r
163  *      it reaches zero, frees the socket context structure.\r
164  */\r
165 void AL_API\r
166 deref_socket_info(\r
167         IN                              struct ibsp_socket_info         *p_socket )\r
168 {\r
169         IBSP_ENTER( IBSP_DBG_SI );\r
170 \r
171         if( !cl_atomic_dec( &p_socket->ref_cnt ) )\r
172         {\r
173                 free_socket_info( p_socket );\r
174                 IBSP_TRACE( IBSP_DBG_SI, ("Freed socket_info (%p)\n", p_socket) );\r
175         }\r
176         IBSP_EXIT( IBSP_DBG_SI );\r
177 }\r