bdad2f7603a9fd3b97989f3b6ff1d6032e19cafa
[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 /* \r
36  * Function: create_socket_info\r
37  * \r
38  *  Description:\r
39  *    Allocates a new socket info context structure and initializes some fields.\r
40 */\r
41 struct ibsp_socket_info *\r
42 create_socket_info(void)\r
43 {\r
44         struct ibsp_socket_info *socket_info;\r
45 \r
46         IBSP_ENTER( IBSP_DBG_SI );\r
47 \r
48         socket_info = HeapAlloc( g_ibsp.heap,\r
49                 HEAP_ZERO_MEMORY, sizeof(struct ibsp_socket_info) );\r
50         if( socket_info == NULL )\r
51         {\r
52                 IBSP_TRACE_EXIT( IBSP_DBG_SI,\r
53                         ("HeapAlloc() failed: %d\n", GetLastError()) );\r
54                 return NULL;\r
55         }\r
56 \r
57         cl_spinlock_init( &socket_info->mutex );\r
58 \r
59         cl_qlist_init( &socket_info->buf_mem_list.list );\r
60         cl_spinlock_init( &socket_info->buf_mem_list.mutex );\r
61 \r
62         cl_qlist_init( &socket_info->listen.list );\r
63 \r
64         cl_spinlock_init( &socket_info->send_lock );\r
65         cl_spinlock_init( &socket_info->recv_lock );\r
66 \r
67 #ifdef _DEBUG_\r
68         memset( socket_info->recv_wr, 0x38, sizeof(socket_info->send_wr) );\r
69         memset( socket_info->recv_wr, 0x38, sizeof(socket_info->recv_wr) );\r
70         memset( socket_info->recv_wr, 0x38, sizeof(socket_info->dup_wr) );\r
71 #endif\r
72 \r
73         socket_info->switch_socket = INVALID_SOCKET;\r
74         /*\r
75          * Preset to 1, IBSPCloseSocket will decrement it, and switch socket\r
76          * will be freed once it goes to zero after an upcall.\r
77          */\r
78         socket_info->ref_cnt = 1;\r
79 \r
80         IBSP_TRACE( IBSP_DBG_SI, ("socket_info (%p)\n", socket_info) );\r
81 \r
82         IBSP_EXIT( IBSP_DBG_SI );\r
83         return socket_info;\r
84 }\r
85 \r
86 \r
87 /* \r
88  * Function: free_sock_info\r
89  * \r
90  * Description:\r
91  *  This routine frees the socket context structure.\r
92  */\r
93 void\r
94 free_socket_info(\r
95                                         struct ibsp_socket_info         *socket_info )\r
96 {\r
97         IBSP_ENTER( IBSP_DBG_SI );\r
98 \r
99         CL_ASSERT( !socket_info->conn_item.p_map );\r
100 \r
101         cl_spinlock_destroy( &socket_info->buf_mem_list.mutex );\r
102         cl_spinlock_destroy( &socket_info->mutex );\r
103 \r
104         cl_spinlock_destroy( &socket_info->send_lock );\r
105         cl_spinlock_destroy( &socket_info->recv_lock );\r
106 \r
107         HeapFree( g_ibsp.heap, 0, socket_info );\r
108 \r
109         IBSP_TRACE( IBSP_DBG_SI, ("socket_info (%p)\n", socket_info) );\r
110 \r
111         IBSP_EXIT( IBSP_DBG_SI );\r
112 }\r
113 \r
114 \r
115 void\r
116 deref_socket_info(\r
117         IN                              struct ibsp_socket_info         *p_socket )\r
118 {\r
119         int             ret, error;\r
120 \r
121         if( !cl_atomic_dec( &p_socket->ref_cnt ) )\r
122         {\r
123                 if( p_socket->switch_socket != INVALID_SOCKET )\r
124                 {\r
125                         /* ref_cnt hit zero - destroy the switch socket. */\r
126                         IBSP_TRACE1( IBSP_DBG_SI,\r
127                                 ("socket=0x%p calling lpWPUCloseSocketHandle=0x%p\n",\r
128                                 p_socket, p_socket->switch_socket) );\r
129 \r
130                         ret = g_ibsp.up_call_table.lpWPUCloseSocketHandle(\r
131                                 p_socket->switch_socket, &error );\r
132                         if( ret == SOCKET_ERROR )\r
133                         {\r
134                                 IBSP_ERROR( ("WPUCloseSocketHandle failed: %d\n", error) );\r
135                         }\r
136                         else\r
137                         {\r
138                                 STAT_DEC( wpusocket_num );\r
139                         }\r
140 \r
141                         p_socket->switch_socket = INVALID_SOCKET;\r
142                 }\r
143 \r
144                 /*\r
145                  * This only works because the socket doesn't have its own CQ.  If it\r
146                  * did CQ destruction would have to be async since IBSPCloseSocket can\r
147                  * be invoked from the CQ callback thread context, and freeing the\r
148                  * socket structure would need to be delayed until the CQ's destroy\r
149                  * callback.\r
150                  */\r
151                 free_socket_info( p_socket );\r
152         }\r
153 }\r