IMPLEMENTATION MODULE Locks; (* * ModBase * Release 3.0 * (c) Copyright 1991 John McMonagle * P.O. Box 8402 * Green Bay Wi 53308 * All Rights Reserved * *) FROM StringIO IMPORT PrintMessage,ErrorMessage; IMPORT FAPI,FAPI,ErrorManager,KbdInput,BigSets; IMPORT SYSTEM,ErrStrgs,M2Strings,StrEdit,StringIO; CONST Nil=SYSTEM.ADDRESS(VAL(LONGINT,0)); VAR AllRange:RangeRec; PROCEDURE AskError(code:CARDINAL;FileName:ARRAY OF CHAR):BOOLEAN; VAR st:ARRAY[0..63] OF CHAR; str:ARRAY[0..127] OF CHAR; BEGIN M2Strings.Concat('Unable to access file ',FileName,str); StrEdit.Append(str,'. Error is:'); ErrStrgs.NumToStr(code,st); StrEdit.Append(str,st); RETURN AbortRetryIgnore(str) ; END AskError; PROCEDURE Lock(FileHandle : CARDINAL; range:RangeRec) : ErrorMessage; BEGIN RETURN FAPI.DOSFILELOCKS(FileHandle,Nil,SYSTEM.ADR(range)); END Lock; PROCEDURE LockRetry(FileHandle : CARDINAL; range:RangeRec; Retries:CARDINAL; VAR FileName:ARRAY OF CHAR) : ErrorMessage; VAR count, code:CARDINAL; BEGIN count:=0; LOOP code:=FAPI.DOSFILELOCKS(FileHandle,Nil,SYSTEM.ADR(range)); IF (code=0) THEN RETURN code END; IF (count>Retries) THEN IF NOT AskError(code,FileName) THEN RETURN code END; count:=0 END; INC(count); Pause(55); END; END LockRetry; PROCEDURE UnLock(FileHandle : CARDINAL; range:RangeRec) : ErrorMessage; BEGIN RETURN FAPI.DOSFILELOCKS(FileHandle,SYSTEM.ADR(range),Nil); END UnLock; PROCEDURE LockFile(FileHandle : CARDINAL) : ErrorMessage; BEGIN RETURN FAPI.DOSFILELOCKS(FileHandle,Nil,SYSTEM.ADR(AllRange)); END LockFile; PROCEDURE LockFileRetry(FileHandle : CARDINAL; Retries:CARDINAL; VAR FileName:ARRAY OF CHAR) : ErrorMessage; BEGIN RETURN LockRetry(FileHandle,AllRange,Retries,FileName); END LockFileRetry; PROCEDURE UnLockFile(FileHandle : CARDINAL) : ErrorMessage; BEGIN RETURN FAPI.DOSFILELOCKS(FileHandle,SYSTEM.ADR(AllRange),Nil); END UnLockFile; (* used to pause between retries should give give control to the operating system if possible *) PROCEDURE Pause(Msec:CARDINAL); VAR code:CARDINAL; mode:SYSTEM.BYTE; BEGIN code:=FAPI.DOSSLEEP(VAL(LONGINT,Msec)); END Pause; PROCEDURE NoLocking(handle:CARDINAL):BOOLEAN; VAR code:CARDINAL; BEGIN code:=LockFile(handle); CASE code OF 0: code:=LockFile(handle); PrintMessage(UnLockFile(handle)); RETURN code#33; | 1: RETURN TRUE; |33:RETURN FALSE; ELSE PrintMessage(code); RETURN TRUE; END; END NoLocking; PROCEDURE ReadRetry(FileHandle : CARDINAL; ptr : SYSTEM.ADDRESS; size,Retries : CARDINAL;VAR FileName:ARRAY OF CHAR) : CARDINAL; VAR ErrorReturn, BytesRead, count: CARDINAL; BEGIN count:=0; LOOP ErrorReturn := FAPI.DOSREAD( FileHandle, ptr, size, SYSTEM.ADR(BytesRead) ); (* Looks like something may be wrong here. *) IF ErrorReturn=0 THEN IF BytesRead < size THEN IF BytesRead = 0 THEN RETURN (StringIO.EndOfFile); ELSE RETURN (StringIO.PartialRead); END; END; RETURN ErrorReturn; END; IF count>Retries THEN IF NOT AskError(ErrorReturn,FileName) THEN RETURN ErrorReturn END; count:=0; END; END; END ReadRetry; PROCEDURE DefaultMessage( TheMessage: ARRAY OF CHAR ): BOOLEAN; VAR c:CARDINAL; set:KbdInput.KeyNumSet; BEGIN BigSets.InitSet(set); BigSets.AppendSet(set,"{'A','a','r','R','I','i'}"); StringIO.WriteEol( StringIO.ErrorOutp, TheMessage ); StringIO.WriteEol( StringIO.ErrorOutp, ' Press A to Abort,R to Retry, and I to Ignore.' ); c:= KbdInput.CAPkey( KbdInput.KeyHit(set) ); IF c=ORD('R') THEN RETURN TRUE ELSIF c=ORD('I') THEN RETURN FALSE ELSE ErrorManager.DoTermProcs(); HALT; END END DefaultMessage; BEGIN AllRange.FileOffset:=VAL(LONGINT,0); AllRange.RangeLength:=MAX(LONGINT); AbortRetryIgnore:=DefaultMessage; ExclusiveOnly:=FALSE; END Locks.