Ignore:
File:
1 edited

Legend:

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

    r649f087 rc0699467  
    112112#include <mem.h>
    113113#include <stdlib.h>
    114 #include <macros.h>
    115114#include "private/async.h"
    116115
     
    139138        link_t link;
    140139       
    141         task_id_t in_task_id;
     140        sysarg_t in_task_hash;
    142141        atomic_t refcnt;
    143142        void *data;
     
    151150        link_t link;
    152151       
    153         /** Incoming client task ID. */
    154         task_id_t in_task_id;
     152        /** Incoming client task hash. */
     153        sysarg_t in_task_hash;
    155154       
    156155        /** Incoming phone hash. */
     
    204203}
    205204
     205void *async_get_client_data(void)
     206{
     207        assert(fibril_connection);
     208        return fibril_connection->client->data;
     209}
     210
    206211/** Default fibril function that gets called to handle new connection.
    207212 *
     
    284289{
    285290        assert(key);
    286         assert(keys == 2);
    287291        assert(item);
    288292       
    289293        client_t *client = hash_table_get_instance(item, client_t, link);
    290         return (key[0] == LOWER32(client->in_task_id) &&
    291             (key[1] == UPPER32(client->in_task_id)));
     294        return (key[0] == client->in_task_hash);
    292295}
    293296
     
    577580}
    578581
    579 static client_t *async_client_get(task_id_t client_id, bool create)
    580 {
    581         unsigned long key[2] = {
    582                 LOWER32(client_id),
    583                 UPPER32(client_id),
    584         };
    585         client_t *client = NULL;
    586 
    587         futex_down(&async_futex);
    588         link_t *lnk = hash_table_find(&client_hash_table, key);
    589         if (lnk) {
    590                 client = hash_table_get_instance(lnk, client_t, link);
    591                 atomic_inc(&client->refcnt);
    592         } else if (create) {
    593                 client = malloc(sizeof(client_t));
    594                 if (client) {
    595                         client->in_task_id = client_id;
    596                         client->data = async_client_data_create();
    597                
    598                         atomic_set(&client->refcnt, 1);
    599                         hash_table_insert(&client_hash_table, key, &client->link);
    600                 }
    601         }
    602 
    603         futex_up(&async_futex);
    604         return client;
    605 }
    606 
    607 static void async_client_put(client_t *client)
    608 {
    609         bool destroy;
    610         unsigned long key[2] = {
    611                 LOWER32(client->in_task_id),
    612                 UPPER32(client->in_task_id)
    613         };
    614        
    615         futex_down(&async_futex);
    616        
    617         if (atomic_predec(&client->refcnt) == 0) {
    618                 hash_table_remove(&client_hash_table, key, 2);
    619                 destroy = true;
    620         } else
    621                 destroy = false;
    622        
    623         futex_up(&async_futex);
    624        
    625         if (destroy) {
    626                 if (client->data)
    627                         async_client_data_destroy(client->data);
    628                
    629                 free(client);
    630         }
    631 }
    632 
    633 void *async_get_client_data(void)
    634 {
    635         assert(fibril_connection);
    636         return fibril_connection->client->data;
    637 }
    638 
    639 void *async_get_client_data_by_id(task_id_t client_id)
    640 {
    641         client_t *client = async_client_get(client_id, false);
    642         if (!client)
    643                 return NULL;
    644         if (!client->data) {
    645                 async_client_put(client);
    646                 return NULL;
    647         }
    648 
    649         return client->data;
    650 }
    651 
    652 void async_put_client_data_by_id(task_id_t client_id)
    653 {
    654         client_t *client = async_client_get(client_id, false);
    655 
    656         assert(client);
    657         assert(client->data);
    658 
    659         /* Drop the reference we got in async_get_client_data_by_hash(). */
    660         async_client_put(client);
    661 
    662         /* Drop our own reference we got at the beginning of this function. */
    663         async_client_put(client);
    664 }
    665 
    666582/** Wrapper for client connection fibril.
    667583 *
     
    682598         */
    683599        fibril_connection = (connection_t *) arg;
     600       
     601        futex_down(&async_futex);
    684602       
    685603        /*
     
    688606         * hash in a new tracking structure.
    689607         */
    690 
    691         client_t *client = async_client_get(fibril_connection->in_task_id, true);
    692         if (!client) {
    693                 ipc_answer_0(fibril_connection->callid, ENOMEM);
    694                 return 0;
    695         }
    696 
     608       
     609        unsigned long key = fibril_connection->in_task_hash;
     610        link_t *lnk = hash_table_find(&client_hash_table, &key);
     611       
     612        client_t *client;
     613       
     614        if (lnk) {
     615                client = hash_table_get_instance(lnk, client_t, link);
     616                atomic_inc(&client->refcnt);
     617        } else {
     618                client = malloc(sizeof(client_t));
     619                if (!client) {
     620                        ipc_answer_0(fibril_connection->callid, ENOMEM);
     621                        futex_up(&async_futex);
     622                        return 0;
     623                }
     624               
     625                client->in_task_hash = fibril_connection->in_task_hash;
     626                client->data = async_client_data_create();
     627               
     628                atomic_set(&client->refcnt, 1);
     629                hash_table_insert(&client_hash_table, &key, &client->link);
     630        }
     631       
     632        futex_up(&async_futex);
     633       
    697634        fibril_connection->client = client;
    698635       
     
    706643         * Remove the reference for this client task connection.
    707644         */
    708         async_client_put(client);
     645        bool destroy;
     646       
     647        futex_down(&async_futex);
     648       
     649        if (atomic_predec(&client->refcnt) == 0) {
     650                hash_table_remove(&client_hash_table, &key, 1);
     651                destroy = true;
     652        } else
     653                destroy = false;
     654       
     655        futex_up(&async_futex);
     656       
     657        if (destroy) {
     658                if (client->data)
     659                        async_client_data_destroy(client->data);
     660               
     661                free(client);
     662        }
    709663       
    710664        /*
     
    712666         */
    713667        futex_down(&async_futex);
    714         unsigned long key = fibril_connection->in_phone_hash;
     668        key = fibril_connection->in_phone_hash;
    715669        hash_table_remove(&conn_hash_table, &key, 1);
    716670        futex_up(&async_futex);
     
    746700 * particular fibrils.
    747701 *
    748  * @param in_task_id    Identification of the incoming connection.
     702 * @param in_task_hash  Identification of the incoming connection.
    749703 * @param in_phone_hash Identification of the incoming connection.
    750704 * @param callid        Hash of the opening IPC_M_CONNECT_ME_TO call.
     
    760714 *
    761715 */
    762 fid_t async_new_connection(task_id_t in_task_id, sysarg_t in_phone_hash,
     716fid_t async_new_connection(sysarg_t in_task_hash, sysarg_t in_phone_hash,
    763717    ipc_callid_t callid, ipc_call_t *call,
    764718    async_client_conn_t cfibril, void *carg)
     
    772726        }
    773727       
    774         conn->in_task_id = in_task_id;
     728        conn->in_task_hash = in_task_hash;
    775729        conn->in_phone_hash = in_phone_hash;
    776730        list_initialize(&conn->msg_queue);
     
    831785        case IPC_M_CONNECT_ME_TO:
    832786                /* Open new connection with fibril, etc. */
    833                 async_new_connection(call->in_task_id, IPC_GET_ARG5(*call),
     787                async_new_connection(call->in_task_hash, IPC_GET_ARG5(*call),
    834788                    callid, call, client_connection, NULL);
    835789                return;
     
    979933{
    980934        if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS,
    981             2, &client_hash_table_ops))
     935            1, &client_hash_table_ops))
    982936                abort();
    983937       
     
    14721426                return ENOENT;
    14731427       
    1474         task_id_t task_id;
    1475         sysarg_t task_id_lo;
    1476         sysarg_t task_id_hi;
     1428        sysarg_t task_hash;
    14771429        sysarg_t phone_hash;
    14781430        int rc = async_req_3_5(exch, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,
    1479             NULL, NULL, &task_id_lo, &task_id_hi, &phone_hash);
     1431            NULL, NULL, NULL, &task_hash, &phone_hash);
    14801432        if (rc != EOK)
    14811433                return rc;
    1482 
    1483         task_id = (task_id_t) MERGE_LOUP32(task_id_lo, task_id_hi);
    14841434       
    14851435        if (client_receiver != NULL)
    1486                 async_new_connection(task_id, phone_hash, 0, NULL,
     1436                async_new_connection(task_hash, phone_hash, 0, NULL,
    14871437                    client_receiver, carg);
    14881438       
     
    24792429}
    24802430
    2481 int async_state_change_start(async_exch_t *exch, sysarg_t arg1, sysarg_t arg2,
    2482     sysarg_t arg3, async_exch_t *other_exch)
    2483 {
    2484         return async_req_5_0(exch, IPC_M_STATE_CHANGE_AUTHORIZE,
    2485             arg1, arg2, arg3, 0, other_exch->phone);
    2486 }
    2487 
    2488 bool async_state_change_receive(ipc_callid_t *callid, sysarg_t *arg1,
    2489     sysarg_t *arg2, sysarg_t *arg3)
    2490 {
    2491         assert(callid);
    2492 
    2493         ipc_call_t call;
    2494         *callid = async_get_call(&call);
    2495 
    2496         if (IPC_GET_IMETHOD(call) != IPC_M_STATE_CHANGE_AUTHORIZE)
    2497                 return false;
    2498        
    2499         if (arg1)
    2500                 *arg1 = IPC_GET_ARG1(call);
    2501         if (arg2)
    2502                 *arg2 = IPC_GET_ARG2(call);
    2503         if (arg3)
    2504                 *arg3 = IPC_GET_ARG3(call);
    2505 
    2506         return true;
    2507 }
    2508 
    2509 int async_state_change_finalize(ipc_callid_t callid, async_exch_t *other_exch)
    2510 {
    2511         return ipc_answer_1(callid, EOK, other_exch->phone);
    2512 }
    2513 
    25142431/** @}
    25152432 */
Note: See TracChangeset for help on using the changeset viewer.