Changeset 8013637 in mainline for uspace/srv/net/udp/sock.c


Ignore:
Timestamp:
2012-07-20T13:51:28Z (12 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
8fccd42
Parents:
c5bff3c (diff), 7030bc9 (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:

More mainline changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/udp/sock.c

    rc5bff3c r8013637  
    5151#include "ucall.h"
    5252
    53 #define FRAGMENT_SIZE 1024
    54 
    5553/** Free ports pool start. */
    5654#define UDP_FREE_PORTS_START            1025
     
    6361
    6462static void udp_sock_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg);
     63static int udp_sock_recv_fibril(void *arg);
    6564
    6665int udp_sock_init(void)
    6766{
    68         int rc;
    69 
    7067        socket_ports_initialize(&gsock);
    71 
     68       
    7269        async_set_client_connection(udp_sock_connection);
    73 
    74         rc = service_register(SERVICE_UDP);
     70       
     71        int rc = service_register(SERVICE_UDP);
    7572        if (rc != EOK)
    7673                return EEXIST;
    77 
     74       
    7875        return EOK;
    7976}
     
    8481
    8582        socket = (udp_sockdata_t *)sock_core->specific_data;
    86         assert(socket->assoc != NULL);
    87         udp_uc_destroy(socket->assoc);
     83        (void)socket;
     84
     85        /* XXX We need to force the receive fibril to quit */
    8886}
    8987
     
    9391        async_exch_t *exch = async_exchange_begin(sock_core->sess);
    9492        async_msg_5(exch, NET_SOCKET_RECEIVED, (sysarg_t)sock_core->socket_id,
    95             FRAGMENT_SIZE, 0, 0, 1);
     93            UDP_FRAGMENT_SIZE, 0, 0, 1);
    9694        async_exchange_end(exch);
    9795}
     
    115113        sock->client = client;
    116114
     115        sock->recv_buffer_used = 0;
     116        sock->recv_error = UDP_EOK;
     117        fibril_mutex_initialize(&sock->recv_buffer_lock);
     118        fibril_condvar_initialize(&sock->recv_buffer_cv);
     119
    117120        rc = udp_uc_create(&sock->assoc);
    118121        if (rc != EOK) {
     122                free(sock);
     123                async_answer_0(callid, rc);
     124                return;
     125        }
     126
     127        sock->recv_fibril = fibril_create(udp_sock_recv_fibril, sock);
     128        if (sock->recv_fibril == 0) {
     129                udp_uc_destroy(sock->assoc);
     130                free(sock);
     131                async_answer_0(callid, ENOMEM);
     132                return;
     133        }
     134
     135        sock_id = SOCKET_GET_SOCKET_ID(call);
     136        rc = socket_create(&client->sockets, client->sess, sock, &sock_id);
     137        if (rc != EOK) {
     138                fibril_destroy(sock->recv_fibril);
    119139                udp_uc_destroy(sock->assoc);
    120140                free(sock);
     
    123143        }
    124144
    125         sock_id = SOCKET_GET_SOCKET_ID(call);
    126         rc = socket_create(&client->sockets, client->sess, sock, &sock_id);
    127         if (rc != EOK) {
    128                 async_answer_0(callid, rc);
    129                 return;
    130         }
     145        fibril_add_ready(sock->recv_fibril);
    131146
    132147        sock_core = socket_cores_find(&client->sockets, sock_id);
     
    136151        SOCKET_SET_SOCKET_ID(answer, sock_id);
    137152
    138         SOCKET_SET_DATA_FRAGMENT_SIZE(answer, FRAGMENT_SIZE);
     153        SOCKET_SET_DATA_FRAGMENT_SIZE(answer, UDP_FRAGMENT_SIZE);
    139154        SOCKET_SET_HEADER_SIZE(answer, sizeof(udp_header_t));
    140155        async_answer_3(callid, EOK, IPC_GET_ARG1(answer),
     
    207222        }
    208223
    209         udp_sock_notify_data(sock_core);
    210 
    211224        log_msg(LVL_DEBUG, " - success");
    212225        async_answer_0(callid, rc);
     
    247260        ipc_callid_t wcallid;
    248261        size_t length;
    249         uint8_t buffer[FRAGMENT_SIZE];
     262        uint8_t buffer[UDP_FRAGMENT_SIZE];
    250263        udp_error_t urc;
    251264        int rc;
     
    294307                        goto out;
    295308                }
    296 
    297                 udp_sock_notify_data(sock_core);
    298309        }
    299310
     
    332343                }
    333344
    334                 if (length > FRAGMENT_SIZE)
    335                         length = FRAGMENT_SIZE;
     345                if (length > UDP_FRAGMENT_SIZE)
     346                        length = UDP_FRAGMENT_SIZE;
    336347
    337348                rc = async_data_write_finalize(wcallid, buffer, length);
     
    369380       
    370381        IPC_SET_ARG1(answer, 0);
    371         SOCKET_SET_DATA_FRAGMENT_SIZE(answer, FRAGMENT_SIZE);
     382        SOCKET_SET_DATA_FRAGMENT_SIZE(answer, UDP_FRAGMENT_SIZE);
    372383        async_answer_2(callid, EOK, IPC_GET_ARG1(answer),
    373384            IPC_GET_ARG2(answer));
     
    388399        ipc_call_t answer;
    389400        ipc_callid_t rcallid;
    390         uint8_t buffer[FRAGMENT_SIZE];
    391401        size_t data_len;
    392         xflags_t xflags;
    393402        udp_error_t urc;
     403        udp_sock_t rsock;
    394404        struct sockaddr_in addr;
    395         udp_sock_t rsock;
    396405        int rc;
    397406
     
    418427        (void)flags;
    419428
    420         urc = udp_uc_receive(socket->assoc, buffer, FRAGMENT_SIZE, &data_len,
    421             &xflags, &rsock);
    422         log_msg(LVL_DEBUG, "**** udp_uc_receive done, data_len=%zu", data_len);
     429        log_msg(LVL_DEBUG, "udp_sock_recvfrom(): lock recv_buffer lock");
     430        fibril_mutex_lock(&socket->recv_buffer_lock);
     431        while (socket->recv_buffer_used == 0 && socket->recv_error == UDP_EOK) {
     432                log_msg(LVL_DEBUG, "udp_sock_recvfrom(): wait for cv");
     433                fibril_condvar_wait(&socket->recv_buffer_cv,
     434                    &socket->recv_buffer_lock);
     435        }
     436
     437        log_msg(LVL_DEBUG, "Got data in sock recv_buffer");
     438
     439        rsock = socket->recv_fsock;
     440        data_len = socket->recv_buffer_used;
     441        urc = socket->recv_error;
     442
     443        log_msg(LVL_DEBUG, "**** recv data_len=%zu", data_len);
    423444
    424445        switch (urc) {
     
    439460        log_msg(LVL_DEBUG, "**** udp_uc_receive -> %d", rc);
    440461        if (rc != EOK) {
     462                fibril_mutex_unlock(&socket->recv_buffer_lock);
    441463                fibril_mutex_unlock(&socket->lock);
    442464                async_answer_0(callid, rc);
     
    452474                log_msg(LVL_DEBUG, "addr read receive");
    453475                if (!async_data_read_receive(&rcallid, &addr_length)) {
     476                        fibril_mutex_unlock(&socket->recv_buffer_lock);
    454477                        fibril_mutex_unlock(&socket->lock);
    455478                        async_answer_0(callid, EINVAL);
     
    463486                rc = async_data_read_finalize(rcallid, &addr, addr_length);
    464487                if (rc != EOK) {
     488                        fibril_mutex_unlock(&socket->recv_buffer_lock);
    465489                        fibril_mutex_unlock(&socket->lock);
    466490                        async_answer_0(callid, EINVAL);
     
    471495        log_msg(LVL_DEBUG, "data read receive");
    472496        if (!async_data_read_receive(&rcallid, &length)) {
     497                fibril_mutex_unlock(&socket->recv_buffer_lock);
    473498                fibril_mutex_unlock(&socket->lock);
    474499                async_answer_0(callid, EINVAL);
     
    480505
    481506        log_msg(LVL_DEBUG, "data read finalize");
    482         rc = async_data_read_finalize(rcallid, buffer, length);
     507        rc = async_data_read_finalize(rcallid, socket->recv_buffer, length);
    483508
    484509        if (length < data_len && rc == EOK)
     
    491516        async_answer_3(callid, EOK, IPC_GET_ARG1(answer),
    492517            IPC_GET_ARG2(answer), IPC_GET_ARG3(answer));
    493        
    494         /* Push one fragment notification to client's queue */
    495         udp_sock_notify_data(sock_core);
     518
     519        socket->recv_buffer_used = 0;
     520
     521        fibril_condvar_broadcast(&socket->recv_buffer_cv);
     522        fibril_mutex_unlock(&socket->recv_buffer_lock);
    496523        fibril_mutex_unlock(&socket->lock);
    497524}
     
    540567}
    541568
     569static int udp_sock_recv_fibril(void *arg)
     570{
     571        udp_sockdata_t *sock = (udp_sockdata_t *)arg;
     572        udp_error_t urc;
     573        xflags_t xflags;
     574        size_t rcvd;
     575
     576        log_msg(LVL_DEBUG, "udp_sock_recv_fibril()");
     577
     578        while (true) {
     579                log_msg(LVL_DEBUG, "[] wait for rcv buffer empty()");
     580                fibril_mutex_lock(&sock->recv_buffer_lock);
     581                while (sock->recv_buffer_used != 0) {
     582                        fibril_condvar_wait(&sock->recv_buffer_cv,
     583                            &sock->recv_buffer_lock);
     584                }
     585
     586                log_msg(LVL_DEBUG, "[] call udp_uc_receive()");
     587                urc = udp_uc_receive(sock->assoc, sock->recv_buffer,
     588                    UDP_FRAGMENT_SIZE, &rcvd, &xflags, &sock->recv_fsock);
     589                sock->recv_error = urc;
     590
     591                udp_sock_notify_data(sock->sock_core);
     592
     593                if (urc != UDP_EOK) {
     594                        fibril_condvar_broadcast(&sock->recv_buffer_cv);
     595                        fibril_mutex_unlock(&sock->recv_buffer_lock);
     596                        break;
     597                }
     598
     599                log_msg(LVL_DEBUG, "[] got data - broadcast recv_buffer_cv");
     600
     601                sock->recv_buffer_used = rcvd;
     602                fibril_mutex_unlock(&sock->recv_buffer_lock);
     603                fibril_condvar_broadcast(&sock->recv_buffer_cv);
     604        }
     605
     606        udp_uc_destroy(sock->assoc);
     607
     608        return 0;
     609}
     610
    542611static void udp_sock_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    543612{
Note: See TracChangeset for help on using the changeset viewer.