Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/net/socket_client.c

    r64d2b10 r6b82009  
    6464#define SOCKET_MAX_ACCEPTED_SIZE        0
    6565
    66 /** Default timeout for connections in microseconds. */
    67 #define SOCKET_CONNECT_TIMEOUT  (1 * 1000 * 1000)
    68 
    6966/**
    7067 * Maximum number of random attempts to find a new socket identifier before
     
    8683        /** Socket identifier. */
    8784        int socket_id;
    88         /** Parent module phone. */
    89         int phone;
     85        /** Parent module session. */
     86        async_sess_t *sess;
    9087        /** Parent module service. */
    9188        services_t service;
     
    146143/** Socket client library global data. */
    147144static struct socket_client_globals {
    148         /** TCP module phone. */
    149         int tcp_phone;
    150         /** UDP module phone. */
    151         int udp_phone;
    152 
    153 //      /** The last socket identifier.
    154 //       */
    155 //      int last_id;
     145        /** TCP module session. */
     146        async_sess_t *tcp_sess;
     147        /** UDP module session. */
     148        async_sess_t *udp_sess;
    156149
    157150        /** Active sockets. */
     
    166159        fibril_rwlock_t lock;
    167160} socket_globals = {
    168         .tcp_phone = -1,
    169         .udp_phone = -1,
    170 //      .last_id = 0,
     161        .tcp_sess = NULL,
     162        .udp_sess = NULL,
    171163        .sockets = NULL,
    172164        .lock = FIBRIL_RWLOCK_INITIALIZER(socket_globals.lock)
     
    202194 * @param[in] iid       The initial message identifier.
    203195 * @param[in] icall     The initial message call structure.
    204  */
    205 static void socket_connection(ipc_callid_t iid, ipc_call_t * icall)
     196 * @param[in] arg       Local argument.
     197 */
     198static void socket_connection(ipc_callid_t iid, ipc_call_t * icall, void *arg)
    206199{
    207200        ipc_callid_t callid;
     
    281274}
    282275
    283 /** Returns the TCP module phone.
    284  *
    285  * Connects to the TCP module if necessary.
    286  *
    287  * @return              The TCP module phone.
    288  * @return              Other error codes as defined for the
    289  *                      bind_service_timeout() function.
    290  */
    291 static int socket_get_tcp_phone(void)
    292 {
    293         if (socket_globals.tcp_phone < 0) {
    294                 socket_globals.tcp_phone = bind_service_timeout(SERVICE_TCP,
    295                     0, 0, SERVICE_TCP, socket_connection,
    296                     SOCKET_CONNECT_TIMEOUT);
    297         }
    298 
    299         return socket_globals.tcp_phone;
    300 }
    301 
    302 /** Returns the UDP module phone.
    303  *
    304  * Connects to the UDP module if necessary.
    305  *
    306  * @return              The UDP module phone.
    307  * @return              Other error codes as defined for the
    308  *                      bind_service_timeout() function.
    309  */
    310 static int socket_get_udp_phone(void)
    311 {
    312         if (socket_globals.udp_phone < 0) {
    313                 socket_globals.udp_phone = bind_service_timeout(SERVICE_UDP,
    314                     0, 0, SERVICE_UDP, socket_connection,
    315                     SOCKET_CONNECT_TIMEOUT);
    316         }
    317 
    318         return socket_globals.udp_phone;
     276/** Return the TCP module session.
     277 *
     278 * Connect to the TCP module if necessary.
     279 *
     280 * @return The TCP module session.
     281 *
     282 */
     283static async_sess_t *socket_get_tcp_sess(void)
     284{
     285        if (socket_globals.tcp_sess == NULL) {
     286                socket_globals.tcp_sess = bind_service(SERVICE_TCP,
     287                    0, 0, SERVICE_TCP, socket_connection);
     288        }
     289
     290        return socket_globals.tcp_sess;
     291}
     292
     293/** Return the UDP module session.
     294 *
     295 * Connect to the UDP module if necessary.
     296 *
     297 * @return The UDP module session.
     298 *
     299 */
     300static async_sess_t *socket_get_udp_sess(void)
     301{
     302        if (socket_globals.udp_sess == NULL) {
     303                socket_globals.udp_sess = bind_service(SERVICE_UDP,
     304                    0, 0, SERVICE_UDP, socket_connection);
     305        }
     306
     307        return socket_globals.udp_sess;
    319308}
    320309
     
    332321        sockets = socket_get_sockets();
    333322        count = 0;
    334 //      socket_id = socket_globals.last_id;
    335323
    336324        do {
     
    345333                        if (socket_id < INT_MAX) {
    346334                                ++socket_id;
    347 /*                      } else if(socket_globals.last_id) {
    348  *                              socket_globals.last_id = 0;
    349  *                              socket_id = 1;
    350  */                     } else {
     335                        } else {
    351336                                return ELIMIT;
    352337                        }
    353338                }
    354339        } while (sockets_find(sockets, socket_id));
    355 
    356 //      last_id = socket_id
     340       
    357341        return socket_id;
    358342}
     
    361345 *
    362346 * @param[in,out] socket The socket to be initialized.
    363  * @param[in] socket_id The new socket identifier.
    364  * @param[in] phone     The parent module phone.
    365  * @param[in] service   The parent module service.
    366  */
    367 static void
    368 socket_initialize(socket_t *socket, int socket_id, int phone,
    369     services_t service)
     347 * @param[in] socket_id  The new socket identifier.
     348 * @param[in] sess       The parent module session.
     349 * @param[in] service    The parent module service.
     350 */
     351static void socket_initialize(socket_t *socket, int socket_id,
     352    async_sess_t *sess, services_t service)
    370353{
    371354        socket->socket_id = socket_id;
    372         socket->phone = phone;
     355        socket->sess = sess;
    373356        socket->service = service;
    374357        dyn_fifo_initialize(&socket->received, SOCKET_INITIAL_RECEIVED_SIZE);
     
    395378 * @return              Other error codes as defined for the NET_SOCKET message.
    396379 * @return              Other error codes as defined for the
    397  *                      bind_service_timeout() function.
     380 *                      bind_service() function.
    398381 */
    399382int socket(int domain, int type, int protocol)
    400383{
    401384        socket_t *socket;
    402         int phone;
     385        async_sess_t *sess;
    403386        int socket_id;
    404387        services_t service;
     
    417400                        switch (protocol) {
    418401                        case IPPROTO_TCP:
    419                                 phone = socket_get_tcp_phone();
     402                                sess = socket_get_tcp_sess();
    420403                                service = SERVICE_TCP;
    421404                                break;
     
    432415                        switch (protocol) {
    433416                        case IPPROTO_UDP:
    434                                 phone = socket_get_udp_phone();
     417                                sess = socket_get_udp_sess();
    435418                                service = SERVICE_UDP;
    436419                                break;
     
    453436        }
    454437
    455         if (phone < 0)
    456                 return phone;
     438        if (sess == NULL)
     439                return ENOENT;
    457440
    458441        /* Create a new socket structure */
     
    471454                return socket_id;
    472455        }
    473 
    474         rc = (int) async_req_3_3(phone, NET_SOCKET, socket_id, 0, service, NULL,
     456       
     457        async_exch_t *exch = async_exchange_begin(sess);
     458        rc = (int) async_req_3_3(exch, NET_SOCKET, socket_id, 0, service, NULL,
    475459            &fragment_size, &header_size);
     460        async_exchange_end(exch);
     461       
    476462        if (rc != EOK) {
    477463                fibril_rwlock_write_unlock(&socket_globals.lock);
     
    484470
    485471        /* Finish the new socket initialization */
    486         socket_initialize(socket, socket_id, phone, service);
     472        socket_initialize(socket, socket_id, sess, service);
    487473        /* Store the new socket */
    488474        rc = sockets_add(socket_get_sockets(), socket_id, socket);
     
    493479                dyn_fifo_destroy(&socket->accepted);
    494480                free(socket);
    495                 async_msg_3(phone, NET_SOCKET_CLOSE, (sysarg_t) socket_id, 0,
     481               
     482                exch = async_exchange_begin(sess);
     483                async_msg_3(exch, NET_SOCKET_CLOSE, (sysarg_t) socket_id, 0,
    496484                    service);
     485                async_exchange_end(exch);
     486               
    497487                return rc;
    498488        }
     
    538528
    539529        /* Request the message */
    540         message_id = async_send_3(socket->phone, message,
     530        async_exch_t *exch = async_exchange_begin(socket->sess);
     531        message_id = async_send_3(exch, message,
    541532            (sysarg_t) socket->socket_id, arg2, socket->service, NULL);
    542533        /* Send the address */
    543         async_data_write_start(socket->phone, data, datalength);
     534        async_data_write_start(exch, data, datalength);
     535        async_exchange_end(exch);
    544536
    545537        fibril_rwlock_read_unlock(&socket_globals.lock);
     
    598590
    599591        /* Request listen backlog change */
    600         result = (int) async_req_3_0(socket->phone, NET_SOCKET_LISTEN,
     592        async_exch_t *exch = async_exchange_begin(socket->sess);
     593        result = (int) async_req_3_0(exch, NET_SOCKET_LISTEN,
    601594            (sysarg_t) socket->socket_id, (sysarg_t) backlog, socket->service);
     595        async_exchange_end(exch);
    602596
    603597        fibril_rwlock_read_unlock(&socket_globals.lock);
     
    669663                return socket_id;
    670664        }
    671         socket_initialize(new_socket, socket_id, socket->phone,
     665        socket_initialize(new_socket, socket_id, socket->sess,
    672666            socket->service);
    673667        result = sockets_add(socket_get_sockets(), new_socket->socket_id,
     
    681675
    682676        /* Request accept */
    683         message_id = async_send_5(socket->phone, NET_SOCKET_ACCEPT,
     677        async_exch_t *exch = async_exchange_begin(socket->sess);
     678        message_id = async_send_5(exch, NET_SOCKET_ACCEPT,
    684679            (sysarg_t) socket->socket_id, 0, socket->service, 0,
    685680            new_socket->socket_id, &answer);
    686681
    687682        /* Read address */
    688         async_data_read_start(socket->phone, cliaddr, *addrlen);
     683        async_data_read_start(exch, cliaddr, *addrlen);
     684        async_exchange_end(exch);
     685       
    689686        fibril_rwlock_write_unlock(&socket_globals.lock);
    690687        async_wait_for(message_id, &ipc_result);
     
    749746        dyn_fifo_destroy(&socket->received);
    750747        dyn_fifo_destroy(&socket->accepted);
    751         sockets_exclude(socket_get_sockets(), socket->socket_id);
     748        sockets_exclude(socket_get_sockets(), socket->socket_id, free);
    752749}
    753750
     
    780777
    781778        /* Request close */
    782         rc = (int) async_req_3_0(socket->phone, NET_SOCKET_CLOSE,
     779        async_exch_t *exch = async_exchange_begin(socket->sess);
     780        rc = (int) async_req_3_0(exch, NET_SOCKET_CLOSE,
    783781            (sysarg_t) socket->socket_id, 0, socket->service);
     782        async_exchange_end(exch);
     783       
    784784        if (rc != EOK) {
    785785                fibril_rwlock_write_unlock(&socket_globals.lock);
     
    853853
    854854        /* Request send */
    855         message_id = async_send_5(socket->phone, message,
     855        async_exch_t *exch = async_exchange_begin(socket->sess);
     856       
     857        message_id = async_send_5(exch, message,
    856858            (sysarg_t) socket->socket_id,
    857859            (fragments == 1 ? datalength : socket->data_fragment_size),
     
    860862        /* Send the address if given */
    861863        if (!toaddr ||
    862             (async_data_write_start(socket->phone, toaddr, addrlen) == EOK)) {
     864            (async_data_write_start(exch, toaddr, addrlen) == EOK)) {
    863865                if (fragments == 1) {
    864866                        /* Send all if only one fragment */
    865                         async_data_write_start(socket->phone, data, datalength);
     867                        async_data_write_start(exch, data, datalength);
    866868                } else {
    867869                        /* Send the first fragment */
    868                         async_data_write_start(socket->phone, data,
     870                        async_data_write_start(exch, data,
    869871                            socket->data_fragment_size - socket->header_size);
    870872                        data = ((const uint8_t *) data) +
     
    873875                        /* Send the middle fragments */
    874876                        while (--fragments > 1) {
    875                                 async_data_write_start(socket->phone, data,
     877                                async_data_write_start(exch, data,
    876878                                    socket->data_fragment_size);
    877879                                data = ((const uint8_t *) data) +
     
    880882
    881883                        /* Send the last fragment */
    882                         async_data_write_start(socket->phone, data,
     884                        async_data_write_start(exch, data,
    883885                            (datalength + socket->header_size) %
    884886                            socket->data_fragment_size);
    885887                }
    886888        }
     889       
     890        async_exchange_end(exch);
    887891
    888892        async_wait_for(message_id, &result);
     
    10261030                return 0;
    10271031        }
     1032       
     1033        async_exch_t *exch = async_exchange_begin(socket->sess);
    10281034
    10291035        /* Prepare lengths if more fragments */
     
    10381044
    10391045                /* Request packet data */
    1040                 message_id = async_send_4(socket->phone, message,
     1046                message_id = async_send_4(exch, message,
    10411047                    (sysarg_t) socket->socket_id, 0, socket->service,
    10421048                    (sysarg_t) flags, &answer);
     
    10441050                /* Read the address if desired */
    10451051                if(!fromaddr ||
    1046                     (async_data_read_start(socket->phone, fromaddr,
     1052                    (async_data_read_start(exch, fromaddr,
    10471053                    *addrlen) == EOK)) {
    10481054                        /* Read the fragment lengths */
    1049                         if (async_data_read_start(socket->phone, lengths,
     1055                        if (async_data_read_start(exch, lengths,
    10501056                            sizeof(int) * (fragments + 1)) == EOK) {
    10511057                                if (lengths[fragments] <= datalength) {
     
    10541060                                        for (index = 0; index < fragments;
    10551061                                            ++index) {
    1056                                                 async_data_read_start(
    1057                                                     socket->phone, data,
     1062                                                async_data_read_start(exch, data,
    10581063                                                    lengths[index]);
    10591064                                                data = ((uint8_t *) data) +
     
    10671072        } else { /* fragments == 1 */
    10681073                /* Request packet data */
    1069                 message_id = async_send_4(socket->phone, message,
     1074                message_id = async_send_4(exch, message,
    10701075                    (sysarg_t) socket->socket_id, 0, socket->service,
    10711076                    (sysarg_t) flags, &answer);
     
    10731078                /* Read the address if desired */
    10741079                if (!fromaddr ||
    1075                     (async_data_read_start(socket->phone, fromaddr,
    1076                         *addrlen) == EOK)) {
     1080                    (async_data_read_start(exch, fromaddr, *addrlen) == EOK)) {
    10771081                        /* Read all if only one fragment */
    1078                         async_data_read_start(socket->phone, data, datalength);
     1082                        async_data_read_start(exch, data, datalength);
    10791083                }
    10801084        }
     1085       
     1086        async_exchange_end(exch);
    10811087
    10821088        async_wait_for(message_id, &ipc_result);
     
    11901196
    11911197        /* Request option value */
    1192         message_id = async_send_3(socket->phone, NET_SOCKET_GETSOCKOPT,
     1198        async_exch_t *exch = async_exchange_begin(socket->sess);
     1199       
     1200        message_id = async_send_3(exch, NET_SOCKET_GETSOCKOPT,
    11931201            (sysarg_t) socket->socket_id, (sysarg_t) optname, socket->service,
    11941202            NULL);
    11951203
    11961204        /* Read the length */
    1197         if (async_data_read_start(socket->phone, optlen,
     1205        if (async_data_read_start(exch, optlen,
    11981206            sizeof(*optlen)) == EOK) {
    11991207                /* Read the value */
    1200                 async_data_read_start(socket->phone, value, *optlen);
    1201         }
     1208                async_data_read_start(exch, value, *optlen);
     1209        }
     1210       
     1211        async_exchange_end(exch);
    12021212
    12031213        fibril_rwlock_read_unlock(&socket_globals.lock);
Note: See TracChangeset for help on using the changeset viewer.