Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 26fbb7bb in mainline for uspace/lib/c/generic/async.c


Ignore:
Timestamp:
2011-08-17T13:19:46Z (10 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master
Children:
455f190
Parents:
9bf51e64
Message:

Factor out code for getting and dropping references to client_t's.

File:
1 edited

Legend:

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

    r9bf51e64 r26fbb7bb  
    580580}
    581581
     582static client_t *async_client_get(sysarg_t client_hash, bool create)
     583{
     584        unsigned long key = client_hash;
     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_hash = client_hash;
     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
     607static void async_client_put(client_t *client)
     608{
     609        bool destroy;
     610        unsigned long key = client->in_task_hash;
     611       
     612        futex_down(&async_futex);
     613       
     614        if (atomic_predec(&client->refcnt) == 0) {
     615                hash_table_remove(&client_hash_table, &key, 1);
     616                destroy = true;
     617        } else
     618                destroy = false;
     619       
     620        futex_up(&async_futex);
     621       
     622        if (destroy) {
     623                if (client->data)
     624                        async_client_data_destroy(client->data);
     625               
     626                free(client);
     627        }
     628}
     629
    582630/** Wrapper for client connection fibril.
    583631 *
     
    598646         */
    599647        fibril_connection = (connection_t *) arg;
    600        
    601         futex_down(&async_futex);
    602648       
    603649        /*
     
    606652         * hash in a new tracking structure.
    607653         */
    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        
     654
     655        client_t *client = async_client_get(fibril_connection->in_task_hash, true);
     656        if (!client) {
     657                ipc_answer_0(fibril_connection->callid, ENOMEM);
     658                return 0;
     659        }
     660
    634661        fibril_connection->client = client;
    635662       
     
    643670         * Remove the reference for this client task connection.
    644671         */
    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         }
     672        async_client_put(client);
    663673       
    664674        /*
     
    666676         */
    667677        futex_down(&async_futex);
    668         key = fibril_connection->in_phone_hash;
     678        unsigned long key = fibril_connection->in_phone_hash;
    669679        hash_table_remove(&conn_hash_table, &key, 1);
    670680        futex_up(&async_futex);
Note: See TracChangeset for help on using the changeset viewer.