Changeset 43e2cbc in mainline for kernel/generic/src/ipc/sysipc.c


Ignore:
Timestamp:
2016-09-10T13:56:43Z (9 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0b00599
Parents:
838ea8aa
Message:

Implement interruptible wait for messages sent by the kernel

This pertains specifically to handling the IPC_M_PAGE_IN requests
sent by the kernel on behalf of the faulting thread. If the external
pager process does not respond for some reason, the user may decide to
kill the blocked client. That will result in interrupting the client
from the sleep. The kernel will then perform cleanup.

This changeset implements the cleanup by either forgetting the call
(i.e. donating it to the callee) or waiting for the arriving answer,
whichever of the two succeeds.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/ipc/sysipc.c

    r838ea8aa r43e2cbc  
    285285#endif
    286286
    287                 rc = ipc_call_sync(phone, call);
     287                ipc_call_hold(call);
     288                rc = ipc_call_sync(phone, call);
     289                spinlock_lock(&call->forget_lock);
     290                bool forgotten = call->forget;
     291                spinlock_unlock(&call->forget_lock);
     292                ipc_call_release(call);
    288293
    289294#ifdef CONFIG_UDEBUG
     
    291296#endif
    292297
    293                 if (rc != EOK)
    294                         return EINTR;
     298                if (rc != EOK) {
     299                        if (!forgotten) {
     300                                /*
     301                                 * There was an error, but it did not result
     302                                 * in the call being forgotten. In fact, the
     303                                 * call was not even sent. We are still
     304                                 * its owners and are responsible for its
     305                                 * deallocation.
     306                                 */
     307                                ipc_call_free(call);
     308                        } else {
     309                                /*
     310                                 * The call was forgotten and it changed hands.
     311                                 * We are no longer expected to free it.
     312                                 */
     313                                ASSERT(rc == EINTR);
     314                        }
     315                        return rc;     
     316                }
    295317
    296318                process_answer(call);
Note: See TracChangeset for help on using the changeset viewer.