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

Arne Vajhøj arne at vajhoej.dk
Sun Jun 25 21:06:51 EDT 2023


On 6/22/2023 2:48 AM, Jan-Erik Söderholm wrote:
> Den 2023-06-22 kl. 02:03, skrev Arne Vajhøj:
>> 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.
> 
> 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).

C versions:

#include <stdio.h>
#include <stdlib.h>

#include <ssdef.h>
#include <iodef.h>
#include <starlet.h>
#include <descrip.h>

static void ooops(long int stat)
{
     printf("status = %d\n", stat);
     exit(0);
}

int main()
{
     $DESCRIPTOR(ttdesc, "TT:");
     char buf;
     short int chan, iosb[4];
     long int stat, tmo;
     stat = sys$assign(&ttdesc, &chan, 0, 0, 0);
     if(stat != SS$_NORMAL) ooops(stat);
     tmo = 10;
     printf("Press a key within %d seconds\n", tmo);
     stat = sys$qiow(0, chan, IO$_READVBLK+IO$M_TIMED, iosb, 0, 0, &buf, 
1, tmo, 0, 0, 0);
     if(stat == SS$_NORMAL && iosb[0] == SS$_TIMEOUT)
     {
         printf("Arne you are too slow\n");
     }
     else
     {
         if(stat != SS$_NORMAL) ooops(stat);
         if(iosb[0] != SS$_NORMAL) ooops(iosb[0]);
         printf("You entered code: %d\n", buf);
     }
     stat = sys$dassgn(chan);
     if(stat != SS$_NORMAL) ooops(stat);
     return 0;
}

#include <stdio.h>
#include <stdlib.h>

#include <ssdef.h>
#include <iodef.h>
#include <starlet.h>
#include <descrip.h>

static void ooops(long int stat)
{
     printf("status = %d\n", stat);
     exit(0);
}

static void done(short int chan)
{
     sys$cancel(chan);
}

int main()
{
     $DESCRIPTOR(ttdesc, "TT:");
     char buf;
     short int chan, iosb[4];
     long int stat, tmo;
     long long int tmo2;
     stat = sys$assign(&ttdesc, &chan, 0, 0, 0);
     if(stat != SS$_NORMAL) ooops(stat);
     tmo = 10;
     printf("Press a key within %d seconds\n", tmo);
     tmo2 = -tmo * 10000000;
     sys$setimr(0, &tmo2, done, chan, 0);
     stat = sys$qiow(0, chan, IO$_READVBLK, iosb, 0, 0, &buf, 1, 0, 0, 
0, 0);
     if(stat == SS$_NORMAL && iosb[0] == SS$_ABORT)
     {
         printf("Arne you are too slow\n");
     }
     else
     {
         if(stat != SS$_NORMAL) ooops(stat);
         if(iosb[0] != SS$_NORMAL) ooops(iosb[0]);
         sys$cantim(&0, 0);
         printf("You entered code: %d\n", buf);
     }
     stat = sys$dassgn(chan);
     if(stat != SS$_NORMAL) ooops(stat);
     return 0;
}

#include <stdio.h>
#include <stdlib.h>

#include <ssdef.h>
#include <iodef.h>
#include <starlet.h>
#include <descrip.h>

static void ooops(long int stat)
{
     printf("status = %d\n", stat);
     exit(0);
}

static void done(short int chan)
{
     sys$wake(0, 0);
}

int main()
{
     $DESCRIPTOR(ttdesc, "TT:");
     char buf;
     short int chan, iosb[4];
     long int stat, tmo;
     long long int tmo2;
     stat = sys$assign(&ttdesc, &chan, 0, 0, 0);
     if(stat != SS$_NORMAL) ooops(stat);
     tmo = 10;
     printf("Press a key within %d seconds\n", tmo);
     stat = sys$qio(0, chan, IO$_READVBLK, iosb, done, 0, &buf, 1, 0, 0, 
0, 0);
     if(stat != SS$_NORMAL) ooops(stat);
     tmo2 = -tmo * 10000000;
     sys$schdwk(0, 0, &tmo2, 0);
     sys$hiber();
     if(iosb[0] == 0)
     {
         printf("Arne you are too slow\n");
     }
     else
     {
         if(iosb[0] != SS$_NORMAL) ooops(iosb[0]);
         printf("You entered code: %d\n", buf);
     }
     stat = sys$dassgn(chan);
     if(stat != SS$_NORMAL) ooops(stat);
     return 0;
}

Arne




More information about the Info-vax mailing list