Changes in uspace/lib/c/generic/async.c [cdc8ee2d:93ad49a8] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/async.c
rcdc8ee2d r93ad49a8 98 98 #include <ipc/ipc.h> 99 99 #include <async.h> 100 #include "private/async.h" 100 101 #undef LIBC_ASYNC_C_ 101 102 … … 112 113 #include <mem.h> 113 114 #include <stdlib.h> 114 #include "private/async.h"115 #include <macros.h> 115 116 116 117 #define CLIENT_HASH_TABLE_BUCKETS 32 … … 138 139 link_t link; 139 140 140 sysarg_t in_task_hash;141 task_id_t in_task_id; 141 142 atomic_t refcnt; 142 143 void *data; … … 150 151 link_t link; 151 152 152 /** Incoming client task hash. */153 sysarg_t in_task_hash;153 /** Incoming client task ID. */ 154 task_id_t in_task_id; 154 155 155 156 /** Incoming phone hash. */ … … 283 284 { 284 285 assert(key); 286 assert(keys == 2); 285 287 assert(item); 286 288 287 289 client_t *client = hash_table_get_instance(item, client_t, link); 288 return (key[0] == client->in_task_hash); 290 return (key[0] == LOWER32(client->in_task_id) && 291 (key[1] == UPPER32(client->in_task_id))); 289 292 } 290 293 … … 574 577 } 575 578 576 static client_t *async_client_get(sysarg_t client_hash, bool create) 577 { 578 unsigned long key = client_hash; 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 }; 579 585 client_t *client = NULL; 580 586 581 587 futex_down(&async_futex); 582 link_t *lnk = hash_table_find(&client_hash_table, &key);588 link_t *lnk = hash_table_find(&client_hash_table, key); 583 589 if (lnk) { 584 590 client = hash_table_get_instance(lnk, client_t, link); … … 587 593 client = malloc(sizeof(client_t)); 588 594 if (client) { 589 client->in_task_ hash = client_hash;595 client->in_task_id = client_id; 590 596 client->data = async_client_data_create(); 591 597 592 598 atomic_set(&client->refcnt, 1); 593 hash_table_insert(&client_hash_table, &key, &client->link);599 hash_table_insert(&client_hash_table, key, &client->link); 594 600 } 595 601 } … … 602 608 { 603 609 bool destroy; 604 unsigned long key = client->in_task_hash; 610 unsigned long key[2] = { 611 LOWER32(client->in_task_id), 612 UPPER32(client->in_task_id) 613 }; 605 614 606 615 futex_down(&async_futex); 607 616 608 617 if (atomic_predec(&client->refcnt) == 0) { 609 hash_table_remove(&client_hash_table, &key, 1);618 hash_table_remove(&client_hash_table, key, 2); 610 619 destroy = true; 611 620 } else … … 628 637 } 629 638 630 void *async_get_client_data_by_ hash(sysarg_t client_hash)631 { 632 client_t *client = async_client_get(client_ hash, false);639 void *async_get_client_data_by_id(task_id_t client_id) 640 { 641 client_t *client = async_client_get(client_id, false); 633 642 if (!client) 634 643 return NULL; … … 641 650 } 642 651 643 void async_put_client_data_by_ hash(sysarg_t client_hash)644 { 645 client_t *client = async_client_get(client_ hash, false);652 void async_put_client_data_by_id(task_id_t client_id) 653 { 654 client_t *client = async_client_get(client_id, false); 646 655 647 656 assert(client); … … 680 689 */ 681 690 682 client_t *client = async_client_get(fibril_connection->in_task_ hash, true);691 client_t *client = async_client_get(fibril_connection->in_task_id, true); 683 692 if (!client) { 684 693 ipc_answer_0(fibril_connection->callid, ENOMEM); … … 737 746 * particular fibrils. 738 747 * 739 * @param in_task_ hashIdentification of the incoming connection.748 * @param in_task_id Identification of the incoming connection. 740 749 * @param in_phone_hash Identification of the incoming connection. 741 750 * @param callid Hash of the opening IPC_M_CONNECT_ME_TO call. … … 751 760 * 752 761 */ 753 fid_t async_new_connection( sysarg_t in_task_hash, sysarg_t in_phone_hash,762 fid_t async_new_connection(task_id_t in_task_id, sysarg_t in_phone_hash, 754 763 ipc_callid_t callid, ipc_call_t *call, 755 764 async_client_conn_t cfibril, void *carg) … … 763 772 } 764 773 765 conn->in_task_ hash = in_task_hash;774 conn->in_task_id = in_task_id; 766 775 conn->in_phone_hash = in_phone_hash; 767 776 list_initialize(&conn->msg_queue); … … 822 831 case IPC_M_CONNECT_ME_TO: 823 832 /* Open new connection with fibril, etc. */ 824 async_new_connection(call->in_task_ hash, IPC_GET_ARG5(*call),833 async_new_connection(call->in_task_id, IPC_GET_ARG5(*call), 825 834 callid, call, client_connection, NULL); 826 835 return; … … 970 979 { 971 980 if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS, 972 1, &client_hash_table_ops))981 2, &client_hash_table_ops)) 973 982 abort(); 974 983 … … 986 995 session_ns->arg2 = 0; 987 996 session_ns->arg3 = 0; 997 998 fibril_mutex_initialize(&session_ns->remote_state_mtx); 999 session_ns->remote_state_data = NULL; 988 1000 989 1001 list_initialize(&session_ns->exch_list); … … 1463 1475 return ENOENT; 1464 1476 1465 sysarg_t task_hash;1466 1477 sysarg_t phone_hash; 1467 int rc = async_req_3_5(exch, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3, 1468 NULL, NULL, NULL, &task_hash, &phone_hash); 1478 sysarg_t rc; 1479 1480 aid_t req; 1481 ipc_call_t answer; 1482 req = async_send_3(exch, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3, 1483 &answer); 1484 async_wait_for(req, &rc); 1469 1485 if (rc != EOK) 1470 return rc; 1471 1486 return (int) rc; 1487 1488 phone_hash = IPC_GET_ARG5(answer); 1489 1472 1490 if (client_receiver != NULL) 1473 async_new_connection( task_hash, phone_hash, 0, NULL,1491 async_new_connection(answer.in_task_id, phone_hash, 0, NULL, 1474 1492 client_receiver, carg); 1475 1493 … … 1546 1564 sess->arg3 = 0; 1547 1565 1566 fibril_mutex_initialize(&sess->remote_state_mtx); 1567 sess->remote_state_data = NULL; 1568 1548 1569 list_initialize(&sess->exch_list); 1549 1570 fibril_mutex_initialize(&sess->mutex); … … 1627 1648 sess->arg3 = arg3; 1628 1649 1650 fibril_mutex_initialize(&sess->remote_state_mtx); 1651 sess->remote_state_data = NULL; 1652 1629 1653 list_initialize(&sess->exch_list); 1630 1654 fibril_mutex_initialize(&sess->mutex); … … 1632 1656 1633 1657 return sess; 1658 } 1659 1660 /** Set arguments for new connections. 1661 * 1662 * FIXME This is an ugly hack to work around the problem that parallel 1663 * exchanges are implemented using parallel connections. When we create 1664 * a callback session, the framework does not know arguments for the new 1665 * connections. 1666 * 1667 * The proper solution seems to be to implement parallel exchanges using 1668 * tagging. 1669 */ 1670 void async_sess_args_set(async_sess_t *sess, sysarg_t arg1, sysarg_t arg2, 1671 sysarg_t arg3) 1672 { 1673 sess->arg1 = arg1; 1674 sess->arg2 = arg2; 1675 sess->arg3 = arg3; 1634 1676 } 1635 1677 … … 1677 1719 sess->arg3 = arg3; 1678 1720 1721 fibril_mutex_initialize(&sess->remote_state_mtx); 1722 sess->remote_state_data = NULL; 1723 1679 1724 list_initialize(&sess->exch_list); 1680 1725 fibril_mutex_initialize(&sess->mutex); … … 1707 1752 sess->arg2 = 0; 1708 1753 sess->arg3 = 0; 1754 1755 fibril_mutex_initialize(&sess->remote_state_mtx); 1756 sess->remote_state_data = NULL; 1709 1757 1710 1758 list_initialize(&sess->exch_list); … … 2371 2419 sess->arg3 = 0; 2372 2420 2421 fibril_mutex_initialize(&sess->remote_state_mtx); 2422 sess->remote_state_data = NULL; 2423 2373 2424 list_initialize(&sess->exch_list); 2374 2425 fibril_mutex_initialize(&sess->mutex); … … 2417 2468 sess->arg3 = 0; 2418 2469 2470 fibril_mutex_initialize(&sess->remote_state_mtx); 2471 sess->remote_state_data = NULL; 2472 2419 2473 list_initialize(&sess->exch_list); 2420 2474 fibril_mutex_initialize(&sess->mutex); … … 2458 2512 sess->arg2 = 0; 2459 2513 sess->arg3 = 0; 2514 2515 fibril_mutex_initialize(&sess->remote_state_mtx); 2516 sess->remote_state_data = NULL; 2460 2517 2461 2518 list_initialize(&sess->exch_list); … … 2499 2556 } 2500 2557 2558 /** Lock and get session remote state 2559 * 2560 * Lock and get the local replica of the remote state 2561 * in stateful sessions. The call should be paired 2562 * with async_remote_state_release*(). 2563 * 2564 * @param[in] sess Stateful session. 2565 * 2566 * @return Local replica of the remote state. 2567 * 2568 */ 2569 void *async_remote_state_acquire(async_sess_t *sess) 2570 { 2571 fibril_mutex_lock(&sess->remote_state_mtx); 2572 return sess->remote_state_data; 2573 } 2574 2575 /** Update the session remote state 2576 * 2577 * Update the local replica of the remote state 2578 * in stateful sessions. The remote state must 2579 * be already locked. 2580 * 2581 * @param[in] sess Stateful session. 2582 * @param[in] state New local replica of the remote state. 2583 * 2584 */ 2585 void async_remote_state_update(async_sess_t *sess, void *state) 2586 { 2587 assert(fibril_mutex_is_locked(&sess->remote_state_mtx)); 2588 sess->remote_state_data = state; 2589 } 2590 2591 /** Release the session remote state 2592 * 2593 * Unlock the local replica of the remote state 2594 * in stateful sessions. 2595 * 2596 * @param[in] sess Stateful session. 2597 * 2598 */ 2599 void async_remote_state_release(async_sess_t *sess) 2600 { 2601 assert(fibril_mutex_is_locked(&sess->remote_state_mtx)); 2602 2603 fibril_mutex_unlock(&sess->remote_state_mtx); 2604 } 2605 2606 /** Release the session remote state and end an exchange 2607 * 2608 * Unlock the local replica of the remote state 2609 * in stateful sessions. This is convenience function 2610 * which gets the session pointer from the exchange 2611 * and also ends the exchange. 2612 * 2613 * @param[in] exch Stateful session's exchange. 2614 * 2615 */ 2616 void async_remote_state_release_exchange(async_exch_t *exch) 2617 { 2618 if (exch == NULL) 2619 return; 2620 2621 async_sess_t *sess = exch->sess; 2622 assert(fibril_mutex_is_locked(&sess->remote_state_mtx)); 2623 2624 async_exchange_end(exch); 2625 fibril_mutex_unlock(&sess->remote_state_mtx); 2626 } 2627 2501 2628 /** @} 2502 2629 */
Note:
See TracChangeset
for help on using the changeset viewer.