Interface CALL_IORQ_CANCELABLE

Preprocessor macro expanding to a command

SpaceUser/kernel
ContextSync/async
May blockNo
SPLAny
Dynamic memoryNo

#include <SPAD/AC.H>

CALL_IORQ_CANCELABLE(iorq, handler, chained_iorq);

Description

This is a preprocessor macro that expands to machine- and compiler-dependent code to call an IORQ. The functionality is similar to CALL_IORQ except that CALL_IORQ_CANCELABLE links the iorq to already posted chained_iorq — when cancel on chained_iorq is attempted, iorq is also canceled.

An AST for this iorq MUST perform IO_DISABLE_CHAIN_CANCEL on chained_iorq — before it frees or reuses iorq (It is good practice to call IO_DISABLE_CHAIN_CANCEL as the first command in the AST). IO_DISABLE_CHAIN_CANCEL will unlink iorq from chained_iorq, if it were not called there would be dangling pointer to uninitialized memory space.

If chained_iorq has already pending cancel, CALL_IORQ_CANCELABLE won't call handler at all and will instead post iorq's AST with status -EINTR.

Arguments

Example

IORQ *r;
SIORQ s;
char string[80];

DECL_IOCALL(FUNCTION, SPL_DEV, IORQ)
{
        r = RQ;
        s.v.ptr = (unsigned long)string;
        s.v.len = sizeof string;
        s.v.vspace = KERNEL$VIRTUAL;
        s.h = 0;
        s.progress = 0;
        s.fn = READ_CHARS;
        CALL_IORQ_CANCELABLE(s, KERNEL$READ);
        RETURN;
}

DECL_AST(READ_CHARS, SPL_DEV, AST)
{
        IO_DISABLE_CHAIN_CANCEL(SPL_DEV, r);
        if (RQ->status == -EINTR) {
                r->status = -EINTR;
                RETURN_AST(r);
        }
        ... more code ...
}

We declare an IORQ handler FUNCTION that calls another IORQ to read data from handle 0 (terminal). When the IORQ passed to FUNCTION is canceled, reading of data from the terminal is canceled too and returns -EINTR. Our AST READ_CHARS checks this condition and return -EINTR to the IORQ in this case.
Note that because we use global variables, there may not be more FUNCTION requests posted concurrently.

See also

CALL_IORQ, DECL_IOCALL, DECL_AST, IO_DISABLE_CHAIN_CANCEL