Changeset 42a619b in mainline for uspace/lib/c/generic/async.c
- Timestamp:
- 2011-08-19T08:58:50Z (13 years ago)
- 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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/async.c
ref7052ec r42a619b 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;209 203 } 210 204 … … 580 574 } 581 575 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 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 601 static 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 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 582 657 /** Wrapper for client connection fibril. 583 658 * … … 598 673 */ 599 674 fibril_connection = (connection_t *) arg; 600 601 futex_down(&async_futex);602 675 603 676 /* … … 606 679 * hash in a new tracking structure. 607 680 */ 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 634 688 fibril_connection->client = client; 635 689 … … 643 697 * Remove the reference for this client task connection. 644 698 */ 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); 663 700 664 701 /* … … 666 703 */ 667 704 futex_down(&async_futex); 668 key = fibril_connection->in_phone_hash;705 unsigned long key = fibril_connection->in_phone_hash; 669 706 hash_table_remove(&conn_hash_table, &key, 1); 670 707 futex_up(&async_futex); … … 2429 2466 } 2430 2467 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 2431 2501 /** @} 2432 2502 */
Note:
See TracChangeset
for help on using the changeset viewer.