Changeset a438de4 in mainline for uspace/srv/net/tl/tcp/conn.c
- Timestamp:
- 2011-12-19T18:50:17Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 1440eae, d9cf684a
- Parents:
- 58f6229 (diff), 522a4f9 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/tl/tcp/conn.c
r58f6229 ra438de4 56 56 57 57 LIST_INITIALIZE(conn_list); 58 FIBRIL_MUTEX_INITIALIZE(conn_list_lock); 58 59 59 60 static void tcp_conn_seg_process(tcp_conn_t *conn, tcp_segment_t *seg); … … 61 62 static void tcp_conn_tw_timer_clear(tcp_conn_t *conn); 62 63 63 /** Create new segmentstructure.64 /** Create new connection structure. 64 65 * 65 66 * @param lsock Local socket (will be deeply copied) 66 67 * @param fsock Foreign socket (will be deeply copied) 67 * @return New segmentor NULL68 * @return New connection or NULL 68 69 */ 69 70 tcp_conn_t *tcp_conn_new(tcp_sock_t *lsock, tcp_sock_t *fsock) … … 81 82 goto error; 82 83 84 fibril_mutex_initialize(&conn->lock); 85 86 /* One for the user, one for not being in closed state */ 87 atomic_set(&conn->refcnt, 2); 88 83 89 /* Allocate receive buffer */ 84 fibril_mutex_initialize(&conn->rcv_buf_lock);85 90 fibril_condvar_initialize(&conn->rcv_buf_cv); 86 91 conn->rcv_buf_size = RCV_BUF_SIZE; … … 93 98 94 99 /** Allocate send buffer */ 100 fibril_condvar_initialize(&conn->snd_buf_cv); 95 101 conn->snd_buf_size = SND_BUF_SIZE; 96 102 conn->snd_buf_used = 0; … … 113 119 114 120 /* Connection state change signalling */ 115 fibril_mutex_initialize(&conn->cstate_lock);116 121 fibril_condvar_initialize(&conn->cstate_cv); 117 122 118 123 conn->cstate = st_listen; 119 124 conn->reset = false; 125 conn->deleted = false; 120 126 conn->ap = ap_passive; 121 127 conn->fin_is_acked = false; … … 141 147 } 142 148 149 /** Destroy connection structure. 150 * 151 * Connection structure should be destroyed when the folowing condtitions 152 * are met: 153 * (1) user has deleted the connection 154 * (2) the connection has entered closed state 155 * (3) nobody is holding references to the connection 156 * 157 * This happens when @a conn->refcnt is zero as we count (1) and (2) 158 * as special references. 159 * 160 * @param conn Connection 161 */ 162 static void tcp_conn_free(tcp_conn_t *conn) 163 { 164 log_msg(LVL_DEBUG, "%s: tcp_conn_free(%p)", conn->name, conn); 165 tcp_tqueue_fini(&conn->retransmit); 166 167 if (conn->rcv_buf != NULL) 168 free(conn->rcv_buf); 169 if (conn->snd_buf != NULL) 170 free(conn->snd_buf); 171 if (conn->tw_timer != NULL) 172 fibril_timer_destroy(conn->tw_timer); 173 free(conn); 174 } 175 176 /** Add reference to connection. 177 * 178 * Increase connection reference count by one. 179 * 180 * @param conn Connection 181 */ 182 void tcp_conn_addref(tcp_conn_t *conn) 183 { 184 log_msg(LVL_DEBUG, "%s: tcp_conn_addref(%p)", conn->name, conn); 185 atomic_inc(&conn->refcnt); 186 } 187 188 /** Remove reference from connection. 189 * 190 * Decrease connection reference count by one. 191 * 192 * @param conn Connection 193 */ 194 void tcp_conn_delref(tcp_conn_t *conn) 195 { 196 log_msg(LVL_DEBUG, "%s: tcp_conn_delref(%p)", conn->name, conn); 197 198 if (atomic_predec(&conn->refcnt) == 0) 199 tcp_conn_free(conn); 200 } 201 202 /** Delete connection. 203 * 204 * The caller promises not make no further references to @a conn. 205 * TCP will free @a conn eventually. 206 * 207 * @param conn Connection 208 */ 209 void tcp_conn_delete(tcp_conn_t *conn) 210 { 211 log_msg(LVL_DEBUG, "%s: tcp_conn_delete(%p)", conn->name, conn); 212 213 assert(conn->deleted == false); 214 tcp_conn_delref(conn); 215 } 216 143 217 /** Enlist connection. 144 218 * … … 147 221 void tcp_conn_add(tcp_conn_t *conn) 148 222 { 223 tcp_conn_addref(conn); 224 fibril_mutex_lock(&conn_list_lock); 149 225 list_append(&conn->link, &conn_list); 226 fibril_mutex_unlock(&conn_list_lock); 150 227 } 151 228 … … 156 233 void tcp_conn_remove(tcp_conn_t *conn) 157 234 { 235 fibril_mutex_lock(&conn_list_lock); 158 236 list_remove(&conn->link); 237 fibril_mutex_unlock(&conn_list_lock); 238 tcp_conn_delref(conn); 159 239 } 160 240 161 241 static void tcp_conn_state_set(tcp_conn_t *conn, tcp_cstate_t nstate) 162 242 { 163 fibril_mutex_lock(&conn->cstate_lock); 243 tcp_cstate_t old_state; 244 245 old_state = conn->cstate; 164 246 conn->cstate = nstate; 165 247 fibril_condvar_broadcast(&conn->cstate_cv); 166 fibril_mutex_unlock(&conn->cstate_lock); 248 249 assert(old_state != st_closed); 250 if (nstate == st_closed) { 251 /* Drop one reference for now being in closed state */ 252 tcp_conn_delref(conn); 253 } 167 254 } 168 255 … … 251 338 * A connection is uniquely identified by a socket pair. Look up our 252 339 * connection map and return connection structure based on socket pair. 340 * The connection reference count is bumped by one. 253 341 * 254 342 * @param sp Socket pair 255 343 * @return Connection structure or NULL if not found. 256 344 */ 257 tcp_conn_t *tcp_conn_find (tcp_sockpair_t *sp)345 tcp_conn_t *tcp_conn_find_ref(tcp_sockpair_t *sp) 258 346 { 259 347 log_msg(LVL_DEBUG, "tcp_conn_find(%p)", sp); 348 349 fibril_mutex_lock(&conn_list_lock); 260 350 261 351 list_foreach(conn_list, link) { … … 266 356 csp->local.addr.ipv4, csp->local.port); 267 357 if (tcp_sockpair_match(sp, csp)) { 358 tcp_conn_addref(conn); 359 fibril_mutex_unlock(&conn_list_lock); 268 360 return conn; 269 361 } 270 362 } 271 363 364 fibril_mutex_unlock(&conn_list_lock); 272 365 return NULL; 273 366 } … … 287 380 288 381 fibril_condvar_broadcast(&conn->rcv_buf_cv); 382 fibril_condvar_broadcast(&conn->snd_buf_cv); 289 383 } 290 384 … … 858 952 tcp_conn_trim_seg_to_wnd(conn, seg); 859 953 860 fibril_mutex_lock(&conn->rcv_buf_lock);861 862 954 /* Determine how many bytes to copy */ 863 955 text_size = tcp_segment_text_size(seg); … … 871 963 /* Signal to the receive function that new data has arrived */ 872 964 fibril_condvar_broadcast(&conn->rcv_buf_cv); 873 fibril_mutex_unlock(&conn->rcv_buf_lock);874 965 875 966 log_msg(LVL_DEBUG, "Received %zu bytes of data.", xfer_size); … … 961 1052 962 1053 /* Add FIN to the receive buffer */ 963 fibril_mutex_lock(&conn->rcv_buf_lock);964 1054 conn->rcv_buf_fin = true; 965 1055 fibril_condvar_broadcast(&conn->rcv_buf_cv); 966 fibril_mutex_unlock(&conn->rcv_buf_lock);967 1056 968 1057 tcp_segment_delete(seg); … … 1073 1162 log_msg(LVL_DEBUG, "tw_timeout_func(%p)", conn); 1074 1163 1164 fibril_mutex_lock(&conn->lock); 1165 1075 1166 if (conn->cstate == st_closed) { 1076 1167 log_msg(LVL_DEBUG, "Connection already closed."); 1168 fibril_mutex_unlock(&conn->lock); 1169 tcp_conn_delref(conn); 1077 1170 return; 1078 1171 } … … 1081 1174 tcp_conn_remove(conn); 1082 1175 tcp_conn_state_set(conn, st_closed); 1176 1177 fibril_mutex_unlock(&conn->lock); 1178 tcp_conn_delref(conn); 1083 1179 } 1084 1180 … … 1089 1185 void tcp_conn_tw_timer_set(tcp_conn_t *conn) 1090 1186 { 1187 tcp_conn_addref(conn); 1091 1188 fibril_timer_set(conn->tw_timer, TIME_WAIT_TIMEOUT, tw_timeout_func, 1092 1189 (void *)conn); … … 1099 1196 void tcp_conn_tw_timer_clear(tcp_conn_t *conn) 1100 1197 { 1101 fibril_timer_clear(conn->tw_timer); 1198 if (fibril_timer_clear(conn->tw_timer) == fts_active) 1199 tcp_conn_delref(conn); 1102 1200 } 1103 1201
Note:
See TracChangeset
for help on using the changeset viewer.