[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