Changeset 95c675b in mainline for uspace/lib/c/generic/async.c


Ignore:
Timestamp:
2017-10-17T13:11:35Z (8 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
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.
Message:

Merge mainline

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/async.c

    rdbf32b1 r95c675b  
    106106#include <fibril.h>
    107107#include <adt/hash_table.h>
     108#include <adt/hash.h>
    108109#include <adt/list.h>
    109110#include <assert.h>
     
    587588};
    588589
    589 /** Compute hash into the connection hash table based on the source phone hash.
    590  *
    591  * @param key Pointer to source phone hash.
     590typedef 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.
    592603 *
    593604 * @return Index into the connection hash table.
     
    596607static size_t conn_key_hash(void *key)
    597608{
    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;
    600616}
    601617
     
    603619{
    604620        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        });
    606625}
    607626
    608627static bool conn_key_equal(void *key, const ht_link_t *item)
    609628{
    610         sysarg_t in_phone_hash = *(sysarg_t *) key;
     629        conn_key_t *ck = (conn_key_t *) key;
    611630        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));
    613633}
    614634
     
    716736         */
    717737        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        });
    719742        futex_up(&async_futex);
    720743       
     
    951974        futex_down(&async_futex);
    952975       
    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        });
    954980        if (!link) {
    955981                futex_up(&async_futex);
     
    10221048 *
    10231049 * @param inr     IRQ number.
    1024  * @param devno   Device number of the device generating inr.
    10251050 * @param handler Notification handler.
    10261051 * @param data    Notification handler client data.
    10271052 * @param ucode   Top-half pseudocode handler.
    10281053 *
    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 */
     1058int async_irq_subscribe(int inr, async_notification_handler_t handler,
     1059    void *data, const irq_code_t *ucode)
    10341060{
    10351061        notification_t *notification =
     
    10511077        futex_up(&async_futex);
    10521078       
    1053         return ipc_irq_subscribe(inr, devno, imethod, ucode);
     1079        return ipc_irq_subscribe(inr, imethod, ucode);
    10541080}
    10551081
    10561082/** Unsubscribe from IRQ notification.
    10571083 *
    1058  * @param inr     IRQ number.
    1059  * @param devno   Device number of the device generating inr.
     1084 * @param cap     IRQ capability handle.
    10601085 *
    10611086 * @return Zero on success or a negative error code.
    10621087 *
    10631088 */
    1064 int async_irq_unsubscribe(int inr, int devno)
     1089int async_irq_unsubscribe(int cap)
    10651090{
    10661091        // TODO: Remove entry from hash table
    10671092        //       to avoid memory leak
    10681093       
    1069         return ipc_irq_unsubscribe(inr, devno);
     1094        return ipc_irq_unsubscribe(cap);
    10701095}
    10711096
     
    13581383                async_new_connection(call->in_task_id, in_phone_hash, callid,
    13591384                    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 altogether
    1366                
    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);
    13701385                return;
    13711386        }
     
    20852100       
    20862101        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;
    21592102}
    21602103
     
    31273070}
    31283071
    3129 /** Wrapper for sending an exchange over different exchange for cloning
    3130  *
    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 new
    3143  * 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 
    31893072/** Wrapper for receiving the IPC_M_CONNECT_TO_ME calls.
    31903073 *
Note: See TracChangeset for help on using the changeset viewer.