Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/async.c

    r86d7bfa rc1c0184  
    4343 * framework will automatically take care of most synchronization problems.
    4444 *
     45 * Default semantics:
     46 * - async_send_*(): Send asynchronously. If the kernel refuses to send
     47 *                   more messages, [ try to get responses from kernel, if
     48 *                   nothing found, might try synchronous ]
     49 *
    4550 * Example of use (pseudo C):
    4651 *
     
    5358 *   int fibril1(void *arg)
    5459 *   {
    55  *     conn = async_connect_me_to();
     60 *     conn = ipc_connect_me_to();
    5661 *     c1 = async_send(conn);
    5762 *     c2 = async_send(conn);
     
    7277 *   {
    7378 *     if (want_refuse) {
    74  *       async_answer_0(icallid, ELIMIT);
     79 *       ipc_answer_0(icallid, ELIMIT);
    7580 *       return;
    7681 *     }
    77  *     async_answer_0(icallid, EOK);
     82 *     ipc_answer_0(icallid, EOK);
    7883 *
    7984 *     callid = async_get_call(&call);
    8085 *     somehow_handle_the_call(callid, call);
    81  *     async_answer_2(callid, 1, 2, 3);
     86 *     ipc_answer_2(callid, 1, 2, 3);
    8287 *
    8388 *     callid = async_get_call(&call);
     
    8792 */
    8893
    89 #define LIBC_ASYNC_C_
    90 #include <ipc/ipc.h>
     94#include <futex.h>
    9195#include <async.h>
    92 #undef LIBC_ASYNC_C_
    93 
    94 #include <futex.h>
     96#include <async_priv.h>
    9597#include <fibril.h>
    9698#include <stdio.h>
    9799#include <adt/hash_table.h>
    98100#include <adt/list.h>
     101#include <ipc/ipc.h>
    99102#include <assert.h>
    100103#include <errno.h>
     
    102105#include <arch/barrier.h>
    103106#include <bool.h>
    104 #include "private/async.h"
    105107
    106108atomic_t async_futex = FUTEX_INITIALIZER;
     
    122124
    123125/**
    124  * Structures of this type are used to group information about
    125  * a call and about a message queue link.
     126 * Structures of this type are used to group information about a call and a
     127 * message queue link.
    126128 */
    127129typedef struct {
     
    132134
    133135typedef struct {
    134         sysarg_t in_task_hash;
    135         link_t link;
    136         int refcnt;
    137         void *data;
    138 } client_t;
    139 
    140 typedef struct {
    141136        awaiter_t wdata;
    142137       
     
    144139        link_t link;
    145140       
    146         /** Incoming client task hash. */
    147         sysarg_t in_task_hash;
    148141        /** Incoming phone hash. */
    149142        sysarg_t in_phone_hash;
    150        
    151         /** Link to the client tracking structure. */
    152         client_t *client;
    153143       
    154144        /** Messages that should be delivered to this fibril. */
     
    168158
    169159/** Identifier of the incoming connection handled by the current fibril. */
    170 static fibril_local connection_t *FIBRIL_connection;
    171 
    172 static void *default_client_data_constructor(void)
    173 {
    174         return NULL;
    175 }
    176 
    177 static void default_client_data_destructor(void *data)
    178 {
    179 }
    180 
    181 static async_client_data_ctor_t async_client_data_create =
    182     default_client_data_constructor;
    183 static async_client_data_dtor_t async_client_data_destroy =
    184     default_client_data_destructor;
    185 
    186 void async_set_client_data_constructor(async_client_data_ctor_t ctor)
    187 {
    188         async_client_data_create = ctor;
    189 }
    190 
    191 void async_set_client_data_destructor(async_client_data_dtor_t dtor)
    192 {
    193         async_client_data_destroy = dtor;
    194 }
    195 
    196 void *async_client_data_get(void)
    197 {
    198         assert(FIBRIL_connection);
    199         return FIBRIL_connection->client->data;
    200 }
    201 
    202 /** Default fibril function that gets called to handle new connection.
    203  *
    204  * This function is defined as a weak symbol - to be redefined in user code.
    205  *
    206  * @param callid Hash of the incoming call.
    207  * @param call   Data of the incoming call.
    208  *
    209  */
    210 static void default_client_connection(ipc_callid_t callid, ipc_call_t *call)
    211 {
    212         ipc_answer_0(callid, ENOENT);
    213 }
     160fibril_local connection_t *FIBRIL_connection;
     161
     162static void default_client_connection(ipc_callid_t callid, ipc_call_t *call);
     163static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call);
    214164
    215165/**
     
    217167 */
    218168static async_client_conn_t client_connection = default_client_connection;
    219 
    220 /** Default fibril function that gets called to handle interrupt notifications.
    221  *
    222  * This function is defined as a weak symbol - to be redefined in user code.
    223  *
    224  * @param callid Hash of the incoming call.
    225  * @param call   Data of the incoming call.
    226  *
    227  */
    228 static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call)
    229 {
    230 }
    231169
    232170/**
     
    236174static async_client_conn_t interrupt_received = default_interrupt_received;
    237175
    238 static hash_table_t client_hash_table;
    239176static hash_table_t conn_hash_table;
    240177static LIST_INITIALIZE(timeout_list);
    241178
    242 #define CLIENT_HASH_TABLE_BUCKETS  32
    243 #define CONN_HASH_TABLE_BUCKETS    32
    244 
    245 static hash_index_t client_hash(unsigned long key[])
     179#define CONN_HASH_TABLE_CHAINS  32
     180
     181/** Compute hash into the connection hash table based on the source phone hash.
     182 *
     183 * @param key Pointer to source phone hash.
     184 *
     185 * @return Index into the connection hash table.
     186 *
     187 */
     188static hash_index_t conn_hash(unsigned long *key)
    246189{
    247190        assert(key);
    248         return (((key[0]) >> 4) % CLIENT_HASH_TABLE_BUCKETS);
    249 }
    250 
    251 static int client_compare(unsigned long key[], hash_count_t keys, link_t *item)
    252 {
    253         client_t *client = hash_table_get_instance(item, client_t, link);
    254         return (key[0] == client->in_task_hash);
    255 }
    256 
    257 static void client_remove(link_t *item)
    258 {
    259 }
    260 
    261 /** Operations for the client hash table. */
    262 static hash_table_operations_t client_hash_table_ops = {
    263         .hash = client_hash,
    264         .compare = client_compare,
    265         .remove_callback = client_remove
    266 };
    267 
    268 /** Compute hash into the connection hash table based on the source phone hash.
    269  *
    270  * @param key Pointer to source phone hash.
    271  *
    272  * @return Index into the connection hash table.
    273  *
    274  */
    275 static hash_index_t conn_hash(unsigned long key[])
    276 {
    277         assert(key);
    278         return (((key[0]) >> 4) % CONN_HASH_TABLE_BUCKETS);
     191        return (((*key) >> 4) % CONN_HASH_TABLE_CHAINS);
    279192}
    280193
     
    290203static int conn_compare(unsigned long key[], hash_count_t keys, link_t *item)
    291204{
    292         connection_t *conn = hash_table_get_instance(item, connection_t, link);
    293         return (key[0] == conn->in_phone_hash);
     205        connection_t *hs = hash_table_get_instance(item, connection_t, link);
     206        return (key[0] == hs->in_phone_hash);
    294207}
    295208
     
    306219        free(hash_table_get_instance(item, connection_t, link));
    307220}
     221
    308222
    309223/** Operations for the connection hash table. */
     
    326240        link_t *tmp = timeout_list.next;
    327241        while (tmp != &timeout_list) {
    328                 awaiter_t *cur
    329                     = list_get_instance(tmp, awaiter_t, to_event.link);
     242                awaiter_t *cur;
    330243               
     244                cur = list_get_instance(tmp, awaiter_t, to_event.link);
    331245                if (tv_gteq(&cur->to_event.expires, &wd->to_event.expires))
    332246                        break;
    333                
    334247                tmp = tmp->next;
    335248        }
     
    348261 *
    349262 * @return False if the call doesn't match any connection.
    350  * @return True if the call was passed to the respective connection fibril.
     263 *         True if the call was passed to the respective connection fibril.
    351264 *
    352265 */
     
    439352       
    440353        fid_t fid = fibril_create(notification_fibril, msg);
    441         if (fid == 0) {
    442                 free(msg);
    443                 futex_up(&async_futex);
    444                 return false;
    445         }
    446        
    447354        fibril_add_ready(fid);
    448355       
     
    491398                         * the first IPC_M_PHONE_HUNGUP call and continues to
    492399                         * call async_get_call_timeout(). Repeat
    493                          * IPC_M_PHONE_HUNGUP until the caller notices.
     400                         * IPC_M_PHONE_HUNGUP until the caller notices. 
    494401                         */
    495402                        memset(call, 0, sizeof(ipc_call_t));
     
    498405                        return conn->close_callid;
    499406                }
    500                
     407
    501408                if (usecs)
    502409                        async_insert_timeout(&conn->wdata);
     
    536443}
    537444
     445/** Default fibril function that gets called to handle new connection.
     446 *
     447 * This function is defined as a weak symbol - to be redefined in user code.
     448 *
     449 * @param callid Hash of the incoming call.
     450 * @param call   Data of the incoming call.
     451 *
     452 */
     453static void default_client_connection(ipc_callid_t callid, ipc_call_t *call)
     454{
     455        ipc_answer_0(callid, ENOENT);
     456}
     457
     458/** Default fibril function that gets called to handle interrupt notifications.
     459 *
     460 * This function is defined as a weak symbol - to be redefined in user code.
     461 *
     462 * @param callid Hash of the incoming call.
     463 * @param call   Data of the incoming call.
     464 *
     465 */
     466static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call)
     467{
     468}
     469
    538470/** Wrapper for client connection fibril.
    539471 *
     
    549481{
    550482        /*
    551          * Setup fibril-local connection pointer.
     483         * Setup fibril-local connection pointer and call client_connection().
     484         *
    552485         */
    553486        FIBRIL_connection = (connection_t *) arg;
    554        
    555         futex_down(&async_futex);
    556        
    557         /*
    558          * Add our reference for the current connection in the client task
    559          * tracking structure. If this is the first reference, create and
    560          * hash in a new tracking structure.
    561          */
    562        
    563         unsigned long key = FIBRIL_connection->in_task_hash;
    564         link_t *lnk = hash_table_find(&client_hash_table, &key);
    565        
    566         client_t *client;
    567        
    568         if (lnk) {
    569                 client = hash_table_get_instance(lnk, client_t, link);
    570                 client->refcnt++;
    571         } else {
    572                 client = malloc(sizeof(client_t));
    573                 if (!client) {
    574                         ipc_answer_0(FIBRIL_connection->callid, ENOMEM);
    575                         futex_up(&async_futex);
    576                         return 0;
    577                 }
    578                
    579                 client->in_task_hash = FIBRIL_connection->in_task_hash;
    580                
    581                 async_serialize_start();
    582                 client->data = async_client_data_create();
    583                 async_serialize_end();
    584                
    585                 client->refcnt = 1;
    586                 hash_table_insert(&client_hash_table, &key, &client->link);
    587         }
    588        
    589         futex_up(&async_futex);
    590        
    591         FIBRIL_connection->client = client;
    592        
    593         /*
    594          * Call the connection handler function.
    595          */
    596487        FIBRIL_connection->cfibril(FIBRIL_connection->callid,
    597488            &FIBRIL_connection->call);
    598489       
    599         /*
    600          * Remove the reference for this client task connection.
    601          */
    602         bool destroy;
    603        
     490        /* Remove myself from the connection hash table */
    604491        futex_down(&async_futex);
    605        
    606         if (--client->refcnt == 0) {
    607                 hash_table_remove(&client_hash_table, &key, 1);
    608                 destroy = true;
    609         } else
    610                 destroy = false;
    611        
    612         futex_up(&async_futex);
    613        
    614         if (destroy) {
    615                 if (client->data)
    616                         async_client_data_destroy(client->data);
    617                
    618                 free(client);
    619         }
    620        
    621         /*
    622          * Remove myself from the connection hash table.
    623          */
    624         futex_down(&async_futex);
    625         key = FIBRIL_connection->in_phone_hash;
     492        unsigned long key = FIBRIL_connection->in_phone_hash;
    626493        hash_table_remove(&conn_hash_table, &key, 1);
    627494        futex_up(&async_futex);
    628495       
    629         /*
    630          * Answer all remaining messages with EHANGUP.
    631          */
     496        /* Answer all remaining messages with EHANGUP */
    632497        while (!list_empty(&FIBRIL_connection->msg_queue)) {
    633                 msg_t *msg =
    634                     list_get_instance(FIBRIL_connection->msg_queue.next, msg_t,
    635                     link);
     498                msg_t *msg;
    636499               
     500                msg = list_get_instance(FIBRIL_connection->msg_queue.next,
     501                    msg_t, link);
    637502                list_remove(&msg->link);
    638503                ipc_answer_0(msg->callid, EHANGUP);
     
    640505        }
    641506       
    642         /*
    643          * If the connection was hung-up, answer the last call,
    644          * i.e. IPC_M_PHONE_HUNGUP.
    645          */
    646507        if (FIBRIL_connection->close_callid)
    647508                ipc_answer_0(FIBRIL_connection->close_callid, EOK);
     
    656517 * particular fibrils.
    657518 *
    658  * @param in_task_hash  Identification of the incoming connection.
    659519 * @param in_phone_hash Identification of the incoming connection.
    660520 * @param callid        Hash of the opening IPC_M_CONNECT_ME_TO call.
     
    669529 *
    670530 */
    671 fid_t async_new_connection(sysarg_t in_task_hash, sysarg_t in_phone_hash,
    672     ipc_callid_t callid, ipc_call_t *call,
    673     void (*cfibril)(ipc_callid_t, ipc_call_t *))
     531fid_t async_new_connection(sysarg_t in_phone_hash, ipc_callid_t callid,
     532    ipc_call_t *call, void (*cfibril)(ipc_callid_t, ipc_call_t *))
    674533{
    675534        connection_t *conn = malloc(sizeof(*conn));
     
    677536                if (callid)
    678537                        ipc_answer_0(callid, ENOMEM);
    679                
    680538                return (uintptr_t) NULL;
    681539        }
    682540       
    683         conn->in_task_hash = in_task_hash;
    684541        conn->in_phone_hash = in_phone_hash;
    685542        list_initialize(&conn->msg_queue);
     
    695552        conn->wdata.fid = fibril_create(connection_fibril, conn);
    696553       
    697         if (conn->wdata.fid == 0) {
     554        if (!conn->wdata.fid) {
    698555                free(conn);
    699                
    700556                if (callid)
    701557                        ipc_answer_0(callid, ENOMEM);
    702                
    703558                return (uintptr_t) NULL;
    704559        }
     
    727582static void handle_call(ipc_callid_t callid, ipc_call_t *call)
    728583{
    729         /* Unrouted call - take some default action */
     584        /* Unrouted call - do some default behaviour */
    730585        if ((callid & IPC_CALLID_NOTIFICATION)) {
    731586                process_notification(callid, call);
    732                 return;
     587                goto out;
    733588        }
    734589       
     
    736591        case IPC_M_CONNECT_ME:
    737592        case IPC_M_CONNECT_ME_TO:
    738                 /* Open new connection with fibril, etc. */
    739                 async_new_connection(call->in_task_hash, IPC_GET_ARG5(*call),
    740                     callid, call, client_connection);
    741                 return;
     593                /* Open new connection with fibril etc. */
     594                async_new_connection(IPC_GET_ARG5(*call), callid, call,
     595                    client_connection);
     596                goto out;
    742597        }
    743598       
    744599        /* Try to route the call through the connection hash table */
    745600        if (route_call(callid, call))
    746                 return;
     601                goto out;
    747602       
    748603        /* Unknown call from unknown phone - hang it up */
    749604        ipc_answer_0(callid, EHANGUP);
     605        return;
     606       
     607out:
     608        ;
    750609}
    751610
     
    760619        link_t *cur = timeout_list.next;
    761620        while (cur != &timeout_list) {
    762                 awaiter_t *waiter =
    763                     list_get_instance(cur, awaiter_t, to_event.link);
     621                awaiter_t *waiter;
    764622               
     623                waiter = list_get_instance(cur, awaiter_t, to_event.link);
    765624                if (tv_gt(&waiter->to_event.expires, &tv))
    766625                        break;
    767                
     626
    768627                cur = cur->next;
    769                
     628
    770629                list_remove(&waiter->to_event.link);
    771630                waiter->to_event.inlist = false;
     
    794653        while (true) {
    795654                if (fibril_switch(FIBRIL_FROM_MANAGER)) {
    796                         futex_up(&async_futex);
     655                        futex_up(&async_futex); 
    797656                        /*
    798657                         * async_futex is always held when entering a manager
     
    817676                                continue;
    818677                        } else
    819                                 timeout = tv_sub(&waiter->to_event.expires, &tv);
     678                                timeout = tv_sub(&waiter->to_event.expires,
     679                                    &tv);
    820680                } else
    821681                        timeout = SYNCH_NO_TIMEOUT;
    822682               
    823683                futex_up(&async_futex);
    824                
     684
    825685                atomic_inc(&threads_in_ipc_wait);
    826686               
     
    830690               
    831691                atomic_dec(&threads_in_ipc_wait);
    832                
     692
    833693                if (!callid) {
    834694                        handle_expired_timeouts();
     
    869729{
    870730        fid_t fid = fibril_create(async_manager_fibril, NULL);
    871         if (fid != 0)
    872                 fibril_add_manager(fid);
     731        fibril_add_manager(fid);
    873732}
    874733
     
    881740/** Initialize the async framework.
    882741 *
    883  */
    884 void __async_init(void)
    885 {
    886         if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS, 1,
    887             &client_hash_table_ops))
    888                 abort();
    889        
    890         if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_BUCKETS, 1,
    891             &conn_hash_table_ops))
    892                 abort();
     742 * @return Zero on success or an error code.
     743 */
     744int __async_init(void)
     745{
     746        if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_CHAINS, 1,
     747            &conn_hash_table_ops)) {
     748                printf("%s: Cannot create async hash table\n", "libc");
     749                return ENOMEM;
     750        }
     751
     752        _async_sess_init();
     753       
     754        return 0;
    893755}
    894756
     
    903765 * @param retval Value returned in the answer.
    904766 * @param data   Call data of the answer.
    905  *
    906767 */
    907768static void reply_received(void *arg, int retval, ipc_call_t *data)
     
    951812    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr)
    952813{
    953         amsg_t *msg = malloc(sizeof(amsg_t));
     814        amsg_t *msg = malloc(sizeof(*msg));
    954815       
    955816        if (!msg)
     
    960821       
    961822        msg->wdata.to_event.inlist = false;
    962        
    963         /*
    964          * We may sleep in the next method,
    965          * but it will use its own means
    966          */
     823        /* We may sleep in the next method, but it will use its own mechanism */
    967824        msg->wdata.active = true;
    968825       
     
    995852    ipc_call_t *dataptr)
    996853{
    997         amsg_t *msg = malloc(sizeof(amsg_t));
     854        amsg_t *msg = malloc(sizeof(*msg));
    998855       
    999856        if (!msg)
     
    1004861       
    1005862        msg->wdata.to_event.inlist = false;
    1006        
    1007         /*
    1008          * We may sleep in the next method,
    1009          * but it will use its own means
    1010          */
     863        /* We may sleep in next method, but it will use its own mechanism */
    1011864        msg->wdata.active = true;
    1012865       
     
    1107960void async_usleep(suseconds_t timeout)
    1108961{
    1109         amsg_t *msg = malloc(sizeof(amsg_t));
     962        amsg_t *msg = malloc(sizeof(*msg));
    1110963       
    1111964        if (!msg)
     
    12501103}
    12511104
    1252 void async_msg_0(int phone, sysarg_t imethod)
    1253 {
    1254         ipc_call_async_0(phone, imethod, NULL, NULL, true);
    1255 }
    1256 
    1257 void async_msg_1(int phone, sysarg_t imethod, sysarg_t arg1)
    1258 {
    1259         ipc_call_async_1(phone, imethod, arg1, NULL, NULL, true);
    1260 }
    1261 
    1262 void async_msg_2(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2)
    1263 {
    1264         ipc_call_async_2(phone, imethod, arg1, arg2, NULL, NULL, true);
    1265 }
    1266 
    1267 void async_msg_3(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
    1268     sysarg_t arg3)
    1269 {
    1270         ipc_call_async_3(phone, imethod, arg1, arg2, arg3, NULL, NULL, true);
    1271 }
    1272 
    1273 void async_msg_4(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
    1274     sysarg_t arg3, sysarg_t arg4)
    1275 {
    1276         ipc_call_async_4(phone, imethod, arg1, arg2, arg3, arg4, NULL, NULL,
    1277             true);
    1278 }
    1279 
    1280 void async_msg_5(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
    1281     sysarg_t arg3, sysarg_t arg4, sysarg_t arg5)
    1282 {
    1283         ipc_call_async_5(phone, imethod, arg1, arg2, arg3, arg4, arg5, NULL,
    1284             NULL, true);
    1285 }
    1286 
    1287 sysarg_t async_answer_0(ipc_callid_t callid, sysarg_t retval)
    1288 {
    1289         return ipc_answer_0(callid, retval);
    1290 }
    1291 
    1292 sysarg_t async_answer_1(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1)
    1293 {
    1294         return ipc_answer_1(callid, retval, arg1);
    1295 }
    1296 
    1297 sysarg_t async_answer_2(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,
    1298     sysarg_t arg2)
    1299 {
    1300         return ipc_answer_2(callid, retval, arg1, arg2);
    1301 }
    1302 
    1303 sysarg_t async_answer_3(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,
    1304     sysarg_t arg2, sysarg_t arg3)
    1305 {
    1306         return ipc_answer_3(callid, retval, arg1, arg2, arg3);
    1307 }
    1308 
    1309 sysarg_t async_answer_4(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,
    1310     sysarg_t arg2, sysarg_t arg3, sysarg_t arg4)
    1311 {
    1312         return ipc_answer_4(callid, retval, arg1, arg2, arg3, arg4);
    1313 }
    1314 
    1315 sysarg_t async_answer_5(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,
    1316     sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5)
    1317 {
    1318         return ipc_answer_5(callid, retval, arg1, arg2, arg3, arg4, arg5);
    1319 }
    1320 
    1321 int async_forward_fast(ipc_callid_t callid, int phoneid, sysarg_t imethod,
    1322     sysarg_t arg1, sysarg_t arg2, unsigned int mode)
    1323 {
    1324         return ipc_forward_fast(callid, phoneid, imethod, arg1, arg2, mode);
    1325 }
    1326 
    1327 int async_forward_slow(ipc_callid_t callid, int phoneid, sysarg_t imethod,
    1328     sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
    1329     unsigned int mode)
    1330 {
    1331         return ipc_forward_slow(callid, phoneid, imethod, arg1, arg2, arg3, arg4,
    1332             arg5, mode);
    1333 }
    1334 
    1335 /** Wrapper for making IPC_M_CONNECT_TO_ME calls using the async framework.
    1336  *
     1105/** Wrapper for making IPC_M_CONNECT_ME_TO calls using the async framework.
     1106 *
    13371107 * Ask through phone for a new connection to some service.
    13381108 *
    1339  * @param phone           Phone handle used for contacting the other side.
    1340  * @param arg1            User defined argument.
    1341  * @param arg2            User defined argument.
    1342  * @param arg3            User defined argument.
    1343  * @param client_receiver Connection handing routine.
    1344  *
    1345  * @return New phone handle on success or a negative error code.
    1346  *
    1347  */
    1348 int async_connect_to_me(int phone, sysarg_t arg1, sysarg_t arg2,
    1349     sysarg_t arg3, async_client_conn_t client_receiver)
    1350 {
    1351         sysarg_t task_hash;
    1352         sysarg_t phone_hash;
    1353         int rc = async_req_3_5(phone, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,
    1354             NULL, NULL, NULL, &task_hash, &phone_hash);
    1355         if (rc != EOK)
     1109 * @param phoneid       Phone handle used for contacting the other side.
     1110 * @param arg1          User defined argument.
     1111 * @param arg2          User defined argument.
     1112 * @param arg3          User defined argument.
     1113 *
     1114 * @return              New phone handle on success or a negative error code.
     1115 */
     1116int
     1117async_connect_me_to(int phoneid, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3)
     1118{
     1119        int rc;
     1120        sysarg_t newphid;
     1121
     1122        rc = async_req_3_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, NULL,
     1123            NULL, NULL, NULL, &newphid);
     1124       
     1125        if (rc != EOK) 
    13561126                return rc;
    1357        
    1358         if (client_receiver != NULL)
    1359                 async_new_connection(task_hash, phone_hash, 0, NULL,
    1360                     client_receiver);
    1361        
    1362         return EOK;
     1127
     1128        return newphid;
    13631129}
    13641130
    13651131/** Wrapper for making IPC_M_CONNECT_ME_TO calls using the async framework.
    1366  *
    1367  * Ask through phone for a new connection to some service.
    1368  *
    1369  * @param phone Phone handle used for contacting the other side.
    1370  * @param arg1  User defined argument.
    1371  * @param arg2  User defined argument.
    1372  * @param arg3  User defined argument.
    1373  *
    1374  * @return New phone handle on success or a negative error code.
    1375  *
    1376  */
    1377 int async_connect_me_to(int phone, sysarg_t arg1, sysarg_t arg2,
    1378     sysarg_t arg3)
    1379 {
    1380         sysarg_t newphid;
    1381         int rc = async_req_3_5(phone, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
    1382             NULL, NULL, NULL, NULL, &newphid);
    1383        
    1384         if (rc != EOK)
    1385                 return rc;
    1386        
    1387         return newphid;
    1388 }
    1389 
    1390 /** Wrapper for making IPC_M_CONNECT_ME_TO calls using the async framework.
    1391  *
     1132 *
    13921133 * Ask through phone for a new connection to some service and block until
    13931134 * success.
    13941135 *
    1395  * @param phoneid Phone handle used for contacting the other side.
    1396  * @param arg1    User defined argument.
    1397  * @param arg2    User defined argument.
    1398  * @param arg3    User defined argument.
    1399  *
    1400  * @return New phone handle on success or a negative error code.
    1401  *
    1402  */
    1403 int async_connect_me_to_blocking(int phoneid, sysarg_t arg1, sysarg_t arg2,
     1136 * @param phoneid       Phone handle used for contacting the other side.
     1137 * @param arg1          User defined argument.
     1138 * @param arg2          User defined argument.
     1139 * @param arg3          User defined argument.
     1140 *
     1141 * @return              New phone handle on success or a negative error code.
     1142 */
     1143int
     1144async_connect_me_to_blocking(int phoneid, sysarg_t arg1, sysarg_t arg2,
    14041145    sysarg_t arg3)
    14051146{
     1147        int rc;
    14061148        sysarg_t newphid;
    1407         int rc = async_req_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
     1149
     1150        rc = async_req_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
    14081151            IPC_FLAG_BLOCKING, NULL, NULL, NULL, NULL, &newphid);
    14091152       
    1410         if (rc != EOK)
     1153        if (rc != EOK) 
    14111154                return rc;
    1412        
     1155
    14131156        return newphid;
    14141157}
    14151158
    1416 /** Connect to a task specified by id.
    1417  *
    1418  */
    1419 int async_connect_kbox(task_id_t id)
    1420 {
    1421         return ipc_connect_kbox(id);
    1422 }
    1423 
    1424 /** Wrapper for ipc_hangup.
    1425  *
    1426  * @param phone Phone handle to hung up.
    1427  *
    1428  * @return Zero on success or a negative error code.
    1429  *
    1430  */
    1431 int async_hangup(int phone)
    1432 {
    1433         return ipc_hangup(phone);
    1434 }
    1435 
    1436 /** Interrupt one thread of this task from waiting for IPC. */
    1437 void async_poke(void)
    1438 {
    1439         ipc_poke();
    1440 }
    1441 
    1442 /** Wrapper for IPC_M_SHARE_IN calls using the async framework.
    1443  *
    1444  * @param phoneid Phone that will be used to contact the receiving side.
    1445  * @param dst     Destination address space area base.
    1446  * @param size    Size of the destination address space area.
    1447  * @param arg     User defined argument.
    1448  * @param flags   Storage for the received flags. Can be NULL.
    1449  *
    1450  * @return Zero on success or a negative error code from errno.h.
    1451  *
     1159/** Wrapper for making IPC_M_SHARE_IN calls using the async framework.
     1160 *
     1161 * @param phoneid       Phone that will be used to contact the receiving side.
     1162 * @param dst           Destination address space area base.
     1163 * @param size          Size of the destination address space area.
     1164 * @param arg           User defined argument.
     1165 * @param flags         Storage where the received flags will be stored. Can be
     1166 *                      NULL.
     1167 *
     1168 * @return              Zero on success or a negative error code from errno.h.
    14521169 */
    14531170int async_share_in_start(int phoneid, void *dst, size_t size, sysarg_t arg,
    1454     unsigned int *flags)
    1455 {
     1171    int *flags)
     1172{
     1173        int res;
    14561174        sysarg_t tmp_flags;
    1457         int res = async_req_3_2(phoneid, IPC_M_SHARE_IN, (sysarg_t) dst,
     1175        res = async_req_3_2(phoneid, IPC_M_SHARE_IN, (sysarg_t) dst,
    14581176            (sysarg_t) size, arg, NULL, &tmp_flags);
    1459        
    14601177        if (flags)
    1461                 *flags = (unsigned int) tmp_flags;
    1462        
     1178                *flags = tmp_flags;
    14631179        return res;
    14641180}
     
    14661182/** Wrapper for receiving the IPC_M_SHARE_IN calls using the async framework.
    14671183 *
    1468  * This wrapper only makes it more comfortable to receive IPC_M_SHARE_IN
    1469  * calls so that the user doesn't have to remember the meaning of each IPC
    1470  * argument.
     1184 * This wrapper only makes it more comfortable to receive IPC_M_SHARE_IN calls
     1185 * so that the user doesn't have to remember the meaning of each IPC argument.
    14711186 *
    14721187 * So far, this wrapper is to be used from within a connection fibril.
    14731188 *
    1474  * @param callid Storage for the hash of the IPC_M_SHARE_IN call.
    1475  * @param size   Destination address space area size.
    1476  *
    1477  * @return True on success, false on failure.
    1478  *
    1479  */
    1480 bool async_share_in_receive(ipc_callid_t *callid, size_t *size)
    1481 {
     1189 * @param callid        Storage where the hash of the IPC_M_SHARE_IN call will
     1190 *                      be stored.
     1191 * @param size          Destination address space area size.   
     1192 *
     1193 * @return              Non-zero on success, zero on failure.
     1194 */
     1195int async_share_in_receive(ipc_callid_t *callid, size_t *size)
     1196{
     1197        ipc_call_t data;
     1198       
    14821199        assert(callid);
    14831200        assert(size);
    1484        
    1485         ipc_call_t data;
     1201
    14861202        *callid = async_get_call(&data);
    1487        
    14881203        if (IPC_GET_IMETHOD(data) != IPC_M_SHARE_IN)
    1489                 return false;
    1490        
     1204                return 0;
    14911205        *size = (size_t) IPC_GET_ARG2(data);
    1492         return true;
     1206        return 1;
    14931207}
    14941208
    14951209/** Wrapper for answering the IPC_M_SHARE_IN calls using the async framework.
    14961210 *
    1497  * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ
    1498  * calls so that the user doesn't have to remember the meaning of each IPC
    1499  * argument.
    1500  *
    1501  * @param callid Hash of the IPC_M_DATA_READ call to answer.
    1502  * @param src    Source address space base.
    1503  * @param flags  Flags to be used for sharing. Bits can be only cleared.
    1504  *
    1505  * @return Zero on success or a value from @ref errno.h on failure.
    1506  *
    1507  */
    1508 int async_share_in_finalize(ipc_callid_t callid, void *src, unsigned int flags)
     1211 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls
     1212 * so that the user doesn't have to remember the meaning of each IPC argument.
     1213 *
     1214 * @param callid        Hash of the IPC_M_DATA_READ call to answer.
     1215 * @param src           Source address space base.
     1216 * @param flags         Flags to be used for sharing. Bits can be only cleared.
     1217 *
     1218 * @return              Zero on success or a value from @ref errno.h on failure.
     1219 */
     1220int async_share_in_finalize(ipc_callid_t callid, void *src, int flags)
    15091221{
    15101222        return ipc_share_in_finalize(callid, src, flags);
    15111223}
    15121224
    1513 /** Wrapper for IPC_M_SHARE_OUT calls using the async framework.
    1514  *
    1515  * @param phoneid Phone that will be used to contact the receiving side.
    1516  * @param src     Source address space area base address.
    1517  * @param flags   Flags to be used for sharing. Bits can be only cleared.
    1518  *
    1519  * @return Zero on success or a negative error code from errno.h.
    1520  *
    1521  */
    1522 int async_share_out_start(int phoneid, void *src, unsigned int flags)
     1225/** Wrapper for making IPC_M_SHARE_OUT calls using the async framework.
     1226 *
     1227 * @param phoneid       Phone that will be used to contact the receiving side.
     1228 * @param src           Source address space area base address.
     1229 * @param flags         Flags to be used for sharing. Bits can be only cleared.
     1230 *
     1231 * @return              Zero on success or a negative error code from errno.h.
     1232 */
     1233int async_share_out_start(int phoneid, void *src, int flags)
    15231234{
    15241235        return async_req_3_0(phoneid, IPC_M_SHARE_OUT, (sysarg_t) src, 0,
     
    15281239/** Wrapper for receiving the IPC_M_SHARE_OUT calls using the async framework.
    15291240 *
    1530  * This wrapper only makes it more comfortable to receive IPC_M_SHARE_OUT
    1531  * calls so that the user doesn't have to remember the meaning of each IPC
    1532  * argument.
     1241 * This wrapper only makes it more comfortable to receive IPC_M_SHARE_OUT calls
     1242 * so that the user doesn't have to remember the meaning of each IPC argument.
    15331243 *
    15341244 * So far, this wrapper is to be used from within a connection fibril.
    15351245 *
    1536  * @param callid Storage for the hash of the IPC_M_SHARE_OUT call.
    1537  * @param size   Storage for the source address space area size.
    1538  * @param flags  Storage for the sharing flags.
    1539  *
    1540  * @return True on success, false on failure.
    1541  *
    1542  */
    1543 bool async_share_out_receive(ipc_callid_t *callid, size_t *size, unsigned int *flags)
    1544 {
     1246 * @param callid        Storage where the hash of the IPC_M_SHARE_OUT call will
     1247 *                      be stored.
     1248 * @param size          Storage where the source address space area size will be
     1249 *                      stored.
     1250 * @param flags         Storage where the sharing flags will be stored.
     1251 *
     1252 * @return              Non-zero on success, zero on failure.
     1253 */
     1254int async_share_out_receive(ipc_callid_t *callid, size_t *size, int *flags)
     1255{
     1256        ipc_call_t data;
     1257       
    15451258        assert(callid);
    15461259        assert(size);
    15471260        assert(flags);
    1548        
    1549         ipc_call_t data;
     1261
    15501262        *callid = async_get_call(&data);
    1551        
    15521263        if (IPC_GET_IMETHOD(data) != IPC_M_SHARE_OUT)
    1553                 return false;
    1554        
     1264                return 0;
    15551265        *size = (size_t) IPC_GET_ARG2(data);
    1556         *flags = (unsigned int) IPC_GET_ARG3(data);
    1557         return true;
     1266        *flags = (int) IPC_GET_ARG3(data);
     1267        return 1;
    15581268}
    15591269
    15601270/** Wrapper for answering the IPC_M_SHARE_OUT calls using the async framework.
    15611271 *
    1562  * This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT
    1563  * calls so that the user doesn't have to remember the meaning of each IPC
    1564  * argument.
    1565  *
    1566  * @param callid Hash of the IPC_M_DATA_WRITE call to answer.
    1567  * @param dst    Destination address space area base address.
    1568  *
    1569  * @return Zero on success or a value from @ref errno.h on failure.
    1570  *
     1272 * This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT calls
     1273 * so that the user doesn't have to remember the meaning of each IPC argument.
     1274 *
     1275 * @param callid        Hash of the IPC_M_DATA_WRITE call to answer.
     1276 * @param dst           Destination address space area base address.   
     1277 *
     1278 * @return              Zero on success or a value from @ref errno.h on failure.
    15711279 */
    15721280int async_share_out_finalize(ipc_callid_t callid, void *dst)
     
    15751283}
    15761284
    1577 /** Wrapper for IPC_M_DATA_READ calls using the async framework.
    1578  *
    1579  * @param phoneid Phone that will be used to contact the receiving side.
    1580  * @param dst     Address of the beginning of the destination buffer.
    1581  * @param size    Size of the destination buffer.
    1582  *
    1583  * @return Zero on success or a negative error code from errno.h.
    1584  *
     1285
     1286/** Wrapper for making IPC_M_DATA_READ calls using the async framework.
     1287 *
     1288 * @param phoneid       Phone that will be used to contact the receiving side.
     1289 * @param dst           Address of the beginning of the destination buffer.
     1290 * @param size          Size of the destination buffer.
     1291 *
     1292 * @return              Zero on success or a negative error code from errno.h.
    15851293 */
    15861294int async_data_read_start(int phoneid, void *dst, size_t size)
     
    15921300/** Wrapper for receiving the IPC_M_DATA_READ calls using the async framework.
    15931301 *
    1594  * This wrapper only makes it more comfortable to receive IPC_M_DATA_READ
    1595  * calls so that the user doesn't have to remember the meaning of each IPC
    1596  * argument.
     1302 * This wrapper only makes it more comfortable to receive IPC_M_DATA_READ calls
     1303 * so that the user doesn't have to remember the meaning of each IPC argument.
    15971304 *
    15981305 * So far, this wrapper is to be used from within a connection fibril.
    15991306 *
    1600  * @param callid Storage for the hash of the IPC_M_DATA_READ.
    1601  * @param size   Storage for the maximum size. Can be NULL.
    1602  *
    1603  * @return True on success, false on failure.
    1604  *
    1605  */
    1606 bool async_data_read_receive(ipc_callid_t *callid, size_t *size)
    1607 {
     1307 * @param callid        Storage where the hash of the IPC_M_DATA_READ call will
     1308 *                      be stored.
     1309 * @param size          Storage where the maximum size will be stored. Can be
     1310 *                      NULL.
     1311 *
     1312 * @return              Non-zero on success, zero on failure.
     1313 */
     1314int async_data_read_receive(ipc_callid_t *callid, size_t *size)
     1315{
     1316        ipc_call_t data;
     1317       
    16081318        assert(callid);
    1609        
    1610         ipc_call_t data;
     1319
    16111320        *callid = async_get_call(&data);
    1612        
    16131321        if (IPC_GET_IMETHOD(data) != IPC_M_DATA_READ)
    1614                 return false;
    1615        
     1322                return 0;
    16161323        if (size)
    16171324                *size = (size_t) IPC_GET_ARG2(data);
    1618        
    1619         return true;
     1325        return 1;
    16201326}
    16211327
    16221328/** Wrapper for answering the IPC_M_DATA_READ calls using the async framework.
    16231329 *
    1624  * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ
    1625  * calls so that the user doesn't have to remember the meaning of each IPC
    1626  * argument.
    1627  *
    1628  * @param callid Hash of the IPC_M_DATA_READ call to answer.
    1629  * @param src    Source address for the IPC_M_DATA_READ call.
    1630  * @param size   Size for the IPC_M_DATA_READ call. Can be smaller than
    1631  *               the maximum size announced by the sender.
    1632  *
    1633  * @return Zero on success or a value from @ref errno.h on failure.
    1634  *
     1330 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls
     1331 * so that the user doesn't have to remember the meaning of each IPC argument.
     1332 *
     1333 * @param callid        Hash of the IPC_M_DATA_READ call to answer.
     1334 * @param src           Source address for the IPC_M_DATA_READ call.
     1335 * @param size          Size for the IPC_M_DATA_READ call. Can be smaller than
     1336 *                      the maximum size announced by the sender.
     1337 *
     1338 * @return              Zero on success or a value from @ref errno.h on failure.
    16351339 */
    16361340int async_data_read_finalize(ipc_callid_t callid, const void *src, size_t size)
     
    16401344
    16411345/** Wrapper for forwarding any read request
     1346 *
    16421347 *
    16431348 */
     
    16721377}
    16731378
    1674 /** Wrapper for IPC_M_DATA_WRITE calls using the async framework.
     1379/** Wrapper for making IPC_M_DATA_WRITE calls using the async framework.
    16751380 *
    16761381 * @param phoneid Phone that will be used to contact the receiving side.
     
    16891394/** Wrapper for receiving the IPC_M_DATA_WRITE calls using the async framework.
    16901395 *
    1691  * This wrapper only makes it more comfortable to receive IPC_M_DATA_WRITE
    1692  * calls so that the user doesn't have to remember the meaning of each IPC
    1693  * argument.
     1396 * This wrapper only makes it more comfortable to receive IPC_M_DATA_WRITE calls
     1397 * so that the user doesn't have to remember the meaning of each IPC argument.
    16941398 *
    16951399 * So far, this wrapper is to be used from within a connection fibril.
    16961400 *
    1697  * @param callid Storage for the hash of the IPC_M_DATA_WRITE.
    1698  * @param size   Storage for the suggested size. May be NULL.
    1699  *
    1700  * @return True on success, false on failure.
    1701  *
    1702  */
    1703 bool async_data_write_receive(ipc_callid_t *callid, size_t *size)
    1704 {
     1401 * @param callid Storage where the hash of the IPC_M_DATA_WRITE call will
     1402 *               be stored.
     1403 * @param size   Storage where the suggested size will be stored. May be
     1404 *               NULL
     1405 *
     1406 * @return Non-zero on success, zero on failure.
     1407 *
     1408 */
     1409int async_data_write_receive(ipc_callid_t *callid, size_t *size)
     1410{
     1411        ipc_call_t data;
     1412       
    17051413        assert(callid);
    17061414       
    1707         ipc_call_t data;
    17081415        *callid = async_get_call(&data);
    1709        
    17101416        if (IPC_GET_IMETHOD(data) != IPC_M_DATA_WRITE)
    1711                 return false;
     1417                return 0;
    17121418       
    17131419        if (size)
    17141420                *size = (size_t) IPC_GET_ARG2(data);
    17151421       
    1716         return true;
     1422        return 1;
    17171423}
    17181424
    17191425/** Wrapper for answering the IPC_M_DATA_WRITE calls using the async framework.
    17201426 *
    1721  * This wrapper only makes it more comfortable to answer IPC_M_DATA_WRITE
    1722  * calls so that the user doesn't have to remember the meaning of each IPC
    1723  * argument.
     1427 * This wrapper only makes it more comfortable to answer IPC_M_DATA_WRITE calls
     1428 * so that the user doesn't have to remember the meaning of each IPC argument.
    17241429 *
    17251430 * @param callid Hash of the IPC_M_DATA_WRITE call to answer.
     
    18171522 *
    18181523 */
    1819 void async_data_write_void(sysarg_t retval)
     1524void async_data_write_void(const int retval)
    18201525{
    18211526        ipc_callid_t callid;
     
    18251530
    18261531/** Wrapper for forwarding any data that is about to be received
     1532 *
    18271533 *
    18281534 */
Note: See TracChangeset for help on using the changeset viewer.