Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 1d4b815 in mainline


Ignore:
Timestamp:
2015-05-09T19:05:48Z (7 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master
Children:
309469de
Parents:
779541b
Message:

Properly wait for connection establishment.

Location:
uspace
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/inet/tcp.c

    r779541b r1d4b815  
    274274int tcp_conn_wait_connected(tcp_conn_t *conn)
    275275{
    276         async_usleep(1000 * 1000);
    277         return 0;
     276        fibril_mutex_lock(&conn->lock);
     277        while (!conn->connected && !conn->conn_failed && !conn->conn_reset)
     278                fibril_condvar_wait(&conn->cv, &conn->lock);
     279
     280        if (conn->connected) {
     281                fibril_mutex_unlock(&conn->lock);
     282                return EOK;
     283        } else {
     284                assert(conn->conn_failed || conn->conn_reset);
     285                fibril_mutex_unlock(&conn->lock);
     286                return EIO;
     287        }
    278288}
    279289
     
    442452static void tcp_ev_connected(tcp_t *tcp, ipc_callid_t iid, ipc_call_t *icall)
    443453{
     454        tcp_conn_t *conn;
     455        sysarg_t conn_id;
     456        int rc;
     457
    444458        printf("tcp_ev_connected()\n");
    445         async_answer_0(iid, ENOTSUP);
     459        conn_id = IPC_GET_ARG1(*icall);
     460
     461        rc = tcp_conn_get(tcp, conn_id, &conn);
     462        if (rc != EOK) {
     463                printf("conn ID %zu not found\n",
     464                    conn_id);
     465                async_answer_0(iid, ENOENT);
     466                return;
     467        }
     468
     469        fibril_mutex_lock(&conn->lock);
     470        conn->connected = true;
     471        fibril_condvar_broadcast(&conn->cv);
     472        fibril_mutex_unlock(&conn->lock);
     473
     474        async_answer_0(iid, EOK);
    446475}
    447476
    448477static void tcp_ev_conn_failed(tcp_t *tcp, ipc_callid_t iid, ipc_call_t *icall)
    449478{
     479        tcp_conn_t *conn;
     480        sysarg_t conn_id;
     481        int rc;
     482
    450483        printf("tcp_ev_conn_failed()\n");
    451         async_answer_0(iid, ENOTSUP);
     484        conn_id = IPC_GET_ARG1(*icall);
     485
     486        rc = tcp_conn_get(tcp, conn_id, &conn);
     487        if (rc != EOK) {
     488                printf("conn ID %zu not found\n",
     489                    conn_id);
     490                async_answer_0(iid, ENOENT);
     491                return;
     492        }
     493
     494        fibril_mutex_lock(&conn->lock);
     495        conn->conn_failed = true;
     496        fibril_condvar_broadcast(&conn->cv);
     497        fibril_mutex_unlock(&conn->lock);
     498
     499        async_answer_0(iid, EOK);
    452500}
    453501
    454502static void tcp_ev_conn_reset(tcp_t *tcp, ipc_callid_t iid, ipc_call_t *icall)
    455503{
     504        tcp_conn_t *conn;
     505        sysarg_t conn_id;
     506        int rc;
     507
    456508        printf("tcp_ev_conn_reset()\n");
    457         async_answer_0(iid, ENOTSUP);
     509        conn_id = IPC_GET_ARG1(*icall);
     510
     511        rc = tcp_conn_get(tcp, conn_id, &conn);
     512        if (rc != EOK) {
     513                printf("conn ID %zu not found\n",
     514                    conn_id);
     515                async_answer_0(iid, ENOENT);
     516                return;
     517        }
     518
     519        fibril_mutex_lock(&conn->lock);
     520        conn->conn_reset = true;
     521        fibril_condvar_broadcast(&conn->cv);
     522        fibril_mutex_unlock(&conn->lock);
     523
     524        async_answer_0(iid, EOK);
    458525}
    459526
  • uspace/lib/c/include/inet/tcp.h

    r779541b r1d4b815  
    5252        /** Some received data available in TCP server */
    5353        bool data_avail;
     54        bool connected;
     55        bool conn_failed;
     56        bool conn_reset;
    5457} tcp_conn_t;
    5558
  • uspace/srv/net/tcp/conn.c

    r779541b r1d4b815  
    277277        if (conn->cb != NULL && conn->cb->cstate_change != NULL) {
    278278                log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_state_set() - run user CB");
    279                 conn->cb->cstate_change(conn, conn->cb_arg);
     279                conn->cb->cstate_change(conn, conn->cb_arg, old_state);
    280280        } else {
    281281                log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_state_set() - no user CB");
  • uspace/srv/net/tcp/service.c

    r779541b r1d4b815  
    5656
    5757static void tcp_ev_data(tcp_cconn_t *);
    58 
    59 static void tcp_service_cstate_change(tcp_conn_t *, void *);
     58static void tcp_ev_connected(tcp_cconn_t *);
     59static void tcp_ev_conn_failed(tcp_cconn_t *);
     60static void tcp_ev_conn_reset(tcp_cconn_t *);
     61
     62static void tcp_service_cstate_change(tcp_conn_t *, void *, tcp_cstate_t);
    6063static void tcp_service_recv_data(tcp_conn_t *, void *);
    6164
     
    6568};
    6669
    67 static void tcp_service_cstate_change(tcp_conn_t *conn, void *arg)
    68 {
     70static void tcp_service_cstate_change(tcp_conn_t *conn, void *arg,
     71    tcp_cstate_t old_state)
     72{
     73        tcp_cstate_t nstate;
     74        tcp_cconn_t *cconn;
     75
     76        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_service_cstate_change()");
     77        nstate = conn->cstate;
     78        cconn = tcp_uc_get_userptr(conn);
     79
     80        if ((old_state == st_syn_sent || old_state == st_syn_received) &&
     81            (nstate == st_established)) {
     82                /* Connection established */
     83                tcp_ev_connected(cconn);
     84        }
     85
     86        if (old_state != st_closed && nstate == st_closed && conn->reset) {
     87                /* Connection reset */
     88                tcp_ev_conn_reset(cconn);
     89        }
     90
     91        /* XXX Failed to establish connection */
     92        if (0) tcp_ev_conn_failed(cconn);
    6993}
    7094
     
    87111        exch = async_exchange_begin(cconn->client->sess);
    88112        aid_t req = async_send_1(exch, TCP_EV_DATA, cconn->id, NULL);
     113        async_exchange_end(exch);
     114
     115        async_forget(req);
     116}
     117
     118static void tcp_ev_connected(tcp_cconn_t *cconn)
     119{
     120        async_exch_t *exch;
     121
     122        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_ev_connected()");
     123
     124        exch = async_exchange_begin(cconn->client->sess);
     125        aid_t req = async_send_1(exch, TCP_EV_CONNECTED, cconn->id, NULL);
     126        async_exchange_end(exch);
     127
     128        async_forget(req);
     129}
     130
     131static void tcp_ev_conn_failed(tcp_cconn_t *cconn)
     132{
     133        async_exch_t *exch;
     134
     135        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_ev_conn_failed()");
     136
     137        exch = async_exchange_begin(cconn->client->sess);
     138        aid_t req = async_send_1(exch, TCP_EV_CONN_FAILED, cconn->id, NULL);
     139        async_exchange_end(exch);
     140
     141        async_forget(req);
     142}
     143
     144static void tcp_ev_conn_reset(tcp_cconn_t *cconn)
     145{
     146        async_exch_t *exch;
     147
     148        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_ev_conn_reset()");
     149
     150        exch = async_exchange_begin(cconn->client->sess);
     151        aid_t req = async_send_1(exch, TCP_EV_CONN_RESET, cconn->id, NULL);
    89152        async_exchange_end(exch);
    90153
  • uspace/srv/net/tcp/tcp_type.h

    r779541b r1d4b815  
    157157/** Connection callbacks */
    158158typedef struct {
    159         void (*cstate_change)(tcp_conn_t *, void *);
     159        void (*cstate_change)(tcp_conn_t *, void *, tcp_cstate_t);
    160160        void (*recv_data)(tcp_conn_t *, void *);
    161161} tcp_cb_t;
  • uspace/srv/net/tcp/ucall.c

    r779541b r1d4b815  
    305305}
    306306
     307void *tcp_uc_get_userptr(tcp_conn_t *conn)
     308{
     309        return conn->cb_arg;
     310}
     311
    307312/*
    308313 * Arriving segments
  • uspace/srv/net/tcp/ucall.h

    r779541b r1d4b815  
    5151extern void tcp_uc_delete(tcp_conn_t *);
    5252extern void tcp_uc_set_cb(tcp_conn_t *, tcp_cb_t *, void *);
     53extern void *tcp_uc_get_userptr(tcp_conn_t *);
    5354
    5455/*
Note: See TracChangeset for help on using the changeset viewer.