Ignore:
File:
1 edited

Legend:

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

    rc170438 r52d2603  
    9696}
    9797
    98 /** Prologue for ipc_call_async_*() functions.
     98/** Prolog for ipc_call_async_*() functions.
    9999 *
    100100 * @param private  Argument for the answer/error callback.
     
    122122}
    123123
    124 /** Epilogue for ipc_call_async_*() functions.
     124/** Epilog for ipc_call_async_*() functions.
    125125 *
    126126 * @param callid      Value returned by the SYS_IPC_CALL_ASYNC_* syscall.
    127127 * @param phoneid     Phone handle through which the call was made.
    128128 * @param call        Structure returned by ipc_prepare_async().
     129 * @param can_preempt If true, the current fibril can be preempted
     130 *                    in this call.
     131 *
    129132 */
    130133static inline void ipc_finish_async(ipc_callid_t callid, int phoneid,
    131     async_call_t *call)
     134    async_call_t *call, bool can_preempt)
    132135{
    133136        if (!call) {
     
    156159                list_append(&call->list, &queued_calls);
    157160               
    158                 call->fid = fibril_get_id();
    159                 fibril_switch(FIBRIL_TO_MANAGER);
    160                 /* Async futex unlocked by previous call */
     161                if (can_preempt) {
     162                        call->fid = fibril_get_id();
     163                        fibril_switch(FIBRIL_TO_MANAGER);
     164                        /* Async futex unlocked by previous call */
     165                } else {
     166                        call->fid = 0;
     167                        futex_up(&async_futex);
     168                }
    161169               
    162170                return;
     
    189197 * @param private     Argument to be passed to the answer/error callback.
    190198 * @param callback    Answer or error callback.
     199 * @param can_preempt If true, the current fibril will be preempted in
     200 *                    case the kernel temporarily refuses to accept more
     201 *                    asynchronous calls.
     202 *
    191203 */
    192204void ipc_call_async_fast(int phoneid, sysarg_t imethod, sysarg_t arg1,
    193205    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, void *private,
    194     ipc_async_callback_t callback)
     206    ipc_async_callback_t callback, bool can_preempt)
    195207{
    196208        async_call_t *call = NULL;
     
    234246        }
    235247       
    236         ipc_finish_async(callid, phoneid, call);
     248        ipc_finish_async(callid, phoneid, call, can_preempt);
    237249}
    238250
     
    254266 * @param private     Argument to be passed to the answer/error callback.
    255267 * @param callback    Answer or error callback.
     268 * @param can_preempt If true, the current fibril will be preempted in
     269 *                    case the kernel temporarily refuses to accept more
     270 *                    asynchronous calls.
     271 *
    256272 */
    257273void ipc_call_async_slow(int phoneid, sysarg_t imethod, sysarg_t arg1,
    258274    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, void *private,
    259     ipc_async_callback_t callback)
     275    ipc_async_callback_t callback, bool can_preempt)
    260276{
    261277        async_call_t *call = ipc_prepare_async(private, callback);
     
    279295            ipc_call_async_internal(phoneid, &call->u.msg.data);
    280296       
    281         ipc_finish_async(callid, phoneid, call);
     297        ipc_finish_async(callid, phoneid, call, can_preempt);
    282298}
    283299
     
    359375                futex_up(&async_futex);
    360376               
    361                 assert(call->fid);
    362                 fibril_add_ready(call->fid);
     377                if (call->fid)
     378                        fibril_add_ready(call->fid);
    363379               
    364380                if (callid == (ipc_callid_t) IPC_CALLRET_FATAL) {
Note: See TracChangeset for help on using the changeset viewer.