Changeset 01c3bb4 in mainline for uspace/lib/c/generic/ipc.c


Ignore:
Timestamp:
2017-11-25T15:43:25Z (6 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ce4a21a0
Parents:
98cb5e0d
Message:

Convert call-handling syscalls to capabilities

This commit modifies the behavior of sys_ipc_wait_for_call() to return a
capability handle for requests. This capability handle can be used
either by sys_ipc_answer*() to answer the call or by sys_ipc_forward*()
to forward it further along. Answering or forwarding the call results in
destruction of the respective capability. For requests and
notifications, sys_ipc_wait_for_call() returns CAP_NIL and sets call
flags accordingly.

File:
1 edited

Legend:

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

    r98cb5e0d r01c3bb4  
    5959        struct {
    6060                ipc_call_t data;
    61                 int phoneid;
    6261        } msg;
    6362} async_call_t;
     
    9190/** Epilogue for ipc_call_async_*() functions.
    9291 *
    93  * @param callid      Value returned by the SYS_IPC_CALL_ASYNC_* syscall.
    94  * @param phoneid     Phone handle through which the call was made.
    95  * @param call        Structure returned by ipc_prepare_async().
    96  */
    97 static inline void ipc_finish_async(ipc_callid_t callid, int phoneid,
    98     async_call_t *call)
     92 * @param rc       Value returned by the SYS_IPC_CALL_ASYNC_* syscall.
     93 * @param call     Structure returned by ipc_prepare_async().
     94 */
     95static inline void ipc_finish_async(int rc, async_call_t *call)
    9996{
    10097        if (!call) {
     
    103100        }
    104101       
    105         if (callid == (ipc_callid_t) IPC_CALLRET_FATAL) {
     102        if (rc == IPC_CALLRET_FATAL) {
    106103                /* Call asynchronous handler with error code */
    107104                if (call->callback)
     
    124121 * error code. If the call cannot be temporarily made, it is queued.
    125122 *
    126  * @param phoneid     Phone handle for the call.
    127  * @param imethod     Requested interface and method.
    128  * @param arg1        Service-defined payload argument.
    129  * @param arg2        Service-defined payload argument.
    130  * @param arg3        Service-defined payload argument.
    131  * @param private     Argument to be passed to the answer/error callback.
    132  * @param callback    Answer or error callback.
    133  */
    134 void ipc_call_async_fast(int phoneid, sysarg_t imethod, sysarg_t arg1,
     123 * @param phandle   Phone handle for the call.
     124 * @param imethod   Requested interface and method.
     125 * @param arg1      Service-defined payload argument.
     126 * @param arg2      Service-defined payload argument.
     127 * @param arg3      Service-defined payload argument.
     128 * @param private   Argument to be passed to the answer/error callback.
     129 * @param callback  Answer or error callback.
     130 */
     131void ipc_call_async_fast(cap_handle_t phandle, sysarg_t imethod, sysarg_t arg1,
    135132    sysarg_t arg2, sysarg_t arg3, void *private, ipc_async_callback_t callback)
    136133{
     
    139136                return;
    140137       
    141         ipc_callid_t callid = __SYSCALL6(SYS_IPC_CALL_ASYNC_FAST, phoneid,
    142             imethod, arg1, arg2, arg3, (sysarg_t) call);
    143        
    144         ipc_finish_async(callid, phoneid, call);
     138        int rc = __SYSCALL6(SYS_IPC_CALL_ASYNC_FAST, phandle, imethod, arg1,
     139            arg2, arg3, (sysarg_t) call);
     140       
     141        ipc_finish_async(rc, call);
    145142}
    146143
     
    153150 * error code. If the call cannot be temporarily made, it is queued.
    154151 *
    155  * @param phoneid     Phone handle for the call.
    156  * @param imethod     Requested interface and method.
    157  * @param arg1        Service-defined payload argument.
    158  * @param arg2        Service-defined payload argument.
    159  * @param arg3        Service-defined payload argument.
    160  * @param arg4        Service-defined payload argument.
    161  * @param arg5        Service-defined payload argument.
    162  * @param private     Argument to be passed to the answer/error callback.
    163  * @param callback    Answer or error callback.
    164  */
    165 void ipc_call_async_slow(int phoneid, sysarg_t imethod, sysarg_t arg1,
     152 * @param phandle   Phone handle for the call.
     153 * @param imethod   Requested interface and method.
     154 * @param arg1      Service-defined payload argument.
     155 * @param arg2      Service-defined payload argument.
     156 * @param arg3      Service-defined payload argument.
     157 * @param arg4      Service-defined payload argument.
     158 * @param arg5      Service-defined payload argument.
     159 * @param private   Argument to be passed to the answer/error callback.
     160 * @param callback  Answer or error callback.
     161 */
     162void ipc_call_async_slow(int phandle, sysarg_t imethod, sysarg_t arg1,
    166163    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, void *private,
    167164    ipc_async_callback_t callback)
     
    178175        IPC_SET_ARG5(call->msg.data, arg5);
    179176       
    180         ipc_callid_t callid = __SYSCALL3(SYS_IPC_CALL_ASYNC_SLOW, phoneid,
     177        int rc = __SYSCALL3(SYS_IPC_CALL_ASYNC_SLOW, phandle,
    181178            (sysarg_t) &call->msg.data, (sysarg_t) call);
    182179       
    183         ipc_finish_async(callid, phoneid, call);
     180        ipc_finish_async(rc, call);
    184181}
    185182
     
    189186 * registers. If you need to return more, use the ipc_answer_slow() instead.
    190187 *
    191  * @param callid Hash of the call being answered.
    192  * @param retval Return value.
    193  * @param arg1   First return argument.
    194  * @param arg2   Second return argument.
    195  * @param arg3   Third return argument.
    196  * @param arg4   Fourth return argument.
     188 * @param chandle  Handle of the call being answered.
     189 * @param retval   Return value.
     190 * @param arg1     First return argument.
     191 * @param arg2     Second return argument.
     192 * @param arg3     Third return argument.
     193 * @param arg4     Fourth return argument.
    197194 *
    198195 * @return Zero on success.
     
    200197 *
    201198 */
    202 sysarg_t ipc_answer_fast(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,
     199sysarg_t ipc_answer_fast(cap_handle_t chandle, sysarg_t retval, sysarg_t arg1,
    203200    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4)
    204201{
    205         return __SYSCALL6(SYS_IPC_ANSWER_FAST, callid, retval, arg1, arg2, arg3,
    206             arg4);
     202        return __SYSCALL6(SYS_IPC_ANSWER_FAST, chandle, retval, arg1, arg2,
     203            arg3, arg4);
    207204}
    208205
    209206/** Answer received call (entire payload).
    210207 *
    211  * @param callid Hash of the call being answered.
    212  * @param retval Return value.
    213  * @param arg1   First return argument.
    214  * @param arg2   Second return argument.
    215  * @param arg3   Third return argument.
    216  * @param arg4   Fourth return argument.
    217  * @param arg5   Fifth return argument.
     208 * @param chandle  Handle of the call being answered.
     209 * @param retval   Return value.
     210 * @param arg1     First return argument.
     211 * @param arg2     Second return argument.
     212 * @param arg3     Third return argument.
     213 * @param arg4     Fourth return argument.
     214 * @param arg5     Fifth return argument.
    218215 *
    219216 * @return Zero on success.
     
    221218 *
    222219 */
    223 sysarg_t ipc_answer_slow(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,
     220sysarg_t ipc_answer_slow(cap_handle_t chandle, sysarg_t retval, sysarg_t arg1,
    224221    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5)
    225222{
     
    233230        IPC_SET_ARG5(data, arg5);
    234231       
    235         return __SYSCALL2(SYS_IPC_ANSWER_SLOW, callid, (sysarg_t) &data);
     232        return __SYSCALL2(SYS_IPC_ANSWER_SLOW, chandle, (sysarg_t) &data);
    236233}
    237234
    238235/** Handle received answer.
    239236 *
    240  * @param callid Hash of the received answer.
    241  * @param data   Call data of the answer.
    242  */
    243 static void handle_answer(ipc_callid_t callid, ipc_call_t *data)
     237 * @param data  Call data of the answer.
     238 */
     239static void handle_answer(ipc_call_t *data)
    244240{
    245241        async_call_t *call = data->label;
     
    255251/** Wait for first IPC call to come.
    256252 *
     253 * @param call   Incoming call storage.
     254 * @param usec   Timeout in microseconds
     255 * @param flags  Flags passed to SYS_IPC_WAIT (blocking, nonblocking).
     256 *
     257 * @return  Call handle.
     258 * @return  Negative error code.
     259 */
     260cap_handle_t ipc_wait_cycle(ipc_call_t *call, sysarg_t usec, unsigned int flags)
     261{
     262        cap_handle_t chandle =
     263            __SYSCALL3(SYS_IPC_WAIT, (sysarg_t) call, usec, flags);
     264       
     265        /* Handle received answers */
     266        if ((chandle == CAP_NIL) && (call->flags & IPC_CALLID_ANSWERED))
     267                handle_answer(call);
     268       
     269        return chandle;
     270}
     271
     272/** Interrupt one thread of this task from waiting for IPC.
     273 *
     274 */
     275void ipc_poke(void)
     276{
     277        __SYSCALL0(SYS_IPC_POKE);
     278}
     279
     280/** Wait for first IPC call to come.
     281 *
     282 * Only requests are returned, answers are processed internally.
     283 *
    257284 * @param call  Incoming call storage.
    258285 * @param usec  Timeout in microseconds
    259  * @param flags Flags passed to SYS_IPC_WAIT (blocking, nonblocking).
    260  *
    261  * @return Hash of the call.
    262  */
    263 ipc_callid_t ipc_wait_cycle(ipc_call_t *call, sysarg_t usec,
    264     unsigned int flags)
    265 {
    266         ipc_callid_t callid =
    267             __SYSCALL3(SYS_IPC_WAIT, (sysarg_t) call, usec, flags);
    268        
    269         /* Handle received answers */
    270         if (callid && (call->flags & IPC_CALLID_ANSWERED))
    271                 handle_answer(callid, call);
    272        
    273         return callid;
    274 }
    275 
    276 /** Interrupt one thread of this task from waiting for IPC.
    277  *
    278  */
    279 void ipc_poke(void)
    280 {
    281         __SYSCALL0(SYS_IPC_POKE);
    282 }
    283 
    284 /** Wait for first IPC call to come.
     286 *
     287 * @return  Call handle.
     288 * @return  Negative error code.
     289 *
     290 */
     291cap_handle_t ipc_wait_for_call_timeout(ipc_call_t *call, sysarg_t usec)
     292{
     293        cap_handle_t chandle;
     294       
     295        do {
     296                chandle = ipc_wait_cycle(call, usec, SYNCH_FLAGS_NONE);
     297        } while ((chandle == CAP_NIL) && (call->flags & IPC_CALLID_ANSWERED));
     298       
     299        return chandle;
     300}
     301
     302/** Check if there is an IPC call waiting to be picked up.
    285303 *
    286304 * Only requests are returned, answers are processed internally.
    287305 *
    288  * @param call Incoming call storage.
    289  * @param usec Timeout in microseconds
    290  *
    291  * @return Hash of the call.
    292  *
    293  */
    294 ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *call, sysarg_t usec)
    295 {
    296         ipc_callid_t callid;
     306 * @param call  Incoming call storage.
     307 *
     308 * @return  Call handle.
     309 * @return  Negative error code.
     310 *
     311 */
     312cap_handle_t ipc_trywait_for_call(ipc_call_t *call)
     313{
     314        cap_handle_t chandle;
    297315       
    298316        do {
    299                 callid = ipc_wait_cycle(call, usec, SYNCH_FLAGS_NONE);
    300         } while (callid && (call->flags & IPC_CALLID_ANSWERED));
    301        
    302         return callid;
    303 }
    304 
    305 /** Check if there is an IPC call waiting to be picked up.
    306  *
    307  * Only requests are returned, answers are processed internally.
    308  *
    309  * @param call Incoming call storage.
    310  *
    311  * @return Hash of the call.
    312  *
    313  */
    314 ipc_callid_t ipc_trywait_for_call(ipc_call_t *call)
    315 {
    316         ipc_callid_t callid;
    317        
    318         do {
    319                 callid = ipc_wait_cycle(call, SYNCH_NO_TIMEOUT,
     317                chandle = ipc_wait_cycle(call, SYNCH_NO_TIMEOUT,
    320318                    SYNCH_FLAGS_NON_BLOCKING);
    321         } while (callid && (call->flags & IPC_CALLID_ANSWERED));
    322        
    323         return callid;
     319        } while ((chandle == CAP_NIL) && (call->flags & IPC_CALLID_ANSWERED));
     320       
     321        return chandle;
    324322}
    325323
    326324/** Hang up a phone.
    327325 *
    328  * @param phoneid Handle of the phone to be hung up.
    329  *
    330  * @return Zero on success or a negative error code.
    331  *
    332  */
    333 int ipc_hangup(int phoneid)
    334 {
    335         return __SYSCALL1(SYS_IPC_HANGUP, phoneid);
     326 * @param phandle Handle of the phone to be hung up.
     327 *
     328 * @return  Zero on success or a negative error code.
     329 *
     330 */
     331int ipc_hangup(cap_handle_t phandle)
     332{
     333        return __SYSCALL1(SYS_IPC_HANGUP, phandle);
    336334}
    337335
    338336/** Forward a received call to another destination.
    339337 *
    340  * For non-system methods, the old method, arg1 and arg2 are rewritten
    341  * by the new values. For system methods, the new method, arg1 and arg2
    342  * are written to the old arg1, arg2 and arg3, respectivelly. Calls with
    343  * immutable methods are forwarded verbatim.
    344  *
    345  * @param callid  Hash of the call to forward.
    346  * @param phoneid Phone handle to use for forwarding.
    347  * @param imethod New interface and method for the forwarded call.
    348  * @param arg1    New value of the first argument for the forwarded call.
    349  * @param arg2    New value of the second argument for the forwarded call.
    350  * @param mode    Flags specifying mode of the forward operation.
    351  *
    352  * @return Zero on success or an error code.
    353  *
    354  */
    355 int ipc_forward_fast(ipc_callid_t callid, int phoneid, sysarg_t imethod,
    356     sysarg_t arg1, sysarg_t arg2, unsigned int mode)
    357 {
    358         return __SYSCALL6(SYS_IPC_FORWARD_FAST, callid, phoneid, imethod, arg1,
     338 * For non-system methods, the old method, arg1 and arg2 are rewritten by the
     339 * new values. For system methods, the new method, arg1 and arg2 are written to
     340 * the old arg1, arg2 and arg3, respectivelly. Calls with immutable methods are
     341 * forwarded verbatim.
     342 *
     343 * @param chandle  Handle of the call to forward.
     344 * @param phandle Phone handle to use for forwarding.
     345 * @param imethod  New interface and method for the forwarded call.
     346 * @param arg1     New value of the first argument for the forwarded call.
     347 * @param arg2     New value of the second argument for the forwarded call.
     348 * @param mode     Flags specifying mode of the forward operation.
     349 *
     350 * @return  Zero on success or an error code.
     351 *
     352 */
     353int ipc_forward_fast(cap_handle_t chandle, cap_handle_t phandle,
     354    sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, unsigned int mode)
     355{
     356        return __SYSCALL6(SYS_IPC_FORWARD_FAST, chandle, phandle, imethod, arg1,
    359357            arg2, mode);
    360358}
    361359
    362 int ipc_forward_slow(ipc_callid_t callid, int phoneid, sysarg_t imethod,
    363     sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
    364     unsigned int mode)
     360int ipc_forward_slow(cap_handle_t chandle, cap_handle_t phandle,
     361    sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
     362    sysarg_t arg4, sysarg_t arg5, unsigned int mode)
    365363{
    366364        ipc_call_t data;
     
    373371        IPC_SET_ARG5(data, arg5);
    374372       
    375         return __SYSCALL4(SYS_IPC_FORWARD_SLOW, callid, phoneid, (sysarg_t) &data,
    376             mode);
     373        return __SYSCALL4(SYS_IPC_FORWARD_SLOW, chandle, phandle,
     374            (sysarg_t) &data, mode);
    377375}
    378376
Note: See TracChangeset for help on using the changeset viewer.