Ignore:
File:
1 edited

Legend:

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

    r6b82009 r64d2b10  
    4545#include <ipc/services.h>
    4646#include <net/modules.h>
    47 #include <ns.h>
     47
     48/** The time between connect requests in microseconds. */
     49#define MODULE_WAIT_TIME        (10 * 1000)
    4850
    4951/** Answer a call.
     
    9395}
    9496
    95 /** Create bidirectional connection with the needed module service and register
     97/** Create bidirectional connection with the needed module service and registers
    9698 * the message receiver.
    9799 *
    98  * @param[in] need            Needed module service.
    99  * @param[in] arg1            First parameter.
    100  * @param[in] arg2            Second parameter.
    101  * @param[in] arg3            Third parameter.
    102  * @param[in] client_receiver Message receiver.
    103  *
    104  * @return Session to the needed service.
    105  * @return Other error codes as defined for the async_connect_to_me()
    106  *         function.
    107  *
    108  */
    109 async_sess_t *bind_service(services_t need, sysarg_t arg1, sysarg_t arg2,
    110     sysarg_t arg3, async_client_conn_t client_receiver)
     100 * @param[in] need      The needed module service.
     101 * @param[in] arg1      The first parameter.
     102 * @param[in] arg2      The second parameter.
     103 * @param[in] arg3      The third parameter.
     104 * @param[in] client_receiver The message receiver.
     105 *
     106 * @return              The phone of the needed service.
     107 * @return              Other error codes as defined for the ipc_connect_to_me()
     108 *                      function.
     109 */
     110int bind_service(services_t need, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
     111    async_client_conn_t client_receiver)
     112{
     113        return bind_service_timeout(need, arg1, arg2, arg3, client_receiver, 0);
     114}
     115
     116/** Create bidirectional connection with the needed module service and registers
     117 * the message receiver.
     118 *
     119 * @param[in] need      The needed module service.
     120 * @param[in] arg1      The first parameter.
     121 * @param[in] arg2      The second parameter.
     122 * @param[in] arg3      The third parameter.
     123 * @param[in] client_receiver The message receiver.
     124 * @param[in] timeout   The connection timeout in microseconds. No timeout if
     125 *                      set to zero (0).
     126 *
     127 * @return              The phone of the needed service.
     128 * @return              ETIMEOUT if the connection timeouted.
     129 * @return              Other error codes as defined for the ipc_connect_to_me()
     130 *                      function.
     131 *
     132 */
     133int bind_service_timeout(services_t need, sysarg_t arg1, sysarg_t arg2,
     134    sysarg_t arg3, async_client_conn_t client_receiver, suseconds_t timeout)
    111135{
    112136        /* Connect to the needed service */
    113         async_sess_t *sess = connect_to_service(need);
    114         if (sess != NULL) {
     137        int phone = connect_to_service_timeout(need, timeout);
     138        if (phone >= 0) {
    115139                /* Request the bidirectional connection */
    116                 async_exch_t *exch = async_exchange_begin(sess);
    117                 int rc = async_connect_to_me(exch, arg1, arg2, arg3,
    118                     client_receiver, NULL);
    119                 async_exchange_end(exch);
    120                
     140                int rc = async_connect_to_me(phone, arg1, arg2, arg3, client_receiver);
    121141                if (rc != EOK) {
    122                         async_hangup(sess);
    123                         errno = rc;
    124                         return NULL;
     142                        async_hangup(phone);
     143                        return rc;
    125144                }
    126145        }
    127146       
    128         return sess;
    129 }
    130 
    131 /** Connect to the needed module.
    132  *
    133  * @param[in] need Needed module service.
    134  *
    135  * @return Session to the needed service.
    136  * @return NULL if the connection timeouted.
    137  *
    138  */
    139 async_sess_t *connect_to_service(services_t need)
    140 {
    141         return service_connect_blocking(EXCHANGE_SERIALIZE, need, 0, 0);
    142 }
    143 
    144 /** Reply the data to the other party.
    145  *
    146  * @param[in] data        The data buffer to be sent.
     147        return phone;
     148}
     149
     150/** Connects to the needed module.
     151 *
     152 * @param[in] need      The needed module service.
     153 * @return              The phone of the needed service.
     154 */
     155int connect_to_service(services_t need)
     156{
     157        return connect_to_service_timeout(need, 0);
     158}
     159
     160/** Connects to the needed module.
     161 *
     162 *  @param[in] need     The needed module service.
     163 *  @param[in] timeout  The connection timeout in microseconds. No timeout if
     164 *                      set to zero (0).
     165 *  @return             The phone of the needed service.
     166 *  @return             ETIMEOUT if the connection timeouted.
     167 */
     168int connect_to_service_timeout(services_t need, suseconds_t timeout)
     169{
     170        int phone;
     171
     172        /* If no timeout is set */
     173        if (timeout <= 0)
     174                return async_connect_me_to_blocking(PHONE_NS, need, 0, 0);
     175
     176        while (true) {
     177                phone = async_connect_me_to(PHONE_NS, need, 0, 0);
     178                if ((phone >= 0) || (phone != ENOENT))
     179                        return phone;
     180
     181                /* Abort if no time is left */
     182                if (timeout <= 0)
     183                        return ETIMEOUT;
     184
     185                /* Wait the minimum of the module wait time and the timeout */
     186                usleep((timeout <= MODULE_WAIT_TIME) ?
     187                    timeout : MODULE_WAIT_TIME);
     188                timeout -= MODULE_WAIT_TIME;
     189        }
     190}
     191
     192/** Replies the data to the other party.
     193 *
     194 * @param[in] data      The data buffer to be sent.
    147195 * @param[in] data_length The buffer length.
    148  *
    149  * @return EOK on success.
    150  * @return EINVAL if the client does not expect the data.
    151  * @return EOVERFLOW if the client does not expect all the data.
    152  *         Only partial data are transfered.
    153  * @return Other error codes as defined for the
    154  *         async_data_read_finalize() function.
    155  *
     196 * @return              EOK on success.
     197 * @return              EINVAL if the client does not expect the data.
     198 * @return              EOVERFLOW if the client does not expect all the data.
     199 *                      Only partial data are transfered.
     200 * @return              Other error codes as defined for the
     201 *                      async_data_read_finalize() function.
    156202 */
    157203int data_reply(void *data, size_t data_length)
     
    159205        size_t length;
    160206        ipc_callid_t callid;
    161        
     207
    162208        /* Fetch the request */
    163209        if (!async_data_read_receive(&callid, &length))
    164210                return EINVAL;
    165        
     211
    166212        /* Check the requested data size */
    167213        if (length < data_length) {
     
    169215                return EOVERFLOW;
    170216        }
    171        
     217
    172218        /* Send the data */
    173219        return async_data_read_finalize(callid, data, data_length);
Note: See TracChangeset for help on using the changeset viewer.