Changeset 42a619b in mainline for uspace/lib/c/generic/async.c


Ignore:
Timestamp:
2011-08-19T08:58:50Z (14 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
7dcb7981, 903bac0a, c2cf033
Parents:
ef7052ec (diff), d894fbd (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge from lp:~jakub/helenos/camp2011.

File:
1 edited

Legend:

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

    ref7052ec r42a619b  
    201201{
    202202        async_client_data_destroy = dtor;
    203 }
    204 
    205 void *async_get_client_data(void)
    206 {
    207         assert(fibril_connection);
    208         return fibril_connection->client->data;
    209203}
    210204
     
    580574}
    581575
     576static client_t *async_client_get(sysarg_t client_hash, bool create)
     577{
     578        unsigned long key = client_hash;
     579        client_t *client = NULL;
     580
     581        futex_down(&async_futex);
     582        link_t *lnk = hash_table_find(&client_hash_table, &key);
     583        if (lnk) {
     584                client = hash_table_get_instance(lnk, client_t, link);
     585                atomic_inc(&client->refcnt);
     586        } else if (create) {
     587                client = malloc(sizeof(client_t));
     588                if (client) {
     589                        client->in_task_hash = client_hash;
     590                        client->data = async_client_data_create();
     591               
     592                        atomic_set(&client->refcnt, 1);
     593                        hash_table_insert(&client_hash_table, &key, &client->link);
     594                }
     595        }
     596
     597        futex_up(&async_futex);
     598        return client;
     599}
     600
     601static void async_client_put(client_t *client)
     602{
     603        bool destroy;
     604        unsigned long key = client->in_task_hash;
     605       
     606        futex_down(&async_futex);
     607       
     608        if (atomic_predec(&client->refcnt) == 0) {
     609                hash_table_remove(&client_hash_table, &key, 1);
     610                destroy = true;
     611        } else
     612                destroy = false;
     613       
     614        futex_up(&async_futex);
     615       
     616        if (destroy) {
     617                if (client->data)
     618                        async_client_data_destroy(client->data);
     619               
     620                free(client);
     621        }
     622}
     623
     624void *async_get_client_data(void)
     625{
     626        assert(fibril_connection);
     627        return fibril_connection->client->data;
     628}
     629
     630void *async_get_client_data_by_hash(sysarg_t client_hash)
     631{
     632        client_t *client = async_client_get(client_hash, false);
     633        if (!client)
     634                return NULL;
     635        if (!client->data) {
     636                async_client_put(client);
     637                return NULL;
     638        }
     639
     640        return client->data;
     641}
     642
     643void async_put_client_data_by_hash(sysarg_t client_hash)
     644{
     645        client_t *client = async_client_get(client_hash, false);
     646
     647        assert(client);
     648        assert(client->data);
     649
     650        /* Drop the reference we got in async_get_client_data_by_hash(). */
     651        async_client_put(client);
     652
     653        /* Drop our own reference we got at the beginning of this function. */
     654        async_client_put(client);
     655}
     656
    582657/** Wrapper for client connection fibril.
    583658 *
     
    598673         */
    599674        fibril_connection = (connection_t *) arg;
    600        
    601         futex_down(&async_futex);
    602675       
    603676        /*
     
    606679         * hash in a new tracking structure.
    607680         */
    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        
     681
     682        client_t *client = async_client_get(fibril_connection->in_task_hash, true);
     683        if (!client) {
     684                ipc_answer_0(fibril_connection->callid, ENOMEM);
     685                return 0;
     686        }
     687
    634688        fibril_connection->client = client;
    635689       
     
    643697         * Remove the reference for this client task connection.
    644698         */
    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         }
     699        async_client_put(client);
    663700       
    664701        /*
     
    666703         */
    667704        futex_down(&async_futex);
    668         key = fibril_connection->in_phone_hash;
     705        unsigned long key = fibril_connection->in_phone_hash;
    669706        hash_table_remove(&conn_hash_table, &key, 1);
    670707        futex_up(&async_futex);
     
    24292466}
    24302467
     2468int async_state_change_start(async_exch_t *exch, sysarg_t arg1, sysarg_t arg2,
     2469    sysarg_t arg3, async_exch_t *other_exch)
     2470{
     2471        return async_req_5_0(exch, IPC_M_STATE_CHANGE_AUTHORIZE,
     2472            arg1, arg2, arg3, 0, other_exch->phone);
     2473}
     2474
     2475bool async_state_change_receive(ipc_callid_t *callid, sysarg_t *arg1,
     2476    sysarg_t *arg2, sysarg_t *arg3)
     2477{
     2478        assert(callid);
     2479
     2480        ipc_call_t call;
     2481        *callid = async_get_call(&call);
     2482
     2483        if (IPC_GET_IMETHOD(call) != IPC_M_STATE_CHANGE_AUTHORIZE)
     2484                return false;
     2485       
     2486        if (arg1)
     2487                *arg1 = IPC_GET_ARG1(call);
     2488        if (arg2)
     2489                *arg2 = IPC_GET_ARG2(call);
     2490        if (arg3)
     2491                *arg3 = IPC_GET_ARG3(call);
     2492
     2493        return true;
     2494}
     2495
     2496int async_state_change_finalize(ipc_callid_t callid, async_exch_t *other_exch)
     2497{
     2498        return ipc_answer_1(callid, EOK, other_exch->phone);
     2499}
     2500
    24312501/** @}
    24322502 */
Note: See TracChangeset for help on using the changeset viewer.