Ignore:
File:
1 edited

Legend:

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

    r32d19f7 rb1bd89ea  
    5151#include "ucall.h"
    5252
     53#define FRAGMENT_SIZE 1024
     54
    5355/** Free ports pool start. */
    5456#define UDP_FREE_PORTS_START            1025
     
    6163
    6264static void udp_sock_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg);
    63 static int udp_sock_recv_fibril(void *arg);
    6465
    6566int udp_sock_init(void)
    6667{
     68        int rc;
     69
    6770        socket_ports_initialize(&gsock);
    68        
     71
    6972        async_set_client_connection(udp_sock_connection);
    70        
    71         int rc = service_register(SERVICE_UDP);
     73
     74        rc = service_register(SERVICE_UDP);
    7275        if (rc != EOK)
    7376                return EEXIST;
    74        
     77
    7578        return EOK;
    7679}
     
    8184
    8285        socket = (udp_sockdata_t *)sock_core->specific_data;
    83         (void)socket;
    84 
    85         /* XXX We need to force the receive fibril to quit */
     86        assert(socket->assoc != NULL);
     87        udp_uc_destroy(socket->assoc);
    8688}
    8789
     
    9193        async_exch_t *exch = async_exchange_begin(sock_core->sess);
    9294        async_msg_5(exch, NET_SOCKET_RECEIVED, (sysarg_t)sock_core->socket_id,
    93             UDP_FRAGMENT_SIZE, 0, 0, 1);
     95            FRAGMENT_SIZE, 0, 0, 1);
    9496        async_exchange_end(exch);
    9597}
     
    113115        sock->client = client;
    114116
    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 
    120117        rc = udp_uc_create(&sock->assoc);
    121118        if (rc != EOK) {
     119                udp_uc_destroy(sock->assoc);
    122120                free(sock);
    123121                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);
    132122                return;
    133123        }
     
    136126        rc = socket_create(&client->sockets, client->sess, sock, &sock_id);
    137127        if (rc != EOK) {
    138                 fibril_destroy(sock->recv_fibril);
    139                 udp_uc_destroy(sock->assoc);
    140                 free(sock);
    141128                async_answer_0(callid, rc);
    142129                return;
    143130        }
    144 
    145         fibril_add_ready(sock->recv_fibril);
    146131
    147132        sock_core = socket_cores_find(&client->sockets, sock_id);
     
    151136        SOCKET_SET_SOCKET_ID(answer, sock_id);
    152137
    153         SOCKET_SET_DATA_FRAGMENT_SIZE(answer, UDP_FRAGMENT_SIZE);
     138        SOCKET_SET_DATA_FRAGMENT_SIZE(answer, FRAGMENT_SIZE);
    154139        SOCKET_SET_HEADER_SIZE(answer, sizeof(udp_header_t));
    155140        async_answer_3(callid, EOK, IPC_GET_ARG1(answer),
     
    222207        }
    223208
     209        udp_sock_notify_data(sock_core);
     210
    224211        log_msg(LVL_DEBUG, " - success");
    225212        async_answer_0(callid, rc);
     
    260247        ipc_callid_t wcallid;
    261248        size_t length;
    262         uint8_t buffer[UDP_FRAGMENT_SIZE];
     249        uint8_t buffer[FRAGMENT_SIZE];
    263250        udp_error_t urc;
    264251        int rc;
     
    307294                        goto out;
    308295                }
     296
     297                udp_sock_notify_data(sock_core);
    309298        }
    310299
     
    343332                }
    344333
    345                 if (length > UDP_FRAGMENT_SIZE)
    346                         length = UDP_FRAGMENT_SIZE;
     334                if (length > FRAGMENT_SIZE)
     335                        length = FRAGMENT_SIZE;
    347336
    348337                rc = async_data_write_finalize(wcallid, buffer, length);
     
    380369       
    381370        IPC_SET_ARG1(answer, 0);
    382         SOCKET_SET_DATA_FRAGMENT_SIZE(answer, UDP_FRAGMENT_SIZE);
     371        SOCKET_SET_DATA_FRAGMENT_SIZE(answer, FRAGMENT_SIZE);
    383372        async_answer_2(callid, EOK, IPC_GET_ARG1(answer),
    384373            IPC_GET_ARG2(answer));
     
    399388        ipc_call_t answer;
    400389        ipc_callid_t rcallid;
     390        uint8_t buffer[FRAGMENT_SIZE];
    401391        size_t data_len;
     392        xflags_t xflags;
    402393        udp_error_t urc;
     394        struct sockaddr_in addr;
    403395        udp_sock_t rsock;
    404         struct sockaddr_in addr;
    405396        int rc;
    406397
     
    427418        (void)flags;
    428419
    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);
     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);
    444423
    445424        switch (urc) {
     
    460439        log_msg(LVL_DEBUG, "**** udp_uc_receive -> %d", rc);
    461440        if (rc != EOK) {
    462                 fibril_mutex_unlock(&socket->recv_buffer_lock);
    463441                fibril_mutex_unlock(&socket->lock);
    464442                async_answer_0(callid, rc);
     
    474452                log_msg(LVL_DEBUG, "addr read receive");
    475453                if (!async_data_read_receive(&rcallid, &addr_length)) {
    476                         fibril_mutex_unlock(&socket->recv_buffer_lock);
    477454                        fibril_mutex_unlock(&socket->lock);
    478455                        async_answer_0(callid, EINVAL);
     
    486463                rc = async_data_read_finalize(rcallid, &addr, addr_length);
    487464                if (rc != EOK) {
    488                         fibril_mutex_unlock(&socket->recv_buffer_lock);
    489465                        fibril_mutex_unlock(&socket->lock);
    490466                        async_answer_0(callid, EINVAL);
     
    495471        log_msg(LVL_DEBUG, "data read receive");
    496472        if (!async_data_read_receive(&rcallid, &length)) {
    497                 fibril_mutex_unlock(&socket->recv_buffer_lock);
    498473                fibril_mutex_unlock(&socket->lock);
    499474                async_answer_0(callid, EINVAL);
     
    505480
    506481        log_msg(LVL_DEBUG, "data read finalize");
    507         rc = async_data_read_finalize(rcallid, socket->recv_buffer, length);
     482        rc = async_data_read_finalize(rcallid, buffer, length);
    508483
    509484        if (length < data_len && rc == EOK)
     
    516491        async_answer_3(callid, EOK, IPC_GET_ARG1(answer),
    517492            IPC_GET_ARG2(answer), IPC_GET_ARG3(answer));
    518 
    519         socket->recv_buffer_used = 0;
    520 
    521         fibril_condvar_broadcast(&socket->recv_buffer_cv);
    522         fibril_mutex_unlock(&socket->recv_buffer_lock);
     493       
     494        /* Push one fragment notification to client's queue */
     495        udp_sock_notify_data(sock_core);
    523496        fibril_mutex_unlock(&socket->lock);
    524497}
     
    567540}
    568541
    569 static 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 
    611542static void udp_sock_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    612543{
Note: See TracChangeset for help on using the changeset viewer.