Changes in uspace/lib/c/generic/async.c [649f087:c0699467] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/async.c
r649f087 rc0699467 112 112 #include <mem.h> 113 113 #include <stdlib.h> 114 #include <macros.h>115 114 #include "private/async.h" 116 115 … … 139 138 link_t link; 140 139 141 task_id_t in_task_id;140 sysarg_t in_task_hash; 142 141 atomic_t refcnt; 143 142 void *data; … … 151 150 link_t link; 152 151 153 /** Incoming client task ID. */154 task_id_t in_task_id;152 /** Incoming client task hash. */ 153 sysarg_t in_task_hash; 155 154 156 155 /** Incoming phone hash. */ … … 204 203 } 205 204 205 void *async_get_client_data(void) 206 { 207 assert(fibril_connection); 208 return fibril_connection->client->data; 209 } 210 206 211 /** Default fibril function that gets called to handle new connection. 207 212 * … … 284 289 { 285 290 assert(key); 286 assert(keys == 2);287 291 assert(item); 288 292 289 293 client_t *client = hash_table_get_instance(item, client_t, link); 290 return (key[0] == LOWER32(client->in_task_id) && 291 (key[1] == UPPER32(client->in_task_id))); 294 return (key[0] == client->in_task_hash); 292 295 } 293 296 … … 577 580 } 578 581 579 static client_t *async_client_get(task_id_t client_id, bool create)580 {581 unsigned long key[2] = {582 LOWER32(client_id),583 UPPER32(client_id),584 };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_id = client_id;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 607 static void async_client_put(client_t *client)608 {609 bool destroy;610 unsigned long key[2] = {611 LOWER32(client->in_task_id),612 UPPER32(client->in_task_id)613 };614 615 futex_down(&async_futex);616 617 if (atomic_predec(&client->refcnt) == 0) {618 hash_table_remove(&client_hash_table, key, 2);619 destroy = true;620 } else621 destroy = false;622 623 futex_up(&async_futex);624 625 if (destroy) {626 if (client->data)627 async_client_data_destroy(client->data);628 629 free(client);630 }631 }632 633 void *async_get_client_data(void)634 {635 assert(fibril_connection);636 return fibril_connection->client->data;637 }638 639 void *async_get_client_data_by_id(task_id_t client_id)640 {641 client_t *client = async_client_get(client_id, false);642 if (!client)643 return NULL;644 if (!client->data) {645 async_client_put(client);646 return NULL;647 }648 649 return client->data;650 }651 652 void async_put_client_data_by_id(task_id_t client_id)653 {654 client_t *client = async_client_get(client_id, false);655 656 assert(client);657 assert(client->data);658 659 /* Drop the reference we got in async_get_client_data_by_hash(). */660 async_client_put(client);661 662 /* Drop our own reference we got at the beginning of this function. */663 async_client_put(client);664 }665 666 582 /** Wrapper for client connection fibril. 667 583 * … … 682 598 */ 683 599 fibril_connection = (connection_t *) arg; 600 601 futex_down(&async_futex); 684 602 685 603 /* … … 688 606 * hash in a new tracking structure. 689 607 */ 690 691 client_t *client = async_client_get(fibril_connection->in_task_id, true); 692 if (!client) { 693 ipc_answer_0(fibril_connection->callid, ENOMEM); 694 return 0; 695 } 696 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 697 634 fibril_connection->client = client; 698 635 … … 706 643 * Remove the reference for this client task connection. 707 644 */ 708 async_client_put(client); 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 } 709 663 710 664 /* … … 712 666 */ 713 667 futex_down(&async_futex); 714 unsigned longkey = fibril_connection->in_phone_hash;668 key = fibril_connection->in_phone_hash; 715 669 hash_table_remove(&conn_hash_table, &key, 1); 716 670 futex_up(&async_futex); … … 746 700 * particular fibrils. 747 701 * 748 * @param in_task_ idIdentification of the incoming connection.702 * @param in_task_hash Identification of the incoming connection. 749 703 * @param in_phone_hash Identification of the incoming connection. 750 704 * @param callid Hash of the opening IPC_M_CONNECT_ME_TO call. … … 760 714 * 761 715 */ 762 fid_t async_new_connection( task_id_t in_task_id, sysarg_t in_phone_hash,716 fid_t async_new_connection(sysarg_t in_task_hash, sysarg_t in_phone_hash, 763 717 ipc_callid_t callid, ipc_call_t *call, 764 718 async_client_conn_t cfibril, void *carg) … … 772 726 } 773 727 774 conn->in_task_ id = in_task_id;728 conn->in_task_hash = in_task_hash; 775 729 conn->in_phone_hash = in_phone_hash; 776 730 list_initialize(&conn->msg_queue); … … 831 785 case IPC_M_CONNECT_ME_TO: 832 786 /* Open new connection with fibril, etc. */ 833 async_new_connection(call->in_task_ id, IPC_GET_ARG5(*call),787 async_new_connection(call->in_task_hash, IPC_GET_ARG5(*call), 834 788 callid, call, client_connection, NULL); 835 789 return; … … 979 933 { 980 934 if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS, 981 2, &client_hash_table_ops))935 1, &client_hash_table_ops)) 982 936 abort(); 983 937 … … 1472 1426 return ENOENT; 1473 1427 1474 task_id_t task_id; 1475 sysarg_t task_id_lo; 1476 sysarg_t task_id_hi; 1428 sysarg_t task_hash; 1477 1429 sysarg_t phone_hash; 1478 1430 int rc = async_req_3_5(exch, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3, 1479 NULL, NULL, &task_id_lo, &task_id_hi, &phone_hash);1431 NULL, NULL, NULL, &task_hash, &phone_hash); 1480 1432 if (rc != EOK) 1481 1433 return rc; 1482 1483 task_id = (task_id_t) MERGE_LOUP32(task_id_lo, task_id_hi);1484 1434 1485 1435 if (client_receiver != NULL) 1486 async_new_connection(task_ id, phone_hash, 0, NULL,1436 async_new_connection(task_hash, phone_hash, 0, NULL, 1487 1437 client_receiver, carg); 1488 1438 … … 2479 2429 } 2480 2430 2481 int async_state_change_start(async_exch_t *exch, sysarg_t arg1, sysarg_t arg2,2482 sysarg_t arg3, async_exch_t *other_exch)2483 {2484 return async_req_5_0(exch, IPC_M_STATE_CHANGE_AUTHORIZE,2485 arg1, arg2, arg3, 0, other_exch->phone);2486 }2487 2488 bool async_state_change_receive(ipc_callid_t *callid, sysarg_t *arg1,2489 sysarg_t *arg2, sysarg_t *arg3)2490 {2491 assert(callid);2492 2493 ipc_call_t call;2494 *callid = async_get_call(&call);2495 2496 if (IPC_GET_IMETHOD(call) != IPC_M_STATE_CHANGE_AUTHORIZE)2497 return false;2498 2499 if (arg1)2500 *arg1 = IPC_GET_ARG1(call);2501 if (arg2)2502 *arg2 = IPC_GET_ARG2(call);2503 if (arg3)2504 *arg3 = IPC_GET_ARG3(call);2505 2506 return true;2507 }2508 2509 int async_state_change_finalize(ipc_callid_t callid, async_exch_t *other_exch)2510 {2511 return ipc_answer_1(callid, EOK, other_exch->phone);2512 }2513 2514 2431 /** @} 2515 2432 */
Note:
See TracChangeset
for help on using the changeset viewer.