Changes in uspace/lib/c/generic/async.c [cdc8ee2d:c0699467] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/async.c
rcdc8ee2d rc0699467 201 201 { 202 202 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; 203 209 } 204 210 … … 574 580 } 575 581 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 */ 592 static 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 581 601 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; 582 610 link_t *lnk = hash_table_find(&client_hash_table, &key); 611 612 client_t *client; 613 583 614 if (lnk) { 584 615 client = hash_table_get_instance(lnk, client_t, link); 585 616 atomic_inc(&client->refcnt); 586 } else if (create){617 } else { 587 618 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; 594 623 } 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 597 632 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 */ 603 645 bool destroy; 604 unsigned long key = client->in_task_hash;605 646 606 647 futex_down(&async_futex); … … 620 661 free(client); 621 662 } 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 is660 * 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 task678 * tracking structure. If this is the first reference, create and679 * 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);700 663 701 664 /* … … 703 666 */ 704 667 futex_down(&async_futex); 705 unsigned longkey = fibril_connection->in_phone_hash;668 key = fibril_connection->in_phone_hash; 706 669 hash_table_remove(&conn_hash_table, &key, 1); 707 670 futex_up(&async_futex); … … 2466 2429 } 2467 2430 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 2501 2431 /** @} 2502 2432 */
Note:
See TracChangeset
for help on using the changeset viewer.