Ignore:
File:
1 edited

Legend:

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

    rcdc8ee2d rc0699467  
    201201{
    202202        async_client_data_destroy = dtor;
     203}
     204
     205void *async_get_client_data(void)
     206{
     207        assert(fibril_connection);
     208        return fibril_connection->client->data;
    203209}
    204210
     
    574580}
    575581
    576 static client_t *async_client_get(sysarg_t client_hash, bool create)
    577 {
    578         unsigned long key = client_hash;
    579         client_t *client = NULL;
    580 
     582/** Wrapper for client connection fibril.
     583 *
     584 * When a new connection arrives, a fibril with this implementing function is
     585 * created. It calls client_connection() and does the final cleanup.
     586 *
     587 * @param arg Connection structure pointer.
     588 *
     589 * @return Always zero.
     590 *
     591 */
     592static int connection_fibril(void *arg)
     593{
     594        assert(arg);
     595       
     596        /*
     597         * Setup fibril-local connection pointer.
     598         */
     599        fibril_connection = (connection_t *) arg;
     600       
    581601        futex_down(&async_futex);
     602       
     603        /*
     604         * Add our reference for the current connection in the client task
     605         * tracking structure. If this is the first reference, create and
     606         * hash in a new tracking structure.
     607         */
     608       
     609        unsigned long key = fibril_connection->in_task_hash;
    582610        link_t *lnk = hash_table_find(&client_hash_table, &key);
     611       
     612        client_t *client;
     613       
    583614        if (lnk) {
    584615                client = hash_table_get_instance(lnk, client_t, link);
    585616                atomic_inc(&client->refcnt);
    586         } else if (create) {
     617        } else {
    587618                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);
     619                if (!client) {
     620                        ipc_answer_0(fibril_connection->callid, ENOMEM);
     621                        futex_up(&async_futex);
     622                        return 0;
    594623                }
    595         }
    596 
     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       
    597632        futex_up(&async_futex);
    598         return client;
    599 }
    600 
    601 static void async_client_put(client_t *client)
    602 {
     633       
     634        fibril_connection->client = client;
     635       
     636        /*
     637         * Call the connection handler function.
     638         */
     639        fibril_connection->cfibril(fibril_connection->callid,
     640            &fibril_connection->call, fibril_connection->carg);
     641       
     642        /*
     643         * Remove the reference for this client task connection.
     644         */
    603645        bool destroy;
    604         unsigned long key = client->in_task_hash;
    605646       
    606647        futex_down(&async_futex);
     
    620661                free(client);
    621662        }
    622 }
    623 
    624 void *async_get_client_data(void)
    625 {
    626         assert(fibril_connection);
    627         return fibril_connection->client->data;
    628 }
    629 
    630 void *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 
    643 void 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 
    657 /** Wrapper for client connection fibril.
    658  *
    659  * When a new connection arrives, a fibril with this implementing function is
    660  * created. It calls client_connection() and does the final cleanup.
    661  *
    662  * @param arg Connection structure pointer.
    663  *
    664  * @return Always zero.
    665  *
    666  */
    667 static int connection_fibril(void *arg)
    668 {
    669         assert(arg);
    670        
    671         /*
    672          * Setup fibril-local connection pointer.
    673          */
    674         fibril_connection = (connection_t *) arg;
    675        
    676         /*
    677          * Add our reference for the current connection in the client task
    678          * tracking structure. If this is the first reference, create and
    679          * hash in a new tracking structure.
    680          */
    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 
    688         fibril_connection->client = client;
    689        
    690         /*
    691          * Call the connection handler function.
    692          */
    693         fibril_connection->cfibril(fibril_connection->callid,
    694             &fibril_connection->call, fibril_connection->carg);
    695        
    696         /*
    697          * Remove the reference for this client task connection.
    698          */
    699         async_client_put(client);
    700663       
    701664        /*
     
    703666         */
    704667        futex_down(&async_futex);
    705         unsigned long key = fibril_connection->in_phone_hash;
     668        key = fibril_connection->in_phone_hash;
    706669        hash_table_remove(&conn_hash_table, &key, 1);
    707670        futex_up(&async_futex);
     
    24662429}
    24672430
    2468 int 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 
    2475 bool 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 
    2496 int 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 
    25012431/** @}
    25022432 */
Note: See TracChangeset for help on using the changeset viewer.