[Info-vax] yet another sys$qiow question
George Cornelius
cornelius at eisner.decus.org
Fri Aug 14 23:12:50 EDT 2015
Bob Gezelter wrote:
> David, JF,
>
> When using a Timer AST to trigger a Cancel IO, one needs to be aware of the
> potential race condition. To be specific, it is possible for the IO to complete
> normally AFTER the Timer has expired BUT before the Cancel actually takes
> place.
>
> The definitive information is to be found in the IOSB upon IO completion. If
> an IO is canceled, the IOSB will reflect this. If it was canceled, the IOSB
> will so indicate.
>
> The precise details of $CANCEL are well-documented in the IDSM.
>
> - Bob Geelter, http://www.rlgsc.com
Interesting that you should mention this. I just a few days ago ran
across the code below that waits for a mailbox read that has been
queued by this routine's caller as part of an "empty the mailbox"
function, and will cancel the pending I/O if it does not complete
in a predetermined (very short) time interval.
Written by me over 25 years ago and has always worked fine. When
converted to Alpha was changed from a JSB subroutine to a CALL
entry point.
EM_IOSB: iosb for the empty-mailbox read operation (underway) using efn=#1
[Quadword aligned. Note that the $WFLOR_S waits on either efn 1 or 2]
DELTA_1S: 10^7 (1 second timeout)
Note that we _do_ test the IOSB before the $SYNCH_S call, but since we
do not try to access the buffer (results will be discarded), I believe
there would be no race condition. If efn1 had been set then the appropriate
synchronization would have occurred and the IOSB would contain completion
status, and the data in the buffer, if we actually wanted to access it
would be available. Ignore the comment about the $CANCEL_S possibly failing:
it never did.
Also the $WAITFR_S is almost certainly overkill, because if the IOSB
status value is zero then the $WFLOR_S must have terminated due to
it being clear that efn 1 must have been set, but it's there out of
an abundance of caution.
The $CANTIM_S is overkill as well if efn2 was set, but there are no
other timer calls in the program and killing an operation that is already
complete is not problematic here.
Opinions of the experts invited.
George
---------------------------------%<------------------------------------------
; Wait for completion, with timer. Makes direct error exits on directive failures.
.entry TIMED_WAIT,^M<>
TSTW EM_IOSB ; Check if already done
BNEQ 12$ ; (May be the normal case)
$SETIMR_S efn=#2,daytim=DELTA_1S ; Start timer
BLBS R0,2$
BRW E_EXII
2$:
$WFLOR_S efn=#1,mask=#6 ; Wait for timer or I/O
BLBS R0,6$
BRW E_EXII
6$:
TSTW EM_IOSB ; We can exit if I/O completed
BNEQ 10$
$WAITFR_S efn=#2 ; Else be sure timeout is done
BLBS R0,8$
BRW E_EXII
8$:
; Exits after timeout initiated come here. Note $CANCEL_S will have no
; work to do if I/O already completed, so we won't check its completion status.
;
10$:
$CANTIM_S ;Cancel the timer call, just in case.
$CANCEL_S chan=MBX_CHAN ;No error check. May hang if this fails.
; Direct exit. Make sure main I/O has completed (possibly aborted), then return.
12$:
$SYNCH_S iosb=EM_IOSB,efn=#1 ; Just to be sure
BRW TW_EXII
; Error from TIMED_WAIT directive op
E_EXII:
$EXIT_S
TW_EXII:
RET
---------------------------------%<------------------------------------------
More information about the Info-vax
mailing list