Ignore:
File:
1 edited

Legend:

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

    rcdc8ee2d r93ad49a8  
    9898#include <ipc/ipc.h>
    9999#include <async.h>
     100#include "private/async.h"
    100101#undef LIBC_ASYNC_C_
    101102
     
    112113#include <mem.h>
    113114#include <stdlib.h>
    114 #include "private/async.h"
     115#include <macros.h>
    115116
    116117#define CLIENT_HASH_TABLE_BUCKETS  32
     
    138139        link_t link;
    139140       
    140         sysarg_t in_task_hash;
     141        task_id_t in_task_id;
    141142        atomic_t refcnt;
    142143        void *data;
     
    150151        link_t link;
    151152       
    152         /** Incoming client task hash. */
    153         sysarg_t in_task_hash;
     153        /** Incoming client task ID. */
     154        task_id_t in_task_id;
    154155       
    155156        /** Incoming phone hash. */
     
    283284{
    284285        assert(key);
     286        assert(keys == 2);
    285287        assert(item);
    286288       
    287289        client_t *client = hash_table_get_instance(item, client_t, link);
    288         return (key[0] == client->in_task_hash);
     290        return (key[0] == LOWER32(client->in_task_id) &&
     291            (key[1] == UPPER32(client->in_task_id)));
    289292}
    290293
     
    574577}
    575578
    576 static client_t *async_client_get(sysarg_t client_hash, bool create)
    577 {
    578         unsigned long key = client_hash;
     579static 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        };
    579585        client_t *client = NULL;
    580586
    581587        futex_down(&async_futex);
    582         link_t *lnk = hash_table_find(&client_hash_table, &key);
     588        link_t *lnk = hash_table_find(&client_hash_table, key);
    583589        if (lnk) {
    584590                client = hash_table_get_instance(lnk, client_t, link);
     
    587593                client = malloc(sizeof(client_t));
    588594                if (client) {
    589                         client->in_task_hash = client_hash;
     595                        client->in_task_id = client_id;
    590596                        client->data = async_client_data_create();
    591597               
    592598                        atomic_set(&client->refcnt, 1);
    593                         hash_table_insert(&client_hash_table, &key, &client->link);
     599                        hash_table_insert(&client_hash_table, key, &client->link);
    594600                }
    595601        }
     
    602608{
    603609        bool destroy;
    604         unsigned long key = client->in_task_hash;
     610        unsigned long key[2] = {
     611                LOWER32(client->in_task_id),
     612                UPPER32(client->in_task_id)
     613        };
    605614       
    606615        futex_down(&async_futex);
    607616       
    608617        if (atomic_predec(&client->refcnt) == 0) {
    609                 hash_table_remove(&client_hash_table, &key, 1);
     618                hash_table_remove(&client_hash_table, key, 2);
    610619                destroy = true;
    611620        } else
     
    628637}
    629638
    630 void *async_get_client_data_by_hash(sysarg_t client_hash)
    631 {
    632         client_t *client = async_client_get(client_hash, false);
     639void *async_get_client_data_by_id(task_id_t client_id)
     640{
     641        client_t *client = async_client_get(client_id, false);
    633642        if (!client)
    634643                return NULL;
     
    641650}
    642651
    643 void async_put_client_data_by_hash(sysarg_t client_hash)
    644 {
    645         client_t *client = async_client_get(client_hash, false);
     652void async_put_client_data_by_id(task_id_t client_id)
     653{
     654        client_t *client = async_client_get(client_id, false);
    646655
    647656        assert(client);
     
    680689         */
    681690
    682         client_t *client = async_client_get(fibril_connection->in_task_hash, true);
     691        client_t *client = async_client_get(fibril_connection->in_task_id, true);
    683692        if (!client) {
    684693                ipc_answer_0(fibril_connection->callid, ENOMEM);
     
    737746 * particular fibrils.
    738747 *
    739  * @param in_task_hash  Identification of the incoming connection.
     748 * @param in_task_id    Identification of the incoming connection.
    740749 * @param in_phone_hash Identification of the incoming connection.
    741750 * @param callid        Hash of the opening IPC_M_CONNECT_ME_TO call.
     
    751760 *
    752761 */
    753 fid_t async_new_connection(sysarg_t in_task_hash, sysarg_t in_phone_hash,
     762fid_t async_new_connection(task_id_t in_task_id, sysarg_t in_phone_hash,
    754763    ipc_callid_t callid, ipc_call_t *call,
    755764    async_client_conn_t cfibril, void *carg)
     
    763772        }
    764773       
    765         conn->in_task_hash = in_task_hash;
     774        conn->in_task_id = in_task_id;
    766775        conn->in_phone_hash = in_phone_hash;
    767776        list_initialize(&conn->msg_queue);
     
    822831        case IPC_M_CONNECT_ME_TO:
    823832                /* Open new connection with fibril, etc. */
    824                 async_new_connection(call->in_task_hash, IPC_GET_ARG5(*call),
     833                async_new_connection(call->in_task_id, IPC_GET_ARG5(*call),
    825834                    callid, call, client_connection, NULL);
    826835                return;
     
    970979{
    971980        if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS,
    972             1, &client_hash_table_ops))
     981            2, &client_hash_table_ops))
    973982                abort();
    974983       
     
    986995        session_ns->arg2 = 0;
    987996        session_ns->arg3 = 0;
     997       
     998        fibril_mutex_initialize(&session_ns->remote_state_mtx);
     999        session_ns->remote_state_data = NULL;
    9881000       
    9891001        list_initialize(&session_ns->exch_list);
     
    14631475                return ENOENT;
    14641476       
    1465         sysarg_t task_hash;
    14661477        sysarg_t phone_hash;
    1467         int rc = async_req_3_5(exch, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,
    1468             NULL, NULL, NULL, &task_hash, &phone_hash);
     1478        sysarg_t rc;
     1479
     1480        aid_t req;
     1481        ipc_call_t answer;
     1482        req = async_send_3(exch, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,
     1483            &answer);
     1484        async_wait_for(req, &rc);
    14691485        if (rc != EOK)
    1470                 return rc;
    1471        
     1486                return (int) rc;
     1487
     1488        phone_hash = IPC_GET_ARG5(answer);
     1489
    14721490        if (client_receiver != NULL)
    1473                 async_new_connection(task_hash, phone_hash, 0, NULL,
     1491                async_new_connection(answer.in_task_id, phone_hash, 0, NULL,
    14741492                    client_receiver, carg);
    14751493       
     
    15461564        sess->arg3 = 0;
    15471565       
     1566        fibril_mutex_initialize(&sess->remote_state_mtx);
     1567        sess->remote_state_data = NULL;
     1568       
    15481569        list_initialize(&sess->exch_list);
    15491570        fibril_mutex_initialize(&sess->mutex);
     
    16271648        sess->arg3 = arg3;
    16281649       
     1650        fibril_mutex_initialize(&sess->remote_state_mtx);
     1651        sess->remote_state_data = NULL;
     1652       
    16291653        list_initialize(&sess->exch_list);
    16301654        fibril_mutex_initialize(&sess->mutex);
     
    16321656       
    16331657        return sess;
     1658}
     1659
     1660/** Set arguments for new connections.
     1661 *
     1662 * FIXME This is an ugly hack to work around the problem that parallel
     1663 * exchanges are implemented using parallel connections. When we create
     1664 * a callback session, the framework does not know arguments for the new
     1665 * connections.
     1666 *
     1667 * The proper solution seems to be to implement parallel exchanges using
     1668 * tagging.
     1669 */
     1670void async_sess_args_set(async_sess_t *sess, sysarg_t arg1, sysarg_t arg2,
     1671    sysarg_t arg3)
     1672{
     1673        sess->arg1 = arg1;
     1674        sess->arg2 = arg2;
     1675        sess->arg3 = arg3;
    16341676}
    16351677
     
    16771719        sess->arg3 = arg3;
    16781720       
     1721        fibril_mutex_initialize(&sess->remote_state_mtx);
     1722        sess->remote_state_data = NULL;
     1723       
    16791724        list_initialize(&sess->exch_list);
    16801725        fibril_mutex_initialize(&sess->mutex);
     
    17071752        sess->arg2 = 0;
    17081753        sess->arg3 = 0;
     1754       
     1755        fibril_mutex_initialize(&sess->remote_state_mtx);
     1756        sess->remote_state_data = NULL;
    17091757       
    17101758        list_initialize(&sess->exch_list);
     
    23712419        sess->arg3 = 0;
    23722420       
     2421        fibril_mutex_initialize(&sess->remote_state_mtx);
     2422        sess->remote_state_data = NULL;
     2423       
    23732424        list_initialize(&sess->exch_list);
    23742425        fibril_mutex_initialize(&sess->mutex);
     
    24172468        sess->arg3 = 0;
    24182469       
     2470        fibril_mutex_initialize(&sess->remote_state_mtx);
     2471        sess->remote_state_data = NULL;
     2472       
    24192473        list_initialize(&sess->exch_list);
    24202474        fibril_mutex_initialize(&sess->mutex);
     
    24582512        sess->arg2 = 0;
    24592513        sess->arg3 = 0;
     2514       
     2515        fibril_mutex_initialize(&sess->remote_state_mtx);
     2516        sess->remote_state_data = NULL;
    24602517       
    24612518        list_initialize(&sess->exch_list);
     
    24992556}
    25002557
     2558/** Lock and get session remote state
     2559 *
     2560 * Lock and get the local replica of the remote state
     2561 * in stateful sessions. The call should be paired
     2562 * with async_remote_state_release*().
     2563 *
     2564 * @param[in] sess Stateful session.
     2565 *
     2566 * @return Local replica of the remote state.
     2567 *
     2568 */
     2569void *async_remote_state_acquire(async_sess_t *sess)
     2570{
     2571        fibril_mutex_lock(&sess->remote_state_mtx);
     2572        return sess->remote_state_data;
     2573}
     2574
     2575/** Update the session remote state
     2576 *
     2577 * Update the local replica of the remote state
     2578 * in stateful sessions. The remote state must
     2579 * be already locked.
     2580 *
     2581 * @param[in] sess  Stateful session.
     2582 * @param[in] state New local replica of the remote state.
     2583 *
     2584 */
     2585void async_remote_state_update(async_sess_t *sess, void *state)
     2586{
     2587        assert(fibril_mutex_is_locked(&sess->remote_state_mtx));
     2588        sess->remote_state_data = state;
     2589}
     2590
     2591/** Release the session remote state
     2592 *
     2593 * Unlock the local replica of the remote state
     2594 * in stateful sessions.
     2595 *
     2596 * @param[in] sess Stateful session.
     2597 *
     2598 */
     2599void async_remote_state_release(async_sess_t *sess)
     2600{
     2601        assert(fibril_mutex_is_locked(&sess->remote_state_mtx));
     2602       
     2603        fibril_mutex_unlock(&sess->remote_state_mtx);
     2604}
     2605
     2606/** Release the session remote state and end an exchange
     2607 *
     2608 * Unlock the local replica of the remote state
     2609 * in stateful sessions. This is convenience function
     2610 * which gets the session pointer from the exchange
     2611 * and also ends the exchange.
     2612 *
     2613 * @param[in] exch Stateful session's exchange.
     2614 *
     2615 */
     2616void async_remote_state_release_exchange(async_exch_t *exch)
     2617{
     2618        if (exch == NULL)
     2619                return;
     2620       
     2621        async_sess_t *sess = exch->sess;
     2622        assert(fibril_mutex_is_locked(&sess->remote_state_mtx));
     2623       
     2624        async_exchange_end(exch);
     2625        fibril_mutex_unlock(&sess->remote_state_mtx);
     2626}
     2627
    25012628/** @}
    25022629 */
Note: See TracChangeset for help on using the changeset viewer.