Changeset 91b60499 in mainline for uspace/lib/c/generic/async.c


Ignore:
Timestamp:
2017-09-30T06:29:42Z (7 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
300f4c4
Parents:
d076f16 (diff), 6636fb19 (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 support for capabilities from lp:~jakub/helenos/caps

This commit introduces capabilities as task-local names for references to kernel
objects. Kernel objects are reference-counted wrappers for a select group of
objects allocated in and by the kernel that can be made accessible to userspace
in a controlled way via integer handles.

So far, a kernel object encapsulates either an irq_t or a phone_t.

Support for the former lead to the removal of kernel-assigned devnos and
unsecure deregistration of IRQs in which a random task was able to unregister
some other task's IRQ.

File:
1 edited

Legend:

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

    rd076f16 r91b60499  
    10481048 *
    10491049 * @param inr     IRQ number.
    1050  * @param devno   Device number of the device generating inr.
    10511050 * @param handler Notification handler.
    10521051 * @param data    Notification handler client data.
    10531052 * @param ucode   Top-half pseudocode handler.
    10541053 *
    1055  * @return Zero on success or a negative error code.
    1056  *
    1057  */
    1058 int async_irq_subscribe(int inr, int devno,
    1059     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)
    10601060{
    10611061        notification_t *notification =
     
    10771077        futex_up(&async_futex);
    10781078       
    1079         return ipc_irq_subscribe(inr, devno, imethod, ucode);
     1079        return ipc_irq_subscribe(inr, imethod, ucode);
    10801080}
    10811081
    10821082/** Unsubscribe from IRQ notification.
    10831083 *
    1084  * @param inr     IRQ number.
    1085  * @param devno   Device number of the device generating inr.
     1084 * @param cap     IRQ capability handle.
    10861085 *
    10871086 * @return Zero on success or a negative error code.
    10881087 *
    10891088 */
    1090 int async_irq_unsubscribe(int inr, int devno)
     1089int async_irq_unsubscribe(int cap)
    10911090{
    10921091        // TODO: Remove entry from hash table
    10931092        //       to avoid memory leak
    10941093       
    1095         return ipc_irq_unsubscribe(inr, devno);
     1094        return ipc_irq_unsubscribe(cap);
    10961095}
    10971096
     
    13841383                async_new_connection(call->in_task_id, in_phone_hash, callid,
    13851384                    call, handler, data);
    1386                 return;
    1387         }
    1388        
    1389         /* Cloned connection */
    1390         if (IPC_GET_IMETHOD(*call) == IPC_M_CLONE_ESTABLISH) {
    1391                 // TODO: Currently ignores ports altogether
    1392                
    1393                 /* Open new connection with fibril, etc. */
    1394                 async_new_connection(call->in_task_id, IPC_GET_ARG5(*call),
    1395                     callid, call, fallback_port_handler, fallback_port_data);
    13961385                return;
    13971386        }
     
    21112100       
    21122101        return EOK;
    2113 }
    2114 
    2115 /** Wrapper for making IPC_M_CLONE_ESTABLISH calls using the async framework.
    2116  *
    2117  * Ask for a cloned connection to some service.
    2118  *
    2119  * @param mgmt Exchange management style.
    2120  * @param exch Exchange for sending the message.
    2121  *
    2122  * @return New session on success or NULL on error.
    2123  *
    2124  */
    2125 async_sess_t *async_clone_establish(exch_mgmt_t mgmt, async_exch_t *exch)
    2126 {
    2127         if (exch == NULL) {
    2128                 errno = ENOENT;
    2129                 return NULL;
    2130         }
    2131        
    2132         async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
    2133         if (sess == NULL) {
    2134                 errno = ENOMEM;
    2135                 return NULL;
    2136         }
    2137        
    2138         ipc_call_t result;
    2139        
    2140         amsg_t *msg = amsg_create();
    2141         if (!msg) {
    2142                 free(sess);
    2143                 errno = ENOMEM;
    2144                 return NULL;
    2145         }
    2146        
    2147         msg->dataptr = &result;
    2148         msg->wdata.active = true;
    2149        
    2150         ipc_call_async_0(exch->phone, IPC_M_CLONE_ESTABLISH, msg,
    2151             reply_received);
    2152        
    2153         sysarg_t rc;
    2154         async_wait_for((aid_t) msg, &rc);
    2155        
    2156         if (rc != EOK) {
    2157                 errno = rc;
    2158                 free(sess);
    2159                 return NULL;
    2160         }
    2161        
    2162         int phone = (int) IPC_GET_ARG5(result);
    2163        
    2164         if (phone < 0) {
    2165                 errno = phone;
    2166                 free(sess);
    2167                 return NULL;
    2168         }
    2169        
    2170         sess->iface = 0;
    2171         sess->mgmt = mgmt;
    2172         sess->phone = phone;
    2173         sess->arg1 = 0;
    2174         sess->arg2 = 0;
    2175         sess->arg3 = 0;
    2176        
    2177         fibril_mutex_initialize(&sess->remote_state_mtx);
    2178         sess->remote_state_data = NULL;
    2179        
    2180         list_initialize(&sess->exch_list);
    2181         fibril_mutex_initialize(&sess->mutex);
    2182         atomic_set(&sess->refcnt, 0);
    2183        
    2184         return sess;
    21852102}
    21862103
     
    31533070}
    31543071
    3155 /** Wrapper for sending an exchange over different exchange for cloning
    3156  *
    3157  * @param exch       Exchange to be used for sending.
    3158  * @param clone_exch Exchange to be cloned.
    3159  *
    3160  */
    3161 int async_exchange_clone(async_exch_t *exch, async_exch_t *clone_exch)
    3162 {
    3163         return async_req_1_0(exch, IPC_M_CONNECTION_CLONE, clone_exch->phone);
    3164 }
    3165 
    3166 /** Wrapper for receiving the IPC_M_CONNECTION_CLONE calls.
    3167  *
    3168  * If the current call is IPC_M_CONNECTION_CLONE then a new
    3169  * async session is created for the accepted phone.
    3170  *
    3171  * @param mgmt Exchange management style.
    3172  *
    3173  * @return New async session or NULL on failure.
    3174  *
    3175  */
    3176 async_sess_t *async_clone_receive(exch_mgmt_t mgmt)
    3177 {
    3178         /* Accept the phone */
    3179         ipc_call_t call;
    3180         ipc_callid_t callid = async_get_call(&call);
    3181         int phone = (int) IPC_GET_ARG1(call);
    3182        
    3183         if ((IPC_GET_IMETHOD(call) != IPC_M_CONNECTION_CLONE) ||
    3184             (phone < 0)) {
    3185                 async_answer_0(callid, EINVAL);
    3186                 return NULL;
    3187         }
    3188        
    3189         async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
    3190         if (sess == NULL) {
    3191                 async_answer_0(callid, ENOMEM);
    3192                 return NULL;
    3193         }
    3194        
    3195         sess->iface = 0;
    3196         sess->mgmt = mgmt;
    3197         sess->phone = phone;
    3198         sess->arg1 = 0;
    3199         sess->arg2 = 0;
    3200         sess->arg3 = 0;
    3201        
    3202         fibril_mutex_initialize(&sess->remote_state_mtx);
    3203         sess->remote_state_data = NULL;
    3204        
    3205         list_initialize(&sess->exch_list);
    3206         fibril_mutex_initialize(&sess->mutex);
    3207         atomic_set(&sess->refcnt, 0);
    3208        
    3209         /* Acknowledge the cloned phone */
    3210         async_answer_0(callid, EOK);
    3211        
    3212         return sess;
    3213 }
    3214 
    32153072/** Wrapper for receiving the IPC_M_CONNECT_TO_ME calls.
    32163073 *
Note: See TracChangeset for help on using the changeset viewer.