Preprocessor macro expanding to a command
Space | User/kernel |
Context | Sync/async |
May block | No |
SPL | Any |
Dynamic memory | No |
#include <SPAD/AC.H>
CALL_IORQ_CANCELABLE(iorq, handler, chained_iorq);
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
.
fn
pointing to AST function declared with DECL_AST. The AST function must call IO_DISABLE_CHAIN_CANCEL on chained_iorq. DECL_IOCALL(FUNCTION, SPL_DEV, IORQ) DECL_AST(READ_CHARS, SPL_DEV, AST)IORQ *r;
SIORQ s;
char string[80];
{
  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;
}
{
  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.