Google
 

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