Changeset a438de4 in mainline for uspace/srv/net/tl/tcp/conn.c


Ignore:
Timestamp:
2011-12-19T18:50:17Z (12 years ago)
Author:
Jiri Svoboda <jiri@…>
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.
Message:

Merge TCP improvements.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/tl/tcp/conn.c

    r58f6229 ra438de4  
    5656
    5757LIST_INITIALIZE(conn_list);
     58FIBRIL_MUTEX_INITIALIZE(conn_list_lock);
    5859
    5960static void tcp_conn_seg_process(tcp_conn_t *conn, tcp_segment_t *seg);
     
    6162static void tcp_conn_tw_timer_clear(tcp_conn_t *conn);
    6263
    63 /** Create new segment structure.
     64/** Create new connection structure.
    6465 *
    6566 * @param lsock         Local socket (will be deeply copied)
    6667 * @param fsock         Foreign socket (will be deeply copied)
    67  * @return              New segment or NULL
     68 * @return              New connection or NULL
    6869 */
    6970tcp_conn_t *tcp_conn_new(tcp_sock_t *lsock, tcp_sock_t *fsock)
     
    8182                goto error;
    8283
     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
    8389        /* Allocate receive buffer */
    84         fibril_mutex_initialize(&conn->rcv_buf_lock);
    8590        fibril_condvar_initialize(&conn->rcv_buf_cv);
    8691        conn->rcv_buf_size = RCV_BUF_SIZE;
     
    9398
    9499        /** Allocate send buffer */
     100        fibril_condvar_initialize(&conn->snd_buf_cv);
    95101        conn->snd_buf_size = SND_BUF_SIZE;
    96102        conn->snd_buf_used = 0;
     
    113119
    114120        /* Connection state change signalling */
    115         fibril_mutex_initialize(&conn->cstate_lock);
    116121        fibril_condvar_initialize(&conn->cstate_cv);
    117122
    118123        conn->cstate = st_listen;
    119124        conn->reset = false;
     125        conn->deleted = false;
    120126        conn->ap = ap_passive;
    121127        conn->fin_is_acked = false;
     
    141147}
    142148
     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 */
     162static 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 */
     182void 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 */
     194void 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 */
     209void 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
    143217/** Enlist connection.
    144218 *
     
    147221void tcp_conn_add(tcp_conn_t *conn)
    148222{
     223        tcp_conn_addref(conn);
     224        fibril_mutex_lock(&conn_list_lock);
    149225        list_append(&conn->link, &conn_list);
     226        fibril_mutex_unlock(&conn_list_lock);
    150227}
    151228
     
    156233void tcp_conn_remove(tcp_conn_t *conn)
    157234{
     235        fibril_mutex_lock(&conn_list_lock);
    158236        list_remove(&conn->link);
     237        fibril_mutex_unlock(&conn_list_lock);
     238        tcp_conn_delref(conn);
    159239}
    160240
    161241static void tcp_conn_state_set(tcp_conn_t *conn, tcp_cstate_t nstate)
    162242{
    163         fibril_mutex_lock(&conn->cstate_lock);
     243        tcp_cstate_t old_state;
     244
     245        old_state = conn->cstate;
    164246        conn->cstate = nstate;
    165247        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        }
    167254}
    168255
     
    251338 * A connection is uniquely identified by a socket pair. Look up our
    252339 * connection map and return connection structure based on socket pair.
     340 * The connection reference count is bumped by one.
    253341 *
    254342 * @param sp    Socket pair
    255343 * @return      Connection structure or NULL if not found.
    256344 */
    257 tcp_conn_t *tcp_conn_find(tcp_sockpair_t *sp)
     345tcp_conn_t *tcp_conn_find_ref(tcp_sockpair_t *sp)
    258346{
    259347        log_msg(LVL_DEBUG, "tcp_conn_find(%p)", sp);
     348
     349        fibril_mutex_lock(&conn_list_lock);
    260350
    261351        list_foreach(conn_list, link) {
     
    266356                    csp->local.addr.ipv4, csp->local.port);
    267357                if (tcp_sockpair_match(sp, csp)) {
     358                        tcp_conn_addref(conn);
     359                        fibril_mutex_unlock(&conn_list_lock);
    268360                        return conn;
    269361                }
    270362        }
    271363
     364        fibril_mutex_unlock(&conn_list_lock);
    272365        return NULL;
    273366}
     
    287380
    288381        fibril_condvar_broadcast(&conn->rcv_buf_cv);
     382        fibril_condvar_broadcast(&conn->snd_buf_cv);
    289383}
    290384
     
    858952        tcp_conn_trim_seg_to_wnd(conn, seg);
    859953
    860         fibril_mutex_lock(&conn->rcv_buf_lock);
    861 
    862954        /* Determine how many bytes to copy */
    863955        text_size = tcp_segment_text_size(seg);
     
    871963        /* Signal to the receive function that new data has arrived */
    872964        fibril_condvar_broadcast(&conn->rcv_buf_cv);
    873         fibril_mutex_unlock(&conn->rcv_buf_lock);
    874965
    875966        log_msg(LVL_DEBUG, "Received %zu bytes of data.", xfer_size);
     
    9611052
    9621053                /* Add FIN to the receive buffer */
    963                 fibril_mutex_lock(&conn->rcv_buf_lock);
    9641054                conn->rcv_buf_fin = true;
    9651055                fibril_condvar_broadcast(&conn->rcv_buf_cv);
    966                 fibril_mutex_unlock(&conn->rcv_buf_lock);
    9671056
    9681057                tcp_segment_delete(seg);
     
    10731162        log_msg(LVL_DEBUG, "tw_timeout_func(%p)", conn);
    10741163
     1164        fibril_mutex_lock(&conn->lock);
     1165
    10751166        if (conn->cstate == st_closed) {
    10761167                log_msg(LVL_DEBUG, "Connection already closed.");
     1168                fibril_mutex_unlock(&conn->lock);
     1169                tcp_conn_delref(conn);
    10771170                return;
    10781171        }
     
    10811174        tcp_conn_remove(conn);
    10821175        tcp_conn_state_set(conn, st_closed);
     1176
     1177        fibril_mutex_unlock(&conn->lock);
     1178        tcp_conn_delref(conn);
    10831179}
    10841180
     
    10891185void tcp_conn_tw_timer_set(tcp_conn_t *conn)
    10901186{
     1187        tcp_conn_addref(conn);
    10911188        fibril_timer_set(conn->tw_timer, TIME_WAIT_TIMEOUT, tw_timeout_func,
    10921189            (void *)conn);
     
    10991196void tcp_conn_tw_timer_clear(tcp_conn_t *conn)
    11001197{
    1101         fibril_timer_clear(conn->tw_timer);
     1198        if (fibril_timer_clear(conn->tw_timer) == fts_active)
     1199                tcp_conn_delref(conn);
    11021200}
    11031201
Note: See TracChangeset for help on using the changeset viewer.