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


Ignore:
Timestamp:
2011-12-16T18:04:30Z (12 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ab9378b4
Parents:
7a8c1c4e
Message:

Revamp connection synchronization.

File:
1 edited

Legend:

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

    r7a8c1c4e r0edaf0f6  
    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);
     
    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 */
    95         fibril_mutex_initialize(&conn->snd_buf_lock);
    96100        fibril_condvar_initialize(&conn->snd_buf_cv);
    97101        conn->snd_buf_size = SND_BUF_SIZE;
     
    115119
    116120        /* Connection state change signalling */
    117         fibril_mutex_initialize(&conn->cstate_lock);
    118121        fibril_condvar_initialize(&conn->cstate_cv);
    119122
     
    146149/** Destroy connection structure.
    147150 *
    148  * Connection structure should be destroyed when both of two conditions are
    149  * met: (1) user has deleted the connection and (2) the connection has entered
    150  * closed state.
     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.
    151159 *
    152160 * @param conn          Connection
     
    166174}
    167175
     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
    168202/** Delete connection.
    169203 *
     
    175209void tcp_conn_delete(tcp_conn_t *conn)
    176210{
    177         fibril_mutex_lock(&conn->cstate_lock);
    178         conn->deleted = true;
    179 
    180         if (conn->cstate == st_closed) {
    181                 fibril_mutex_unlock(&conn->cstate_lock);
    182                 tcp_conn_free(conn);
    183         } else {
    184                 fibril_mutex_unlock(&conn->cstate_lock);
    185         }
     211        log_msg(LVL_DEBUG, "%s: tcp_conn_delete(%p)", conn->name, conn);
     212
     213        assert(conn->deleted == false);
     214        tcp_conn_delref(conn);
    186215}
    187216
     
    192221void tcp_conn_add(tcp_conn_t *conn)
    193222{
     223        fibril_mutex_lock(&conn_list_lock);
    194224        list_append(&conn->link, &conn_list);
     225        fibril_mutex_unlock(&conn_list_lock);
    195226}
    196227
     
    201232void tcp_conn_remove(tcp_conn_t *conn)
    202233{
     234        fibril_mutex_lock(&conn_list_lock);
    203235        list_remove(&conn->link);
     236        fibril_mutex_unlock(&conn_list_lock);
    204237}
    205238
    206239static void tcp_conn_state_set(tcp_conn_t *conn, tcp_cstate_t nstate)
    207240{
    208         fibril_mutex_lock(&conn->cstate_lock);
     241        tcp_cstate_t old_state;
     242
     243        old_state = conn->cstate;
    209244        conn->cstate = nstate;
    210245        fibril_condvar_broadcast(&conn->cstate_cv);
    211246
    212         if (nstate == st_closed && conn->deleted) {
    213                 fibril_mutex_unlock(&conn->cstate_lock);
    214                 tcp_conn_free(conn);
    215         } else {
    216                 fibril_mutex_unlock(&conn->cstate_lock);
     247        assert(old_state != st_closed);
     248        if (nstate == st_closed) {
     249                /* Drop one reference for now being in closed state */
     250                tcp_conn_delref(conn);
    217251        }
    218252}
     
    302336 * A connection is uniquely identified by a socket pair. Look up our
    303337 * connection map and return connection structure based on socket pair.
     338 * The connection reference count is bumped by one.
    304339 *
    305340 * @param sp    Socket pair
    306341 * @return      Connection structure or NULL if not found.
    307342 */
    308 tcp_conn_t *tcp_conn_find(tcp_sockpair_t *sp)
     343tcp_conn_t *tcp_conn_find_ref(tcp_sockpair_t *sp)
    309344{
    310345        log_msg(LVL_DEBUG, "tcp_conn_find(%p)", sp);
     346
     347        fibril_mutex_lock(&conn_list_lock);
    311348
    312349        list_foreach(conn_list, link) {
     
    317354                    csp->local.addr.ipv4, csp->local.port);
    318355                if (tcp_sockpair_match(sp, csp)) {
     356                        tcp_conn_addref(conn);
     357                        fibril_mutex_unlock(&conn_list_lock);
    319358                        return conn;
    320359                }
    321360        }
    322361
     362        fibril_mutex_unlock(&conn_list_lock);
    323363        return NULL;
    324364}
     
    910950        tcp_conn_trim_seg_to_wnd(conn, seg);
    911951
    912         fibril_mutex_lock(&conn->rcv_buf_lock);
    913 
    914952        /* Determine how many bytes to copy */
    915953        text_size = tcp_segment_text_size(seg);
     
    923961        /* Signal to the receive function that new data has arrived */
    924962        fibril_condvar_broadcast(&conn->rcv_buf_cv);
    925         fibril_mutex_unlock(&conn->rcv_buf_lock);
    926963
    927964        log_msg(LVL_DEBUG, "Received %zu bytes of data.", xfer_size);
     
    10131050
    10141051                /* Add FIN to the receive buffer */
    1015                 fibril_mutex_lock(&conn->rcv_buf_lock);
    10161052                conn->rcv_buf_fin = true;
    10171053                fibril_condvar_broadcast(&conn->rcv_buf_cv);
    1018                 fibril_mutex_unlock(&conn->rcv_buf_lock);
    10191054
    10201055                tcp_segment_delete(seg);
     
    11251160        log_msg(LVL_DEBUG, "tw_timeout_func(%p)", conn);
    11261161
     1162        fibril_mutex_lock(&conn->lock);
     1163
    11271164        if (conn->cstate == st_closed) {
    11281165                log_msg(LVL_DEBUG, "Connection already closed.");
     1166                fibril_mutex_unlock(&conn->lock);
     1167                tcp_conn_delref(conn);
    11291168                return;
    11301169        }
     
    11331172        tcp_conn_remove(conn);
    11341173        tcp_conn_state_set(conn, st_closed);
     1174
     1175        fibril_mutex_unlock(&conn->lock);
     1176        tcp_conn_delref(conn);
    11351177}
    11361178
     
    11411183void tcp_conn_tw_timer_set(tcp_conn_t *conn)
    11421184{
     1185        tcp_conn_addref(conn);
    11431186        fibril_timer_set(conn->tw_timer, TIME_WAIT_TIMEOUT, tw_timeout_func,
    11441187            (void *)conn);
     
    11511194void tcp_conn_tw_timer_clear(tcp_conn_t *conn)
    11521195{
    1153         fibril_timer_clear(conn->tw_timer);
     1196        if (fibril_timer_clear(conn->tw_timer) == fts_active)
     1197                tcp_conn_delref(conn);
    11541198}
    11551199
Note: See TracChangeset for help on using the changeset viewer.