Ignore:
File:
1 edited

Legend:

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

    r8869f7b rc7bbf029  
    4040 * programming.
    4141 *
    42  * You should be able to write very simple multithreaded programs. The async
    43  * framework will automatically take care of most of the synchronization
    44  * problems.
     42 * You should be able to write very simple multithreaded programs, the async
     43 * framework will automatically take care of most synchronization problems.
    4544 *
    4645 * Example of use (pseudo C):
     
    5453 *   int fibril1(void *arg)
    5554 *   {
    56  *     conn = async_connect_me_to(...);
    57  *
    58  *     exch = async_exchange_begin(conn);
    59  *     c1 = async_send(exch);
    60  *     async_exchange_end(exch);
    61  *
    62  *     exch = async_exchange_begin(conn);
    63  *     c2 = async_send(exch);
    64  *     async_exchange_end(exch);
    65  *
     55 *     conn = async_connect_me_to();
     56 *     c1 = async_send(conn);
     57 *     c2 = async_send(conn);
    6658 *     async_wait_for(c1);
    6759 *     async_wait_for(c2);
     
    10294#include <futex.h>
    10395#include <fibril.h>
     96#include <stdio.h>
    10497#include <adt/hash_table.h>
    10598#include <adt/list.h>
     
    109102#include <arch/barrier.h>
    110103#include <bool.h>
     104#include <stdlib.h>
    111105#include <malloc.h>
    112 #include <mem.h>
    113 #include <stdlib.h>
    114106#include "private/async.h"
    115107
    116 #define CLIENT_HASH_TABLE_BUCKETS  32
    117 #define CONN_HASH_TABLE_BUCKETS    32
    118 
    119 /** Async framework global futex */
    120108atomic_t async_futex = FUTEX_INITIALIZER;
    121109
     
    123111atomic_t threads_in_ipc_wait = { 0 };
    124112
    125 /** Naming service session */
    126 async_sess_t *session_ns;
    127 
    128 /** Call data */
     113typedef struct {
     114        awaiter_t wdata;
     115       
     116        /** If reply was received. */
     117        bool done;
     118       
     119        /** Pointer to where the answer data is stored. */
     120        ipc_call_t *dataptr;
     121       
     122        sysarg_t retval;
     123} amsg_t;
     124
     125/**
     126 * Structures of this type are used to group information about
     127 * a call and about a message queue link.
     128 */
    129129typedef struct {
    130130        link_t link;
    131        
    132131        ipc_callid_t callid;
    133132        ipc_call_t call;
    134133} msg_t;
    135134
    136 /* Client connection data */
    137135typedef struct {
     136        sysarg_t in_task_hash;
    138137        link_t link;
    139        
    140         sysarg_t in_task_hash;
    141         atomic_t refcnt;
     138        int refcnt;
    142139        void *data;
    143140} client_t;
    144141
    145 /* Server connection data */
    146142typedef struct {
    147143        awaiter_t wdata;
     
    152148        /** Incoming client task hash. */
    153149        sysarg_t in_task_hash;
    154        
    155150        /** Incoming phone hash. */
    156151        sysarg_t in_phone_hash;
     
    175170
    176171/** Identifier of the incoming connection handled by the current fibril. */
    177 static fibril_local connection_t *fibril_connection;
     172static fibril_local connection_t *FIBRIL_connection;
    178173
    179174static void *default_client_data_constructor(void)
     
    201196}
    202197
    203 void *async_get_client_data(void)
    204 {
    205         assert(fibril_connection);
    206         return fibril_connection->client->data;
     198void *async_client_data_get(void)
     199{
     200        assert(FIBRIL_connection);
     201        return FIBRIL_connection->client->data;
    207202}
    208203
     
    220215}
    221216
     217/**
     218 * Pointer to a fibril function that will be used to handle connections.
     219 */
     220static async_client_conn_t client_connection = default_client_connection;
     221
    222222/** Default fibril function that gets called to handle interrupt notifications.
    223223 *
     
    232232}
    233233
    234 static async_client_conn_t client_connection = default_client_connection;
     234/**
     235 * Pointer to a fibril function that will be used to handle interrupt
     236 * notifications.
     237 */
    235238static async_client_conn_t interrupt_received = default_interrupt_received;
    236 
    237 /** Setter for client_connection function pointer.
    238  *
    239  * @param conn Function that will implement a new connection fibril.
    240  *
    241  */
    242 void async_set_client_connection(async_client_conn_t conn)
    243 {
    244         client_connection = conn;
    245 }
    246 
    247 /** Setter for interrupt_received function pointer.
    248  *
    249  * @param intr Function that will implement a new interrupt
    250  *             notification fibril.
    251  */
    252 void async_set_interrupt_received(async_client_conn_t intr)
    253 {
    254         interrupt_received = intr;
    255 }
    256 
    257 /** Mutex protecting inactive_exch_list and avail_phone_cv.
    258  *
    259  */
    260 static FIBRIL_MUTEX_INITIALIZE(async_sess_mutex);
    261 
    262 /** List of all currently inactive exchanges.
    263  *
    264  */
    265 static LIST_INITIALIZE(inactive_exch_list);
    266 
    267 /** Condition variable to wait for a phone to become available.
    268  *
    269  */
    270 static FIBRIL_CONDVAR_INITIALIZE(avail_phone_cv);
    271239
    272240static hash_table_t client_hash_table;
     
    274242static LIST_INITIALIZE(timeout_list);
    275243
     244#define CLIENT_HASH_TABLE_BUCKETS  32
     245#define CONN_HASH_TABLE_BUCKETS    32
     246
    276247static hash_index_t client_hash(unsigned long key[])
    277248{
    278249        assert(key);
    279        
    280250        return (((key[0]) >> 4) % CLIENT_HASH_TABLE_BUCKETS);
    281251}
     
    283253static int client_compare(unsigned long key[], hash_count_t keys, link_t *item)
    284254{
    285         assert(key);
    286         assert(item);
    287        
    288255        client_t *client = hash_table_get_instance(item, client_t, link);
    289256        return (key[0] == client->in_task_hash);
     
    311278{
    312279        assert(key);
    313        
    314280        return (((key[0]) >> 4) % CONN_HASH_TABLE_BUCKETS);
    315281}
     
    326292static int conn_compare(unsigned long key[], hash_count_t keys, link_t *item)
    327293{
    328         assert(key);
    329         assert(item);
    330        
    331294        connection_t *conn = hash_table_get_instance(item, connection_t, link);
    332295        return (key[0] == conn->in_phone_hash);
     
    351314void async_insert_timeout(awaiter_t *wd)
    352315{
    353         assert(wd);
    354        
    355316        wd->to_event.occurred = false;
    356317        wd->to_event.inlist = true;
     
    385346static bool route_call(ipc_callid_t callid, ipc_call_t *call)
    386347{
    387         assert(call);
    388        
    389348        futex_down(&async_futex);
    390349       
     
    441400static int notification_fibril(void *arg)
    442401{
    443         assert(arg);
    444        
    445402        msg_t *msg = (msg_t *) arg;
    446403        interrupt_received(msg->callid, &msg->call);
     
    463420static bool process_notification(ipc_callid_t callid, ipc_call_t *call)
    464421{
    465         assert(call);
    466        
    467422        futex_down(&async_futex);
    468423       
     
    503458ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs)
    504459{
    505         assert(call);
    506         assert(fibril_connection);
     460        assert(FIBRIL_connection);
    507461       
    508462        /* Why doing this?
    509          * GCC 4.1.0 coughs on fibril_connection-> dereference.
     463         * GCC 4.1.0 coughs on FIBRIL_connection-> dereference.
    510464         * GCC 4.1.1 happilly puts the rdhwr instruction in delay slot.
    511465         *           I would never expect to find so many errors in
    512466         *           a compiler.
    513467         */
    514         connection_t *conn = fibril_connection;
     468        connection_t *conn = FIBRIL_connection;
    515469       
    516470        futex_down(&async_futex);
     
    587541static int connection_fibril(void *arg)
    588542{
    589         assert(arg);
    590        
    591543        /*
    592544         * Setup fibril-local connection pointer.
    593545         */
    594         fibril_connection = (connection_t *) arg;
     546        FIBRIL_connection = (connection_t *) arg;
    595547       
    596548        futex_down(&async_futex);
     
    602554         */
    603555       
    604         unsigned long key = fibril_connection->in_task_hash;
     556        unsigned long key = FIBRIL_connection->in_task_hash;
    605557        link_t *lnk = hash_table_find(&client_hash_table, &key);
    606558       
     
    609561        if (lnk) {
    610562                client = hash_table_get_instance(lnk, client_t, link);
    611                 atomic_inc(&client->refcnt);
     563                client->refcnt++;
    612564        } else {
    613565                client = malloc(sizeof(client_t));
    614566                if (!client) {
    615                         ipc_answer_0(fibril_connection->callid, ENOMEM);
     567                        ipc_answer_0(FIBRIL_connection->callid, ENOMEM);
    616568                        futex_up(&async_futex);
    617569                        return 0;
    618570                }
    619571               
    620                 client->in_task_hash = fibril_connection->in_task_hash;
     572                client->in_task_hash = FIBRIL_connection->in_task_hash;
     573               
     574                async_serialize_start();
    621575                client->data = async_client_data_create();
    622                
    623                 atomic_set(&client->refcnt, 1);
     576                async_serialize_end();
     577               
     578                client->refcnt = 1;
    624579                hash_table_insert(&client_hash_table, &key, &client->link);
    625580        }
     
    627582        futex_up(&async_futex);
    628583       
    629         fibril_connection->client = client;
     584        FIBRIL_connection->client = client;
    630585       
    631586        /*
    632587         * Call the connection handler function.
    633588         */
    634         fibril_connection->cfibril(fibril_connection->callid,
    635             &fibril_connection->call);
     589        FIBRIL_connection->cfibril(FIBRIL_connection->callid,
     590            &FIBRIL_connection->call);
    636591       
    637592        /*
     
    642597        futex_down(&async_futex);
    643598       
    644         if (atomic_predec(&client->refcnt) == 0) {
     599        if (--client->refcnt == 0) {
    645600                hash_table_remove(&client_hash_table, &key, 1);
    646601                destroy = true;
     
    661616         */
    662617        futex_down(&async_futex);
    663         key = fibril_connection->in_phone_hash;
     618        key = FIBRIL_connection->in_phone_hash;
    664619        hash_table_remove(&conn_hash_table, &key, 1);
    665620        futex_up(&async_futex);
     
    668623         * Answer all remaining messages with EHANGUP.
    669624         */
    670         while (!list_empty(&fibril_connection->msg_queue)) {
     625        while (!list_empty(&FIBRIL_connection->msg_queue)) {
    671626                msg_t *msg =
    672                     list_get_instance(fibril_connection->msg_queue.next, msg_t,
     627                    list_get_instance(FIBRIL_connection->msg_queue.next, msg_t,
    673628                    link);
    674629               
     
    682637         * i.e. IPC_M_PHONE_HUNGUP.
    683638         */
    684         if (fibril_connection->close_callid)
    685                 ipc_answer_0(fibril_connection->close_callid, EOK);
    686        
    687         free(fibril_connection);
     639        if (FIBRIL_connection->close_callid)
     640                ipc_answer_0(FIBRIL_connection->close_callid, EOK);
     641       
     642        free(FIBRIL_connection);
    688643        return 0;
    689644}
     
    691646/** Create a new fibril for a new connection.
    692647 *
    693  * Create new fibril for connection, fill in connection structures and insert
     648 * Create new fibril for connection, fill in connection structures and inserts
    694649 * it into the hash table, so that later we can easily do routing of messages to
    695650 * particular fibrils.
     
    710665fid_t async_new_connection(sysarg_t in_task_hash, sysarg_t in_phone_hash,
    711666    ipc_callid_t callid, ipc_call_t *call,
    712     async_client_conn_t cfibril)
     667    void (*cfibril)(ipc_callid_t, ipc_call_t *))
    713668{
    714669        connection_t *conn = malloc(sizeof(*conn));
     
    766721static void handle_call(ipc_callid_t callid, ipc_call_t *call)
    767722{
    768         assert(call);
    769        
    770723        /* Unrouted call - take some default action */
    771724        if ((callid & IPC_CALLID_NOTIFICATION)) {
     
    925878void __async_init(void)
    926879{
    927         if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS,
    928             1, &client_hash_table_ops))
     880        if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS, 1,
     881            &client_hash_table_ops))
    929882                abort();
    930883       
    931         if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_BUCKETS,
    932             1, &conn_hash_table_ops))
     884        if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_BUCKETS, 1,
     885            &conn_hash_table_ops))
    933886                abort();
    934        
    935         session_ns = (async_sess_t *) malloc(sizeof(async_sess_t));
    936         if (session_ns == NULL)
    937                 abort();
    938        
    939         session_ns->mgmt = EXCHANGE_ATOMIC;
    940         session_ns->phone = PHONE_NS;
    941         session_ns->arg1 = 0;
    942         session_ns->arg2 = 0;
    943         session_ns->arg3 = 0;
    944        
    945         list_initialize(&session_ns->exch_list);
    946         fibril_mutex_initialize(&session_ns->mutex);
    947         atomic_set(&session_ns->refcnt, 0);
    948887}
    949888
     
    960899 *
    961900 */
    962 void reply_received(void *arg, int retval, ipc_call_t *data)
    963 {
    964         assert(arg);
    965        
     901static void reply_received(void *arg, int retval, ipc_call_t *data)
     902{
    966903        futex_down(&async_futex);
    967904       
     
    993930 * completion.
    994931 *
    995  * @param exch    Exchange for sending the message.
    996  * @param imethod Service-defined interface and method.
     932 * @param phoneid Handle of the phone that will be used for the send.
     933 * @param method  Service-defined method.
    997934 * @param arg1    Service-defined payload argument.
    998935 * @param arg2    Service-defined payload argument.
     
    1005942 *
    1006943 */
    1007 aid_t async_send_fast(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
     944aid_t async_send_fast(int phoneid, sysarg_t method, sysarg_t arg1,
    1008945    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr)
    1009946{
    1010         if (exch == NULL)
    1011                 return 0;
    1012        
    1013947        amsg_t *msg = malloc(sizeof(amsg_t));
    1014         if (msg == NULL)
     948       
     949        if (!msg)
    1015950                return 0;
    1016951       
     
    1026961        msg->wdata.active = true;
    1027962       
    1028         ipc_call_async_4(exch->phone, imethod, arg1, arg2, arg3, arg4, msg,
     963        ipc_call_async_4(phoneid, method, arg1, arg2, arg3, arg4, msg,
    1029964            reply_received, true);
    1030965       
     
    1037972 * completion.
    1038973 *
    1039  * @param exch    Exchange for sending the message.
    1040  * @param imethod Service-defined interface and method.
     974 * @param phoneid Handle of the phone that will be used for the send.
     975 * @param method  Service-defined method.
    1041976 * @param arg1    Service-defined payload argument.
    1042977 * @param arg2    Service-defined payload argument.
     
    1050985 *
    1051986 */
    1052 aid_t async_send_slow(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
     987aid_t async_send_slow(int phoneid, sysarg_t method, sysarg_t arg1,
    1053988    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
    1054989    ipc_call_t *dataptr)
    1055990{
    1056         if (exch == NULL)
    1057                 return 0;
    1058        
    1059991        amsg_t *msg = malloc(sizeof(amsg_t));
    1060992       
    1061         if (msg == NULL)
     993        if (!msg)
    1062994                return 0;
    1063995       
     
    10731005        msg->wdata.active = true;
    10741006       
    1075         ipc_call_async_5(exch->phone, imethod, arg1, arg2, arg3, arg4, arg5,
    1076             msg, reply_received, true);
     1007        ipc_call_async_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, msg,
     1008            reply_received, true);
    10771009       
    10781010        return (aid_t) msg;
     
    10881020void async_wait_for(aid_t amsgid, sysarg_t *retval)
    10891021{
    1090         assert(amsgid);
    1091        
    10921022        amsg_t *msg = (amsg_t *) amsgid;
    10931023       
     
    11261056int async_wait_timeout(aid_t amsgid, sysarg_t *retval, suseconds_t timeout)
    11271057{
    1128         assert(amsgid);
    1129        
    11301058        amsg_t *msg = (amsg_t *) amsgid;
    11311059       
     
    11961124}
    11971125
     1126/** Setter for client_connection function pointer.
     1127 *
     1128 * @param conn Function that will implement a new connection fibril.
     1129 *
     1130 */
     1131void async_set_client_connection(async_client_conn_t conn)
     1132{
     1133        client_connection = conn;
     1134}
     1135
     1136/** Setter for interrupt_received function pointer.
     1137 *
     1138 * @param intr Function that will implement a new interrupt
     1139 *             notification fibril.
     1140 */
     1141void async_set_interrupt_received(async_client_conn_t intr)
     1142{
     1143        interrupt_received = intr;
     1144}
     1145
    11981146/** Pseudo-synchronous message sending - fast version.
    11991147 *
     
    12031151 * transferring more arguments, see the slower async_req_slow().
    12041152 *
    1205  * @param exch    Exchange for sending the message.
    1206  * @param imethod Interface and method of the call.
     1153 * @param phoneid Hash of the phone through which to make the call.
     1154 * @param method  Method of the call.
    12071155 * @param arg1    Service-defined payload argument.
    12081156 * @param arg2    Service-defined payload argument.
     
    12181166 *
    12191167 */
    1220 sysarg_t async_req_fast(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
     1168sysarg_t async_req_fast(int phoneid, sysarg_t method, sysarg_t arg1,
    12211169    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t *r1, sysarg_t *r2,
    12221170    sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
    12231171{
    1224         if (exch == NULL)
    1225                 return ENOENT;
    1226        
    12271172        ipc_call_t result;
    1228         aid_t aid = async_send_4(exch, imethod, arg1, arg2, arg3, arg4,
     1173        aid_t eid = async_send_4(phoneid, method, arg1, arg2, arg3, arg4,
    12291174            &result);
    12301175       
    12311176        sysarg_t rc;
    1232         async_wait_for(aid, &rc);
     1177        async_wait_for(eid, &rc);
    12331178       
    12341179        if (r1)
     
    12541199 * Send message asynchronously and return only after the reply arrives.
    12551200 *
    1256  * @param exch    Exchange for sending the message.
    1257  * @param imethod Interface and method of the call.
     1201 * @param phoneid Hash of the phone through which to make the call.
     1202 * @param method  Method of the call.
    12581203 * @param arg1    Service-defined payload argument.
    12591204 * @param arg2    Service-defined payload argument.
     
    12701215 *
    12711216 */
    1272 sysarg_t async_req_slow(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
     1217sysarg_t async_req_slow(int phoneid, sysarg_t method, sysarg_t arg1,
    12731218    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, sysarg_t *r1,
    12741219    sysarg_t *r2, sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
    12751220{
    1276         if (exch == NULL)
    1277                 return ENOENT;
    1278        
    12791221        ipc_call_t result;
    1280         aid_t aid = async_send_5(exch, imethod, arg1, arg2, arg3, arg4, arg5,
     1222        aid_t eid = async_send_5(phoneid, method, arg1, arg2, arg3, arg4, arg5,
    12811223            &result);
    12821224       
    12831225        sysarg_t rc;
    1284         async_wait_for(aid, &rc);
     1226        async_wait_for(eid, &rc);
    12851227       
    12861228        if (r1)
     
    13021244}
    13031245
    1304 void async_msg_0(async_exch_t *exch, sysarg_t imethod)
    1305 {
    1306         if (exch != NULL)
    1307                 ipc_call_async_0(exch->phone, imethod, NULL, NULL, true);
    1308 }
    1309 
    1310 void async_msg_1(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1)
    1311 {
    1312         if (exch != NULL)
    1313                 ipc_call_async_1(exch->phone, imethod, arg1, NULL, NULL, true);
    1314 }
    1315 
    1316 void async_msg_2(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
    1317     sysarg_t arg2)
    1318 {
    1319         if (exch != NULL)
    1320                 ipc_call_async_2(exch->phone, imethod, arg1, arg2, NULL, NULL,
    1321                     true);
    1322 }
    1323 
    1324 void async_msg_3(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
    1325     sysarg_t arg2, sysarg_t arg3)
    1326 {
    1327         if (exch != NULL)
    1328                 ipc_call_async_3(exch->phone, imethod, arg1, arg2, arg3, NULL,
    1329                     NULL, true);
    1330 }
    1331 
    1332 void async_msg_4(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
    1333     sysarg_t arg2, sysarg_t arg3, sysarg_t arg4)
    1334 {
    1335         if (exch != NULL)
    1336                 ipc_call_async_4(exch->phone, imethod, arg1, arg2, arg3, arg4,
    1337                     NULL, NULL, true);
    1338 }
    1339 
    1340 void async_msg_5(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
    1341     sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5)
    1342 {
    1343         if (exch != NULL)
    1344                 ipc_call_async_5(exch->phone, imethod, arg1, arg2, arg3, arg4,
    1345                     arg5, NULL, NULL, true);
     1246void async_msg_0(int phone, sysarg_t imethod)
     1247{
     1248        ipc_call_async_0(phone, imethod, NULL, NULL, true);
     1249}
     1250
     1251void async_msg_1(int phone, sysarg_t imethod, sysarg_t arg1)
     1252{
     1253        ipc_call_async_1(phone, imethod, arg1, NULL, NULL, true);
     1254}
     1255
     1256void async_msg_2(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2)
     1257{
     1258        ipc_call_async_2(phone, imethod, arg1, arg2, NULL, NULL, true);
     1259}
     1260
     1261void async_msg_3(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
     1262    sysarg_t arg3)
     1263{
     1264        ipc_call_async_3(phone, imethod, arg1, arg2, arg3, NULL, NULL, true);
     1265}
     1266
     1267void async_msg_4(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
     1268    sysarg_t arg3, sysarg_t arg4)
     1269{
     1270        ipc_call_async_4(phone, imethod, arg1, arg2, arg3, arg4, NULL, NULL,
     1271            true);
     1272}
     1273
     1274void async_msg_5(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
     1275    sysarg_t arg3, sysarg_t arg4, sysarg_t arg5)
     1276{
     1277        ipc_call_async_5(phone, imethod, arg1, arg2, arg3, arg4, arg5, NULL,
     1278            NULL, true);
    13461279}
    13471280
     
    13801313}
    13811314
    1382 int async_forward_fast(ipc_callid_t callid, async_exch_t *exch,
    1383     sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, unsigned int mode)
    1384 {
    1385         if (exch == NULL)
    1386                 return ENOENT;
    1387        
    1388         return ipc_forward_fast(callid, exch->phone, imethod, arg1, arg2, mode);
    1389 }
    1390 
    1391 int async_forward_slow(ipc_callid_t callid, async_exch_t *exch,
    1392     sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
    1393     sysarg_t arg4, sysarg_t arg5, unsigned int mode)
    1394 {
    1395         if (exch == NULL)
    1396                 return ENOENT;
    1397        
    1398         return ipc_forward_slow(callid, exch->phone, imethod, arg1, arg2, arg3,
    1399             arg4, arg5, mode);
     1315int async_forward_fast(ipc_callid_t callid, int phoneid, sysarg_t imethod,
     1316    sysarg_t arg1, sysarg_t arg2, unsigned int mode)
     1317{
     1318        return ipc_forward_fast(callid, phoneid, imethod, arg1, arg2, mode);
     1319}
     1320
     1321int async_forward_slow(ipc_callid_t callid, int phoneid, sysarg_t imethod,
     1322    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
     1323    unsigned int mode)
     1324{
     1325        return ipc_forward_slow(callid, phoneid, imethod, arg1, arg2, arg3, arg4,
     1326            arg5, mode);
    14001327}
    14011328
     
    14041331 * Ask through phone for a new connection to some service.
    14051332 *
    1406  * @param exch            Exchange for sending the message.
     1333 * @param phone           Phone handle used for contacting the other side.
    14071334 * @param arg1            User defined argument.
    14081335 * @param arg2            User defined argument.
     
    14101337 * @param client_receiver Connection handing routine.
    14111338 *
    1412  * @return Zero on success or a negative error code.
    1413  *
    1414  */
    1415 int async_connect_to_me(async_exch_t *exch, sysarg_t arg1, sysarg_t arg2,
     1339 * @return New phone handle on success or a negative error code.
     1340 *
     1341 */
     1342int async_connect_to_me(int phone, sysarg_t arg1, sysarg_t arg2,
    14161343    sysarg_t arg3, async_client_conn_t client_receiver)
    14171344{
    1418         if (exch == NULL)
    1419                 return ENOENT;
    1420        
    14211345        sysarg_t task_hash;
    14221346        sysarg_t phone_hash;
    1423         int rc = async_req_3_5(exch, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,
     1347        int rc = async_req_3_5(phone, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,
    14241348            NULL, NULL, NULL, &task_hash, &phone_hash);
    14251349        if (rc != EOK)
     
    14331357}
    14341358
    1435 /** Wrapper for making IPC_M_CONNECT_ME calls using the async framework.
    1436  *
    1437  * Ask through for a cloned connection to some service.
    1438  *
    1439  * @param mgmt Exchange management style.
    1440  * @param exch Exchange for sending the message.
    1441  *
    1442  * @return New session on success or NULL on error.
    1443  *
    1444  */
    1445 async_sess_t *async_connect_me(exch_mgmt_t mgmt, async_exch_t *exch)
    1446 {
    1447         if (exch == NULL) {
    1448                 errno = ENOENT;
    1449                 return NULL;
    1450         }
    1451        
    1452         async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
    1453         if (sess == NULL) {
    1454                 errno = ENOMEM;
    1455                 return NULL;
    1456         }
    1457        
    1458         ipc_call_t result;
    1459        
    1460         amsg_t *msg = malloc(sizeof(amsg_t));
    1461         if (msg == NULL) {
    1462                 free(sess);
    1463                 errno = ENOMEM;
    1464                 return NULL;
    1465         }
    1466        
    1467         msg->done = false;
    1468         msg->dataptr = &result;
    1469        
    1470         msg->wdata.to_event.inlist = false;
    1471        
    1472         /*
    1473          * We may sleep in the next method,
    1474          * but it will use its own means
    1475          */
    1476         msg->wdata.active = true;
    1477        
    1478         ipc_call_async_0(exch->phone, IPC_M_CONNECT_ME, msg,
    1479             reply_received, true);
    1480        
    1481         sysarg_t rc;
    1482         async_wait_for((aid_t) msg, &rc);
    1483        
    1484         if (rc != EOK) {
    1485                 errno = rc;
    1486                 free(sess);
    1487                 return NULL;
    1488         }
    1489        
    1490         int phone = (int) IPC_GET_ARG5(result);
    1491        
    1492         if (phone < 0) {
    1493                 errno = phone;
    1494                 free(sess);
    1495                 return NULL;
    1496         }
    1497        
    1498         sess->mgmt = mgmt;
    1499         sess->phone = phone;
    1500         sess->arg1 = 0;
    1501         sess->arg2 = 0;
    1502         sess->arg3 = 0;
    1503        
    1504         list_initialize(&sess->exch_list);
    1505         fibril_mutex_initialize(&sess->mutex);
    1506         atomic_set(&sess->refcnt, 0);
    1507        
    1508         return sess;
    1509 }
    1510 
    1511 static int async_connect_me_to_internal(int phone, sysarg_t arg1, sysarg_t arg2,
    1512     sysarg_t arg3, sysarg_t arg4)
    1513 {
    1514         ipc_call_t result;
    1515        
    1516         amsg_t *msg = malloc(sizeof(amsg_t));
    1517         if (msg == NULL)
    1518                 return ENOENT;
    1519        
    1520         msg->done = false;
    1521         msg->dataptr = &result;
    1522        
    1523         msg->wdata.to_event.inlist = false;
    1524        
    1525         /*
    1526          * We may sleep in the next method,
    1527          * but it will use its own means
    1528          */
    1529         msg->wdata.active = true;
    1530        
    1531         ipc_call_async_4(phone, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, arg4,
    1532             msg, reply_received, true);
    1533        
    1534         sysarg_t rc;
    1535         async_wait_for((aid_t) msg, &rc);
     1359/** Wrapper for making IPC_M_CONNECT_ME_TO calls using the async framework.
     1360 *
     1361 * Ask through phone for a new connection to some service.
     1362 *
     1363 * @param phone Phone handle used for contacting the other side.
     1364 * @param arg1  User defined argument.
     1365 * @param arg2  User defined argument.
     1366 * @param arg3  User defined argument.
     1367 *
     1368 * @return New phone handle on success or a negative error code.
     1369 *
     1370 */
     1371int async_connect_me_to(int phone, sysarg_t arg1, sysarg_t arg2,
     1372    sysarg_t arg3)
     1373{
     1374        sysarg_t newphid;
     1375        int rc = async_req_3_5(phone, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
     1376            NULL, NULL, NULL, NULL, &newphid);
    15361377       
    15371378        if (rc != EOK)
    15381379                return rc;
    15391380       
    1540         return (int) IPC_GET_ARG5(result);
    1541 }
    1542 
    1543 /** Wrapper for making IPC_M_CONNECT_ME_TO calls using the async framework.
    1544  *
    1545  * Ask through for a new connection to some service.
    1546  *
    1547  * @param mgmt Exchange management style.
    1548  * @param exch Exchange for sending the message.
    1549  * @param arg1 User defined argument.
    1550  * @param arg2 User defined argument.
    1551  * @param arg3 User defined argument.
    1552  *
    1553  * @return New session on success or NULL on error.
    1554  *
    1555  */
    1556 async_sess_t *async_connect_me_to(exch_mgmt_t mgmt, async_exch_t *exch,
    1557     sysarg_t arg1, sysarg_t arg2, sysarg_t arg3)
    1558 {
    1559         if (exch == NULL) {
    1560                 errno = ENOENT;
    1561                 return NULL;
    1562         }
    1563        
    1564         async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
    1565         if (sess == NULL) {
    1566                 errno = ENOMEM;
    1567                 return NULL;
    1568         }
    1569        
    1570         int phone = async_connect_me_to_internal(exch->phone, arg1, arg2, arg3,
    1571             0);
    1572        
    1573         if (phone < 0) {
    1574                 errno = phone;
    1575                 free(sess);
    1576                 return NULL;
    1577         }
    1578        
    1579         sess->mgmt = mgmt;
    1580         sess->phone = phone;
    1581         sess->arg1 = arg1;
    1582         sess->arg2 = arg2;
    1583         sess->arg3 = arg3;
    1584        
    1585         list_initialize(&sess->exch_list);
    1586         fibril_mutex_initialize(&sess->mutex);
    1587         atomic_set(&sess->refcnt, 0);
    1588        
    1589         return sess;
     1381        return newphid;
    15901382}
    15911383
     
    15951387 * success.
    15961388 *
    1597  * @param mgmt Exchange management style.
    1598  * @param exch Exchange for sending the message.
    1599  * @param arg1 User defined argument.
    1600  * @param arg2 User defined argument.
    1601  * @param arg3 User defined argument.
    1602  *
    1603  * @return New session on success or NULL on error.
    1604  *
    1605  */
    1606 async_sess_t *async_connect_me_to_blocking(exch_mgmt_t mgmt, async_exch_t *exch,
    1607     sysarg_t arg1, sysarg_t arg2, sysarg_t arg3)
    1608 {
    1609         if (exch == NULL) {
    1610                 errno = ENOENT;
    1611                 return NULL;
    1612         }
    1613        
    1614         async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
    1615         if (sess == NULL) {
    1616                 errno = ENOMEM;
    1617                 return NULL;
    1618         }
    1619        
    1620         int phone = async_connect_me_to_internal(exch->phone, arg1, arg2, arg3,
    1621             IPC_FLAG_BLOCKING);
    1622        
    1623         if (phone < 0) {
    1624                 errno = phone;
    1625                 free(sess);
    1626                 return NULL;
    1627         }
    1628        
    1629         sess->mgmt = mgmt;
    1630         sess->phone = phone;
    1631         sess->arg1 = arg1;
    1632         sess->arg2 = arg2;
    1633         sess->arg3 = arg3;
    1634        
    1635         list_initialize(&sess->exch_list);
    1636         fibril_mutex_initialize(&sess->mutex);
    1637         atomic_set(&sess->refcnt, 0);
    1638        
    1639         return sess;
     1389 * @param phoneid Phone handle used for contacting the other side.
     1390 * @param arg1    User defined argument.
     1391 * @param arg2    User defined argument.
     1392 * @param arg3    User defined argument.
     1393 *
     1394 * @return New phone handle on success or a negative error code.
     1395 *
     1396 */
     1397int async_connect_me_to_blocking(int phoneid, sysarg_t arg1, sysarg_t arg2,
     1398    sysarg_t arg3)
     1399{
     1400        sysarg_t newphid;
     1401        int rc = async_req_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
     1402            IPC_FLAG_BLOCKING, NULL, NULL, NULL, NULL, &newphid);
     1403       
     1404        if (rc != EOK)
     1405                return rc;
     1406       
     1407        return newphid;
    16401408}
    16411409
     
    16431411 *
    16441412 */
    1645 async_sess_t *async_connect_kbox(task_id_t id)
    1646 {
    1647         async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
    1648         if (sess == NULL) {
    1649                 errno = ENOMEM;
    1650                 return NULL;
    1651         }
    1652        
    1653         int phone = ipc_connect_kbox(id);
    1654         if (phone < 0) {
    1655                 errno = phone;
    1656                 free(sess);
    1657                 return NULL;
    1658         }
    1659        
    1660         sess->mgmt = EXCHANGE_ATOMIC;
    1661         sess->phone = phone;
    1662         sess->arg1 = 0;
    1663         sess->arg2 = 0;
    1664         sess->arg3 = 0;
    1665        
    1666         list_initialize(&sess->exch_list);
    1667         fibril_mutex_initialize(&sess->mutex);
    1668         atomic_set(&sess->refcnt, 0);
    1669        
    1670         return sess;
    1671 }
    1672 
    1673 static int async_hangup_internal(int phone)
     1413int async_connect_kbox(task_id_t id)
     1414{
     1415        return ipc_connect_kbox(id);
     1416}
     1417
     1418/** Wrapper for ipc_hangup.
     1419 *
     1420 * @param phone Phone handle to hung up.
     1421 *
     1422 * @return Zero on success or a negative error code.
     1423 *
     1424 */
     1425int async_hangup(int phone)
    16741426{
    16751427        return ipc_hangup(phone);
    1676 }
    1677 
    1678 /** Wrapper for ipc_hangup.
    1679  *
    1680  * @param sess Session to hung up.
    1681  *
    1682  * @return Zero on success or a negative error code.
    1683  *
    1684  */
    1685 int async_hangup(async_sess_t *sess)
    1686 {
    1687         assert(sess);
    1688        
    1689         if (atomic_get(&sess->refcnt) > 0)
    1690                 return EBUSY;
    1691        
    1692         int rc = async_hangup_internal(sess->phone);
    1693         if (rc == EOK)
    1694                 free(sess);
    1695        
    1696         return rc;
    16971428}
    16981429
     
    17031434}
    17041435
    1705 /** Start new exchange in a session.
    1706  *
    1707  * @param session Session.
    1708  *
    1709  * @return New exchange or NULL on error.
    1710  *
    1711  */
    1712 async_exch_t *async_exchange_begin(async_sess_t *sess)
    1713 {
    1714         if (sess == NULL)
    1715                 return NULL;
    1716        
    1717         async_exch_t *exch;
    1718        
    1719         fibril_mutex_lock(&async_sess_mutex);
    1720        
    1721         if (!list_empty(&sess->exch_list)) {
    1722                 /*
    1723                  * There are inactive exchanges in the session.
    1724                  */
    1725                 exch = (async_exch_t *)
    1726                     list_get_instance(sess->exch_list.next, async_exch_t, sess_link);
    1727                 list_remove(&exch->sess_link);
    1728                 list_remove(&exch->global_link);
    1729         } else {
    1730                 /*
    1731                  * There are no available exchanges in the session.
    1732                  */
    1733                
    1734                 if ((sess->mgmt == EXCHANGE_ATOMIC) ||
    1735                     (sess->mgmt == EXCHANGE_SERIALIZE)) {
    1736                         exch = (async_exch_t *) malloc(sizeof(async_exch_t));
    1737                         if (exch != NULL) {
    1738                                 list_initialize(&exch->sess_link);
    1739                                 list_initialize(&exch->global_link);
    1740                                 exch->sess = sess;
    1741                                 exch->phone = sess->phone;
    1742                         }
    1743                 } else {  /* EXCHANGE_PARALLEL */
    1744                         /*
    1745                          * Make a one-time attempt to connect a new data phone.
    1746                          */
    1747                        
    1748                         int phone;
    1749                        
    1750 retry:
    1751                         phone = async_connect_me_to_internal(sess->phone, sess->arg1,
    1752                             sess->arg2, sess->arg3, 0);
    1753                         if (phone >= 0) {
    1754                                 exch = (async_exch_t *) malloc(sizeof(async_exch_t));
    1755                                 if (exch != NULL) {
    1756                                         list_initialize(&exch->sess_link);
    1757                                         list_initialize(&exch->global_link);
    1758                                         exch->sess = sess;
    1759                                         exch->phone = phone;
    1760                                 } else
    1761                                         async_hangup_internal(phone);
    1762                         } else if (!list_empty(&inactive_exch_list)) {
    1763                                 /*
    1764                                  * We did not manage to connect a new phone. But we
    1765                                  * can try to close some of the currently inactive
    1766                                  * connections in other sessions and try again.
    1767                                  */
    1768                                 exch = (async_exch_t *)
    1769                                     list_get_instance(inactive_exch_list.next, async_exch_t,
    1770                                     global_link);
    1771                                 list_remove(&exch->sess_link);
    1772                                 list_remove(&exch->global_link);
    1773                                 async_hangup_internal(exch->phone);
    1774                                 free(exch);
    1775                                 goto retry;
    1776                         } else {
    1777                                 /*
    1778                                  * Wait for a phone to become available.
    1779                                  */
    1780                                 fibril_condvar_wait(&avail_phone_cv, &async_sess_mutex);
    1781                                 goto retry;
    1782                         }
    1783                 }
    1784         }
    1785        
    1786         fibril_mutex_unlock(&async_sess_mutex);
    1787        
    1788         if (exch != NULL) {
    1789                 atomic_inc(&sess->refcnt);
    1790                
    1791                 if (sess->mgmt == EXCHANGE_SERIALIZE)
    1792                         fibril_mutex_lock(&sess->mutex);
    1793         }
    1794        
    1795         return exch;
    1796 }
    1797 
    1798 /** Finish an exchange.
    1799  *
    1800  * @param exch Exchange to finish.
    1801  *
    1802  */
    1803 void async_exchange_end(async_exch_t *exch)
    1804 {
    1805         if (exch == NULL)
    1806                 return;
    1807        
    1808         async_sess_t *sess = exch->sess;
    1809        
    1810         if (sess->mgmt == EXCHANGE_SERIALIZE)
    1811                 fibril_mutex_unlock(&sess->mutex);
    1812        
    1813         fibril_mutex_lock(&async_sess_mutex);
    1814        
    1815         list_append(&exch->sess_link, &sess->exch_list);
    1816         list_append(&exch->global_link, &inactive_exch_list);
    1817         fibril_condvar_signal(&avail_phone_cv);
    1818        
    1819         fibril_mutex_unlock(&async_sess_mutex);
    1820 }
    1821 
    18221436/** Wrapper for IPC_M_SHARE_IN calls using the async framework.
    18231437 *
    1824  * @param exch  Exchange for sending the message.
    1825  * @param dst   Destination address space area base.
    1826  * @param size  Size of the destination address space area.
    1827  * @param arg   User defined argument.
    1828  * @param flags Storage for the received flags. Can be NULL.
     1438 * @param phoneid Phone that will be used to contact the receiving side.
     1439 * @param dst     Destination address space area base.
     1440 * @param size    Size of the destination address space area.
     1441 * @param arg     User defined argument.
     1442 * @param flags   Storage for the received flags. Can be NULL.
    18291443 *
    18301444 * @return Zero on success or a negative error code from errno.h.
    18311445 *
    18321446 */
    1833 int async_share_in_start(async_exch_t *exch, void *dst, size_t size,
    1834     sysarg_t arg, unsigned int *flags)
    1835 {
    1836         if (exch == NULL)
    1837                 return ENOENT;
    1838        
     1447int async_share_in_start(int phoneid, void *dst, size_t size, sysarg_t arg,
     1448    unsigned int *flags)
     1449{
    18391450        sysarg_t tmp_flags;
    1840         int res = async_req_3_2(exch, IPC_M_SHARE_IN, (sysarg_t) dst,
     1451        int res = async_req_3_2(phoneid, IPC_M_SHARE_IN, (sysarg_t) dst,
    18411452            (sysarg_t) size, arg, NULL, &tmp_flags);
    18421453       
     
    18961507/** Wrapper for IPC_M_SHARE_OUT calls using the async framework.
    18971508 *
    1898  * @param exch  Exchange for sending the message.
    1899  * @param src   Source address space area base address.
    1900  * @param flags Flags to be used for sharing. Bits can be only cleared.
     1509 * @param phoneid Phone that will be used to contact the receiving side.
     1510 * @param src     Source address space area base address.
     1511 * @param flags   Flags to be used for sharing. Bits can be only cleared.
    19011512 *
    19021513 * @return Zero on success or a negative error code from errno.h.
    19031514 *
    19041515 */
    1905 int async_share_out_start(async_exch_t *exch, void *src, unsigned int flags)
    1906 {
    1907         if (exch == NULL)
    1908                 return ENOENT;
    1909        
    1910         return async_req_3_0(exch, IPC_M_SHARE_OUT, (sysarg_t) src, 0,
     1516int async_share_out_start(int phoneid, void *src, unsigned int flags)
     1517{
     1518        return async_req_3_0(phoneid, IPC_M_SHARE_OUT, (sysarg_t) src, 0,
    19111519            (sysarg_t) flags);
    19121520}
     
    19611569}
    19621570
    1963 /** Start IPC_M_DATA_READ using the async framework.
    1964  *
    1965  * @param exch    Exchange for sending the message.
     1571/** Wrapper for IPC_M_DATA_READ calls using the async framework.
     1572 *
     1573 * @param phoneid Phone that will be used to contact the receiving side.
    19661574 * @param dst     Address of the beginning of the destination buffer.
    1967  * @param size    Size of the destination buffer (in bytes).
    1968  * @param dataptr Storage of call data (arg 2 holds actual data size).
    1969  *
    1970  * @return Hash of the sent message or 0 on error.
    1971  *
    1972  */
    1973 aid_t async_data_read(async_exch_t *exch, void *dst, size_t size,
    1974     ipc_call_t *dataptr)
    1975 {
    1976         return async_send_2(exch, IPC_M_DATA_READ, (sysarg_t) dst,
    1977             (sysarg_t) size, dataptr);
    1978 }
    1979 
    1980 /** Wrapper for IPC_M_DATA_READ calls using the async framework.
    1981  *
    1982  * @param exch Exchange for sending the message.
    1983  * @param dst  Address of the beginning of the destination buffer.
    1984  * @param size Size of the destination buffer.
     1575 * @param size    Size of the destination buffer.
     1576 * @param flags   Flags to control the data transfer.
    19851577 *
    19861578 * @return Zero on success or a negative error code from errno.h.
    19871579 *
    19881580 */
    1989 int async_data_read_start(async_exch_t *exch, void *dst, size_t size)
    1990 {
    1991         if (exch == NULL)
    1992                 return ENOENT;
    1993        
    1994         return async_req_2_0(exch, IPC_M_DATA_READ, (sysarg_t) dst,
    1995             (sysarg_t) size);
     1581int
     1582async_data_read_start_generic(int phoneid, void *dst, size_t size, int flags)
     1583{
     1584        return async_req_3_0(phoneid, IPC_M_DATA_READ, (sysarg_t) dst,
     1585            (sysarg_t) size, (sysarg_t) flags);
    19961586}
    19971587
     
    20481638 *
    20491639 */
    2050 int async_data_read_forward_fast(async_exch_t *exch, sysarg_t imethod,
    2051     sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4,
    2052     ipc_call_t *dataptr)
    2053 {
    2054         if (exch == NULL)
    2055                 return ENOENT;
    2056        
     1640int async_data_read_forward_fast(int phoneid, sysarg_t method, sysarg_t arg1,
     1641    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr)
     1642{
    20571643        ipc_callid_t callid;
    20581644        if (!async_data_read_receive(&callid, NULL)) {
     
    20611647        }
    20621648       
    2063         aid_t msg = async_send_fast(exch, imethod, arg1, arg2, arg3, arg4,
     1649        aid_t msg = async_send_fast(phoneid, method, arg1, arg2, arg3, arg4,
    20641650            dataptr);
    20651651        if (msg == 0) {
     
    20681654        }
    20691655       
    2070         int retval = ipc_forward_fast(callid, exch->phone, 0, 0, 0,
     1656        int retval = ipc_forward_fast(callid, phoneid, 0, 0, 0,
    20711657            IPC_FF_ROUTE_FROM_ME);
    20721658        if (retval != EOK) {
     
    20841670/** Wrapper for IPC_M_DATA_WRITE calls using the async framework.
    20851671 *
    2086  * @param exch Exchange for sending the message.
    2087  * @param src  Address of the beginning of the source buffer.
    2088  * @param size Size of the source buffer.
     1672 * @param phoneid Phone that will be used to contact the receiving side.
     1673 * @param src     Address of the beginning of the source buffer.
     1674 * @param size    Size of the source buffer.
     1675 * @param flags   Flags to control the data transfer.
    20891676 *
    20901677 * @return Zero on success or a negative error code from errno.h.
    20911678 *
    20921679 */
    2093 int async_data_write_start(async_exch_t *exch, const void *src, size_t size)
    2094 {
    2095         if (exch == NULL)
    2096                 return ENOENT;
    2097        
    2098         return async_req_2_0(exch, IPC_M_DATA_WRITE, (sysarg_t) src,
    2099             (sysarg_t) size);
     1680int
     1681async_data_write_start_generic(int phoneid, const void *src, size_t size,
     1682    int flags)
     1683{
     1684        return async_req_3_0(phoneid, IPC_M_DATA_WRITE, (sysarg_t) src,
     1685            (sysarg_t) size, (sysarg_t) flags);
    21001686}
    21011687
     
    21731759    size_t *received)
    21741760{
    2175         assert(data);
    2176        
    21771761        ipc_callid_t callid;
    21781762        size_t size;
     
    22421826 *
    22431827 */
    2244 int async_data_write_forward_fast(async_exch_t *exch, sysarg_t imethod,
    2245     sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4,
    2246     ipc_call_t *dataptr)
    2247 {
    2248         if (exch == NULL)
    2249                 return ENOENT;
    2250        
     1828int async_data_write_forward_fast(int phoneid, sysarg_t method, sysarg_t arg1,
     1829    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr)
     1830{
    22511831        ipc_callid_t callid;
    22521832        if (!async_data_write_receive(&callid, NULL)) {
     
    22551835        }
    22561836       
    2257         aid_t msg = async_send_fast(exch, imethod, arg1, arg2, arg3, arg4,
     1837        aid_t msg = async_send_fast(phoneid, method, arg1, arg2, arg3, arg4,
    22581838            dataptr);
    22591839        if (msg == 0) {
     
    22621842        }
    22631843       
    2264         int retval = ipc_forward_fast(callid, exch->phone, 0, 0, 0,
     1844        int retval = ipc_forward_fast(callid, phoneid, 0, 0, 0,
    22651845            IPC_FF_ROUTE_FROM_ME);
    22661846        if (retval != EOK) {
     
    22761856}
    22771857
    2278 /** Wrapper for sending an exchange over different exchange for cloning
    2279  *
    2280  * @param exch       Exchange to be used for sending.
    2281  * @param clone_exch Exchange to be cloned.
    2282  *
    2283  */
    2284 int async_exchange_clone(async_exch_t *exch, async_exch_t *clone_exch)
    2285 {
    2286         return async_req_1_0(exch, IPC_M_CONNECTION_CLONE, clone_exch->phone);
    2287 }
    2288 
    2289 /** Wrapper for receiving the IPC_M_CONNECTION_CLONE calls.
    2290  *
    2291  * If the current call is IPC_M_CONNECTION_CLONE then a new
    2292  * async session is created for the accepted phone.
    2293  *
    2294  * @param mgmt Exchange management style.
    2295  *
    2296  * @return New async session or NULL on failure.
    2297  *
    2298  */
    2299 async_sess_t *async_clone_receive(exch_mgmt_t mgmt)
    2300 {
    2301         /* Accept the phone */
    2302         ipc_call_t call;
    2303         ipc_callid_t callid = async_get_call(&call);
    2304         int phone = (int) IPC_GET_ARG1(call);
    2305        
    2306         if ((IPC_GET_IMETHOD(call) != IPC_M_CONNECTION_CLONE) ||
    2307             (phone < 0)) {
    2308                 async_answer_0(callid, EINVAL);
    2309                 return NULL;
    2310         }
    2311        
    2312         async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
    2313         if (sess == NULL) {
    2314                 async_answer_0(callid, ENOMEM);
    2315                 return NULL;
    2316         }
    2317        
    2318         sess->mgmt = mgmt;
    2319         sess->phone = phone;
    2320         sess->arg1 = 0;
    2321         sess->arg2 = 0;
    2322         sess->arg3 = 0;
    2323        
    2324         list_initialize(&sess->exch_list);
    2325         fibril_mutex_initialize(&sess->mutex);
    2326         atomic_set(&sess->refcnt, 0);
    2327        
    2328         /* Acknowledge the cloned phone */
    2329         async_answer_0(callid, EOK);
    2330        
    2331         return sess;
    2332 }
    2333 
    2334 /** Wrapper for receiving the IPC_M_CONNECT_TO_ME calls.
    2335  *
    2336  * If the current call is IPC_M_CONNECT_TO_ME then a new
    2337  * async session is created for the accepted phone.
    2338  *
    2339  * @param mgmt Exchange management style.
    2340  *
    2341  * @return New async session.
    2342  * @return NULL on failure.
    2343  *
    2344  */
    2345 async_sess_t *async_callback_receive(exch_mgmt_t mgmt)
    2346 {
    2347         /* Accept the phone */
    2348         ipc_call_t call;
    2349         ipc_callid_t callid = async_get_call(&call);
    2350         int phone = (int) IPC_GET_ARG5(call);
    2351        
    2352         if ((IPC_GET_IMETHOD(call) != IPC_M_CONNECT_TO_ME) ||
    2353             (phone < 0)) {
    2354                 async_answer_0(callid, EINVAL);
    2355                 return NULL;
    2356         }
    2357        
    2358         async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
    2359         if (sess == NULL) {
    2360                 async_answer_0(callid, ENOMEM);
    2361                 return NULL;
    2362         }
    2363        
    2364         sess->mgmt = mgmt;
    2365         sess->phone = phone;
    2366         sess->arg1 = 0;
    2367         sess->arg2 = 0;
    2368         sess->arg3 = 0;
    2369        
    2370         list_initialize(&sess->exch_list);
    2371         fibril_mutex_initialize(&sess->mutex);
    2372         atomic_set(&sess->refcnt, 0);
    2373        
    2374         /* Acknowledge the connected phone */
    2375         async_answer_0(callid, EOK);
    2376        
    2377         return sess;
    2378 }
    2379 
    2380 /** Wrapper for receiving the IPC_M_CONNECT_TO_ME calls.
    2381  *
    2382  * If the call is IPC_M_CONNECT_TO_ME then a new
    2383  * async session is created. However, the phone is
    2384  * not accepted automatically.
    2385  *
    2386  * @param mgmt   Exchange management style.
    2387  * @param call   Call data.
    2388  *
    2389  * @return New async session.
    2390  * @return NULL on failure.
    2391  * @return NULL if the call is not IPC_M_CONNECT_TO_ME.
    2392  *
    2393  */
    2394 async_sess_t *async_callback_receive_start(exch_mgmt_t mgmt, ipc_call_t *call)
    2395 {
    2396         int phone = (int) IPC_GET_ARG5(*call);
    2397        
    2398         if ((IPC_GET_IMETHOD(*call) != IPC_M_CONNECT_TO_ME) ||
    2399             (phone < 0))
    2400                 return NULL;
    2401        
    2402         async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
    2403         if (sess == NULL)
    2404                 return NULL;
    2405        
    2406         sess->mgmt = mgmt;
    2407         sess->phone = phone;
    2408         sess->arg1 = 0;
    2409         sess->arg2 = 0;
    2410         sess->arg3 = 0;
    2411        
    2412         list_initialize(&sess->exch_list);
    2413         fibril_mutex_initialize(&sess->mutex);
    2414         atomic_set(&sess->refcnt, 0);
    2415        
    2416         return sess;
    2417 }
    2418 
    24191858/** @}
    24201859 */
Note: See TracChangeset for help on using the changeset viewer.