Changeset 95c675b in mainline for uspace/lib/c/generic/async.c
- Timestamp:
- 2017-10-17T13:11:35Z (8 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 60af4cdb
- Parents:
- dbf32b1 (diff), a416d070 (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
rdbf32b1 r95c675b 106 106 #include <fibril.h> 107 107 #include <adt/hash_table.h> 108 #include <adt/hash.h> 108 109 #include <adt/list.h> 109 110 #include <assert.h> … … 587 588 }; 588 589 589 /** Compute hash into the connection hash table based on the source phone hash. 590 * 591 * @param key Pointer to source phone hash. 590 typedef struct { 591 task_id_t task_id; 592 sysarg_t phone_hash; 593 } conn_key_t; 594 595 /** Compute hash into the connection hash table 596 * 597 * The hash is based on the source task ID and the source phone hash. The task 598 * ID is included in the hash because a phone hash alone might not be unique 599 * while we still track connections for killed tasks due to kernel's recycling 600 * of phone structures. 601 * 602 * @param key Pointer to the connection key structure. 592 603 * 593 604 * @return Index into the connection hash table. … … 596 607 static size_t conn_key_hash(void *key) 597 608 { 598 sysarg_t in_phone_hash = *(sysarg_t *) key; 599 return in_phone_hash; 609 conn_key_t *ck = (conn_key_t *) key; 610 611 size_t hash = 0; 612 hash = hash_combine(hash, LOWER32(ck->task_id)); 613 hash = hash_combine(hash, UPPER32(ck->task_id)); 614 hash = hash_combine(hash, ck->phone_hash); 615 return hash; 600 616 } 601 617 … … 603 619 { 604 620 connection_t *conn = hash_table_get_inst(item, connection_t, link); 605 return conn_key_hash(&conn->in_phone_hash); 621 return conn_key_hash(&(conn_key_t){ 622 .task_id = conn->in_task_id, 623 .phone_hash = conn->in_phone_hash 624 }); 606 625 } 607 626 608 627 static bool conn_key_equal(void *key, const ht_link_t *item) 609 628 { 610 sysarg_t in_phone_hash = *(sysarg_t *) key;629 conn_key_t *ck = (conn_key_t *) key; 611 630 connection_t *conn = hash_table_get_inst(item, connection_t, link); 612 return (in_phone_hash == conn->in_phone_hash); 631 return ((ck->task_id == conn->in_task_id) && 632 (ck->phone_hash == conn->in_phone_hash)); 613 633 } 614 634 … … 716 736 */ 717 737 futex_down(&async_futex); 718 hash_table_remove(&conn_hash_table, &fibril_connection->in_phone_hash); 738 hash_table_remove(&conn_hash_table, &(conn_key_t){ 739 .task_id = fibril_connection->in_task_id, 740 .phone_hash = fibril_connection->in_phone_hash 741 }); 719 742 futex_up(&async_futex); 720 743 … … 951 974 futex_down(&async_futex); 952 975 953 ht_link_t *link = hash_table_find(&conn_hash_table, &call->in_phone_hash); 976 ht_link_t *link = hash_table_find(&conn_hash_table, &(conn_key_t){ 977 .task_id = call->in_task_id, 978 .phone_hash = call->in_phone_hash 979 }); 954 980 if (!link) { 955 981 futex_up(&async_futex); … … 1022 1048 * 1023 1049 * @param inr IRQ number. 1024 * @param devno Device number of the device generating inr.1025 1050 * @param handler Notification handler. 1026 1051 * @param data Notification handler client data. 1027 1052 * @param ucode Top-half pseudocode handler. 1028 1053 * 1029 * @return Zero on success or a negative error code. 1030 * 1031 */ 1032 int async_irq_subscribe(int inr, int devno, 1033 async_notification_handler_t handler, void *data, const irq_code_t *ucode) 1054 * @return IRQ capability handle on success. 1055 * @return Negative error code. 1056 * 1057 */ 1058 int async_irq_subscribe(int inr, async_notification_handler_t handler, 1059 void *data, const irq_code_t *ucode) 1034 1060 { 1035 1061 notification_t *notification = … … 1051 1077 futex_up(&async_futex); 1052 1078 1053 return ipc_irq_subscribe(inr, devno,imethod, ucode);1079 return ipc_irq_subscribe(inr, imethod, ucode); 1054 1080 } 1055 1081 1056 1082 /** Unsubscribe from IRQ notification. 1057 1083 * 1058 * @param inr IRQ number. 1059 * @param devno Device number of the device generating inr. 1084 * @param cap IRQ capability handle. 1060 1085 * 1061 1086 * @return Zero on success or a negative error code. 1062 1087 * 1063 1088 */ 1064 int async_irq_unsubscribe(int inr, int devno)1089 int async_irq_unsubscribe(int cap) 1065 1090 { 1066 1091 // TODO: Remove entry from hash table 1067 1092 // to avoid memory leak 1068 1093 1069 return ipc_irq_unsubscribe( inr, devno);1094 return ipc_irq_unsubscribe(cap); 1070 1095 } 1071 1096 … … 1358 1383 async_new_connection(call->in_task_id, in_phone_hash, callid, 1359 1384 call, handler, data); 1360 return;1361 }1362 1363 /* Cloned connection */1364 if (IPC_GET_IMETHOD(*call) == IPC_M_CLONE_ESTABLISH) {1365 // TODO: Currently ignores ports altogether1366 1367 /* Open new connection with fibril, etc. */1368 async_new_connection(call->in_task_id, IPC_GET_ARG5(*call),1369 callid, call, fallback_port_handler, fallback_port_data);1370 1385 return; 1371 1386 } … … 2085 2100 2086 2101 return EOK; 2087 }2088 2089 /** Wrapper for making IPC_M_CLONE_ESTABLISH calls using the async framework.2090 *2091 * Ask for a cloned connection to some service.2092 *2093 * @param mgmt Exchange management style.2094 * @param exch Exchange for sending the message.2095 *2096 * @return New session on success or NULL on error.2097 *2098 */2099 async_sess_t *async_clone_establish(exch_mgmt_t mgmt, async_exch_t *exch)2100 {2101 if (exch == NULL) {2102 errno = ENOENT;2103 return NULL;2104 }2105 2106 async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));2107 if (sess == NULL) {2108 errno = ENOMEM;2109 return NULL;2110 }2111 2112 ipc_call_t result;2113 2114 amsg_t *msg = amsg_create();2115 if (!msg) {2116 free(sess);2117 errno = ENOMEM;2118 return NULL;2119 }2120 2121 msg->dataptr = &result;2122 msg->wdata.active = true;2123 2124 ipc_call_async_0(exch->phone, IPC_M_CLONE_ESTABLISH, msg,2125 reply_received);2126 2127 sysarg_t rc;2128 async_wait_for((aid_t) msg, &rc);2129 2130 if (rc != EOK) {2131 errno = rc;2132 free(sess);2133 return NULL;2134 }2135 2136 int phone = (int) IPC_GET_ARG5(result);2137 2138 if (phone < 0) {2139 errno = phone;2140 free(sess);2141 return NULL;2142 }2143 2144 sess->iface = 0;2145 sess->mgmt = mgmt;2146 sess->phone = phone;2147 sess->arg1 = 0;2148 sess->arg2 = 0;2149 sess->arg3 = 0;2150 2151 fibril_mutex_initialize(&sess->remote_state_mtx);2152 sess->remote_state_data = NULL;2153 2154 list_initialize(&sess->exch_list);2155 fibril_mutex_initialize(&sess->mutex);2156 atomic_set(&sess->refcnt, 0);2157 2158 return sess;2159 2102 } 2160 2103 … … 3127 3070 } 3128 3071 3129 /** Wrapper for sending an exchange over different exchange for cloning3130 *3131 * @param exch Exchange to be used for sending.3132 * @param clone_exch Exchange to be cloned.3133 *3134 */3135 int async_exchange_clone(async_exch_t *exch, async_exch_t *clone_exch)3136 {3137 return async_req_1_0(exch, IPC_M_CONNECTION_CLONE, clone_exch->phone);3138 }3139 3140 /** Wrapper for receiving the IPC_M_CONNECTION_CLONE calls.3141 *3142 * If the current call is IPC_M_CONNECTION_CLONE then a new3143 * async session is created for the accepted phone.3144 *3145 * @param mgmt Exchange management style.3146 *3147 * @return New async session or NULL on failure.3148 *3149 */3150 async_sess_t *async_clone_receive(exch_mgmt_t mgmt)3151 {3152 /* Accept the phone */3153 ipc_call_t call;3154 ipc_callid_t callid = async_get_call(&call);3155 int phone = (int) IPC_GET_ARG1(call);3156 3157 if ((IPC_GET_IMETHOD(call) != IPC_M_CONNECTION_CLONE) ||3158 (phone < 0)) {3159 async_answer_0(callid, EINVAL);3160 return NULL;3161 }3162 3163 async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));3164 if (sess == NULL) {3165 async_answer_0(callid, ENOMEM);3166 return NULL;3167 }3168 3169 sess->iface = 0;3170 sess->mgmt = mgmt;3171 sess->phone = phone;3172 sess->arg1 = 0;3173 sess->arg2 = 0;3174 sess->arg3 = 0;3175 3176 fibril_mutex_initialize(&sess->remote_state_mtx);3177 sess->remote_state_data = NULL;3178 3179 list_initialize(&sess->exch_list);3180 fibril_mutex_initialize(&sess->mutex);3181 atomic_set(&sess->refcnt, 0);3182 3183 /* Acknowledge the cloned phone */3184 async_answer_0(callid, EOK);3185 3186 return sess;3187 }3188 3189 3072 /** Wrapper for receiving the IPC_M_CONNECT_TO_ME calls. 3190 3073 *
Note:
See TracChangeset
for help on using the changeset viewer.