[Info-vax] Timeout in a write using QUIW.

Jan-Erik Söderholm jan-erik.soderholm at telia.com
Thu Jun 22 02:48:17 EDT 2023


Den 2023-06-22 kl. 02:03, skrev Arne Vajhøj:
> On 6/21/2023 5:39 PM, Jan-Erik Söderholm wrote:
>> Den 2023-06-21 kl. 23:17, skrev Arne Vajhøj:
>>> On 6/21/2023 4:45 PM, Jan-Erik Söderholm wrote:
>>>> I was hoping that one could add a timeout value just as in the
>>>> read case, but it doesn't look so. So I do not see how to get
>>>> out of the hanging call to QIOW. Maybe using QIO, and doing
>>>> some extra coding to check the I/O, I guess.
>>>>
>>>> So, is there a way to get out of this state, still using QIOW?
>>>
>>> Totally untested idea:
>>>
>>> SYS$SETIMR with an AST routine that calls SYS$CANCEL
>>
>> My thought was to just queue the I/O, wait a sec or two
>> using $WAIT and then check the IOSB. If not completed OK,
>> CANCEL and return an error to the application...
> 
> That is always an option.
> 
> Just for fun I tried writing some code.
> 
> I tested with read, because it is easy to recreate timeout
> for read.
> 
> First the standard IO$M_TIMED as baseline:
> 
>        program r
>        implicit none
>        include '($ssdef)'
>        include '($iodef)'
>        integer*1 buf(1)
>        integer*2 chan, iosb(4)
>        integer*4 stat, tmo
>        integer*4 sys$assign, sys$qiow, sys$dassgn
>        external sys$assign, sys$qiow, sys$dassgn
>        stat = sys$assign('TT:', chan, , , )
>        if(stat.ne.SS$_NORMAL) call ooops(stat)
>        tmo = 10
>        write(*,*) 'Press a key within ', tmo, ' seconds'
>        stat = sys$qiow(, %val(chan), %val(IO$_READVBLK+IO$M_TIMED),
>       +                iosb, , ,
>       +                buf, %val(1), %val(tmo), , , )
>        if(stat.eq.SS$_NORMAL.and.iosb(1).eq.SS$_TIMEOUT) then
>          write(*,*) 'Arne you are too slow'
>          goto 100
>        end if
>        if(stat.ne.SS$_NORMAL) call ooops(stat)
>        if(iosb(1).ne.SS$_NORMAL) call ooops(iosb(1))
>        write(*,*) 'You entered code: ', buf
> 100   stat = sys$dassgn(%val(chan))
>        if(stat.ne.SS$_NORMAL) call ooops(stat)
>        end
> c
>        subroutine ooops(stat)
>        implicit none
>        integer*4 stat
>        write(*,*) 'status = ', stat
>        stop
>        end
> 
> Now an implementation of my idea:
> 
>        program r1
>        implicit none
>        include '($ssdef)'
>        include '($iodef)'
>        integer*1 buf(1)
>        integer*2 chan, iosb(4)
>        integer*4 stat, tmo
>        integer*8 tmo2
>        integer*4 sys$assign, sys$qiow, sys$dassgn
>        external sys$assign, sys$qiow, sys$dassgn
>        external done
>        stat = sys$assign('TT:', chan, , , )
>        if(stat.ne.SS$_NORMAL) call ooops(stat)
>        tmo = 10
>        write(*,*) 'Press a key within ', tmo, ' seconds'
>        tmo2 = -tmo * 10000000
>        call sys$setimr(, tmo2, done, chan, )
>        stat = sys$qiow(, %val(chan), %val(IO$_READVBLK),
>       +                iosb, , ,
>       +                buf, %val(1), , , , )
>        if(stat.eq.SS$_NORMAL.and.iosb(1).eq.SS$_ABORT) then
>          write(*,*) 'Arne you are too slow'
>          goto 100
>        end if
>        if(stat.ne.SS$_NORMAL) call ooops(stat)
>        if(iosb(1).ne.SS$_NORMAL) call ooops(iosb(1))
>        call sys$cantim(0, )
>        write(*,*) 'You entered code: ', buf
> 100   stat = sys$dassgn(%val(chan))
>        if(stat.ne.SS$_NORMAL) call ooops(stat)
>        end
> c
>        subroutine ooops(stat)
>        implicit none
>        integer*4 stat
>        write(*,*) 'status = ', stat
>        stop
>        end
> c
>        subroutine done(chan)
>        implicit none
>        integer*2 chan
>        call sys$cancel(%val(chan))
>        return
>        end
> 
> And then how I interpret your suggestion:
> 
>        program r2
>        implicit none
>        include '($ssdef)'
>        include '($iodef)'
>        integer*1 buf(1)
>        integer*2 chan, iosb(4)
>        integer*4 stat, tmo
>        integer*8 tmo2
>        integer*4 sys$assign, sys$qio, sys$dassgn
>        external sys$assign, sys$qio, sys$dassgn
>        external done
>        stat = sys$assign('TT:', chan, , , )
>        if(stat.ne.SS$_NORMAL) call ooops(stat)
>        tmo = 10
>        write(*,*) 'Press a key within ', tmo, ' seconds'
>        stat = sys$qio(, %val(chan), %val(IO$_READVBLK),
>       +               iosb, done, ,
>       +               buf, %val(1), , , , )
>        if(stat.ne.SS$_NORMAL) call ooops(stat)
>        tmo2 = -tmo * 10000000
>        call sys$schdwk(, , tmo2, )
>        call sys$hiber()
>        if(iosb(1).eq.0) then
>          write(*,*) 'Arne you are too slow'
>          goto 100
>        end if
>        if(iosb(1).ne.SS$_NORMAL) call ooops(iosb(1))
>        write(*,*) 'You entered code: ', buf
> 100   stat = sys$dassgn(%val(chan))
>        if(stat.ne.SS$_NORMAL) call ooops(stat)
>        end
> c
>        subroutine ooops(stat)
>        implicit none
>        integer*4 stat
>        write(*,*) 'status = ', stat
>        stop
>        end
> c
>        subroutine done
>        implicit none
>        call sys$wake(, )
>        return
>        end
> 
> And sorry for doing it in Fortran. But it would have taken me
> way more time to do in Cobol. And translating from Fortran to
> Cobol is probably easier than from C to Cobol. So Fortran
> it is.
> 
> Arne
> 
> 
> 

Will check, but yes, it sounds as we are on the same track.
And our I/O routines are in C and called from Cobol. But yes,
as far as I know, one could also write it in pure Cobol. :-)

The benefit with your timer/ast based solution is of course that,
when everything works fine (as it does in most cases), there is
no added delay in the routine. AS I thought, there would always
be the same delay no matter if it works or not.

Most doc examples are in C, so that is probably why the I/O
routine was written in C (in 1993 in this case).

We'll have a discussion. Now, even with wired connections, there
can be cases with powered off printers and such, so a better
error handling could be good apart from the Wifi issues.

Jan-Erik.





More information about the Info-vax mailing list