Trailing-Edge
-
PDP-10 Archives
-
decuslib10-08
-
43,50512/fal.b36
There are no other files named fal.b36 in the archive.
MODULE FAL=
!File Access Listener for NETSPL-10
BEGIN
FORWARD ROUTINE
FAL,
FALHANDLE,
FALMJC, !Any fork may call this to tell FAL that the # of jobs changed
SAYWMJ; !Type out on WHAT command: "(Waiting for transfer to finish)"
!
! Conditionals
!
COMPILETIME FTDEBUG=1;
!
! Include files
!
REQUIRE 'INTR.REQ';
LIBRARY 'DAPLIB';
!
! Externals
!
EXTERNAL ROUTINE
LINK, !Establish a data link
REMJOB, !Process a remote job
FREEFB, !Free everything associated with a file block
FBINI, !Initilize file block
NDBINI, !Initialize an NDB
INTINI, !Initialize an Interrupt block
SPLQST, !Tell SPL that things have changed (NXFERS, for instance)
ALLOC, !Get core
FREE, !Give it back
ENTER, !Enable output on a network link
FINDP, !Find a process by name
QUIT; !Say we died
EXTERNAL RUN: REF PROCESS_BLOCK;
EXTERNAL
MJOBS, !# of simultaneous file transfers permitted
NXFERS; !# of file transfers in progress
THIS_IS [FAL] VERSION [1] EDIT [7] DATE[8,OCT,79]
![7] Send back status message for too many jobs at once correctly.
!
! Macros
!
MACRO PREFIX='FAL'%;
!
! Global Data
!
GLOBAL RXFERS, !# of remotly-requested transfers in progress now
FALWMJ: INT_BLOCK; !Tell FAL, # of jobs avaliable changed
GLOBAL FULLDUPLEX: INITIAL(0); !On if we can always talk back
!
! Routines
!
GLOBAL ROUTINE FAL=
BEGIN
LOCAL NB: REF NDB, !Link block
IB: REF INT_BLOCK; !Interrupt block for link
ESTABLISH(FALHANDLE,NB); !condition handler
FALWMJ[INT$SIGNAL_ARGS]=1;
FALWMJ[INT$STSCODE]=CNXFER;
TYPE('[',PPREFIX,'FSU FAL started up]',CRLF);
WHILE 1 DO
BEGIN
%( !This code removed for the time being... Let REMJOB do it
WHILE .NXFERS GEQ .MJOBS DO
BEGIN
%IF FTDEBUG %THEN
LOCAL T;
EXTERNAL ROUTINE UDT,TSIGNL,TSICAN;
T=TSIGNL(FALWMJ,UDT()+20); !Set a timer
%FI
RUN[P$DISPLAY]=SAYWMJ; !Say waiting for free transfer slot
WAIT(FALWMJ); !Wait until more jobs available
%IF FTDEBUG %THEN
TSICAN(.T); !Cancel timer
%FI
RUN[P$DISPLAY]=0; !Not waiting any more
END;
)%
NB=ALLOC(NDB_LEN); !Allocate an NDB
NDBINI(.NB); !Set up defaults
LINK(.NB);
!Tell somebody
DEBUGMSG(INFO('Received connect'));
IF .NXFERS GEQ .MJOBS !Did there get to be enough already
THEN BEGIN !while we weren't looking
IF .FULLDUPLEX NEQ 0
THEN SEND_STATUS(MAC$OPEN,ER$MJE); !Tell him
FREEFB(.NB); !Can't handle him, punt
END
ELSE BEGIN
(BIND FB=ALLOC(FB_LEN);FBINI(FB);NB[NDB$FB]=FB);
!Create an associated file block & link it to the NDB
NOINTS ((
NXFERS=.NXFERS+1; !Another transfer is now in progress
RXFERS=.RXFERS+1
));
SPLQST(); !Tell SPL to change status
FORK(REMJOB,.NB); !Create a process
RUN[P$NDB]=0; !Disown this NDB (it belongs to the REMJOB)
END;
END;
END; !FAL
ROUTINE FALHANDLE(SIGNAL_ARGS,MECH_ARGS,ENABLE_ARGS)=
BEGIN
MAP SIGNAL_ARGS: REF VECTOR,
MECH_ARGS: REF VECTOR,
ENABLE_ARGS: REF VECTOR;
!These are all argument lists of the form:
!length,arg1,arg2,arg3,arg4,... (words)
!length does not include the length word itself
EXTERNAL ROUTINE
REMINF, !Remove an inferior
FSIGNL, !Force a signal to another process
ERTEXT; !Get text of error message
EXTERNAL RUN: REF PROCESS_BLOCK;
LOCAL
C, !Code
S; !Severity
S=.(SIGNAL_ARGS[SA_CODE])<SEVERITY>;
SELECT (C=.(SIGNAL_ARGS[SA_CODE])<STSCODE>) OF SET
!Fill in conditions here
[CNXFER]: BEGIN
DEBUGMSG(INFO('FAL received [CNXFER]'));
IF .RUN[P$WAIT] EQL FALWMJ
THEN RUN[P$WAIT]=0; !We just got an xfer slot
RETURN SS$_CONTINUE;
END;
[INFQIT]: !Inferior process terminated
BEGIN
REMINF(.SIGNAL_ARGS[2]);
NOINTS ((
RXFERS=.RXFERS-1;
NXFERS=.NXFERS-1; !1 less transfer in progress
));
SPLQST();
IF (.RUN[P$WAIT] EQL FALWMJ) !If wait for xfer slot
OR (.RUN[P$WAIT] EQL INFQIT)
THEN RUN[P$WAIT]=0; !Then wait no more
RETURN SS$_CONTINUE !Keep going
END;
[FRKEND]: !We are about to terminate
BEGIN
EXTERNAL ROUTINE FREEFB;
EXTERNAL RUN: REF PROCESS_BLOCK;
LOCAL T;
IF (T=.RUN[P$NDB]) NEQ 0 THEN FREEFB(.T);
WHILE .RUN[P$INFERIORS] NEQ 0 DO
WAIT(INFQIT); !Wait for our inferiors to die
RETURN SS$_CONTINUE; !Give good return
END;
[OPRABO]:
BEGIN
TYPE('[',PPREFIX,
'FSD FAL shut down by operator]',CRLF);
SIGNALW(FRKEND);
QUIT(OPRABO)
END;
[OTHERWISE]:
BEGIN
EXTERNAL ROUTINE TERROR;
TERROR(.SIGNAL_ARGS,.MECH_ARGS,.ENABLE_ARGS);
SELECT .S OF SET !Check severity
[SS$_NORMAL,SS$_WARN]: BEGIN
RETURN SS$_CONTINUE
END;
[SS$_SEVEREERROR]: CRASH();
[SS$_ERROR]: BEGIN
LOCAL CC;
EXTERNAL ERRUEC,RMTUEC;
TYPE('%%',PPREFIX,
'FAE FAL Aborted due to error (');
CC=ERTEXT(.C);
TSTR(.CC);
IF (.CC EQL ERRUEC) OR (.CC EQL RMTUEC)
THEN TNUM(.C,8);
!# for undefined error code
TYPE(')',CRLF);
SIGNALW(FRKEND);
IF .RUN[P$SUPERIOR] EQL 0
THEN CRASH('Error at top level');
!we are in trouble!
QUIT(.C); !Go away
END;
TES
END;
TES
END; !FALHANDLE
GLOBAL ROUTINE FALMJC=
!Routine to tell FAL that the # of jobs changed
!This will FSIGNL the condition CNXFER to FAL if FAL is running
! if not, the routine is a no-op
!
! Formal parameters
!
!none
!
! Implicit arguments
!
!none
!
! Returned value
!
!none
!
! Implicit outputs
!
!none
BEGIN
LOCAL FALPB: REF PROCESS_BLOCK;
IF (FALPB=FINDP(PNAME(FAL))) NEQ 0
THEN FSIGNL(.FALPB,FALWMJ);
END; !FALMJC
ROUTINE SAYWMJ=
!Routine to type out message during "WHAT" command:
! (Waiting for transfer to finish)
!when FAL cannot listen for a new request due to MJOB limit
!
! Formal parameters
!
!none
!
! Implicit arguments
!
!none
!
! Returned value
!
!none
!
! Implicit outputs
!
!none
BEGIN
TYPE(' --- (Waiting for transfer to finish)');
END;
END ELUDOM