LOCKS.MOD 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. IMPLEMENTATION MODULE Locks;
  2. (*
  3. * ModBase
  4. * Release 3.0
  5. * (c) Copyright 1991 John McMonagle
  6. * P.O. Box 8402
  7. * Green Bay Wi 53308
  8. * All Rights Reserved
  9. *
  10. *)
  11. FROM StringIO IMPORT PrintMessage,ErrorMessage;
  12. IMPORT FAPI,FAPI,ErrorManager,KbdInput,BigSets;
  13. IMPORT SYSTEM,ErrStrgs,M2Strings,StrEdit,StringIO;
  14. CONST
  15. Nil=SYSTEM.ADDRESS(VAL(LONGINT,0));
  16. VAR
  17. AllRange:RangeRec;
  18. PROCEDURE AskError(code:CARDINAL;FileName:ARRAY OF CHAR):BOOLEAN;
  19. VAR
  20. st:ARRAY[0..63] OF CHAR;
  21. str:ARRAY[0..127] OF CHAR;
  22. BEGIN
  23. M2Strings.Concat('Unable to access file ',FileName,str);
  24. StrEdit.Append(str,'. Error is:');
  25. ErrStrgs.NumToStr(code,st);
  26. StrEdit.Append(str,st);
  27. RETURN AbortRetryIgnore(str) ;
  28. END AskError;
  29. PROCEDURE Lock(FileHandle : CARDINAL; range:RangeRec) : ErrorMessage;
  30. BEGIN
  31. RETURN FAPI.DOSFILELOCKS(FileHandle,Nil,SYSTEM.ADR(range));
  32. END Lock;
  33. PROCEDURE LockRetry(FileHandle : CARDINAL; range:RangeRec;
  34. Retries:CARDINAL; VAR FileName:ARRAY OF CHAR) : ErrorMessage;
  35. VAR
  36. count,
  37. code:CARDINAL;
  38. BEGIN
  39. count:=0;
  40. LOOP
  41. code:=FAPI.DOSFILELOCKS(FileHandle,Nil,SYSTEM.ADR(range));
  42. IF (code=0) THEN RETURN code END;
  43. IF (count>Retries) THEN
  44. IF NOT AskError(code,FileName)
  45. THEN
  46. RETURN code
  47. END;
  48. count:=0
  49. END;
  50. INC(count);
  51. Pause(55);
  52. END;
  53. END LockRetry;
  54. PROCEDURE UnLock(FileHandle : CARDINAL; range:RangeRec) : ErrorMessage;
  55. BEGIN
  56. RETURN FAPI.DOSFILELOCKS(FileHandle,SYSTEM.ADR(range),Nil);
  57. END UnLock;
  58. PROCEDURE LockFile(FileHandle : CARDINAL) : ErrorMessage;
  59. BEGIN
  60. RETURN FAPI.DOSFILELOCKS(FileHandle,Nil,SYSTEM.ADR(AllRange));
  61. END LockFile;
  62. PROCEDURE LockFileRetry(FileHandle : CARDINAL;
  63. Retries:CARDINAL; VAR FileName:ARRAY OF CHAR) : ErrorMessage;
  64. BEGIN
  65. RETURN LockRetry(FileHandle,AllRange,Retries,FileName);
  66. END LockFileRetry;
  67. PROCEDURE UnLockFile(FileHandle : CARDINAL) : ErrorMessage;
  68. BEGIN
  69. RETURN FAPI.DOSFILELOCKS(FileHandle,SYSTEM.ADR(AllRange),Nil);
  70. END UnLockFile;
  71. (* used to pause between retries should give give control to the
  72. operating system if possible *)
  73. PROCEDURE Pause(Msec:CARDINAL);
  74. VAR
  75. code:CARDINAL;
  76. mode:SYSTEM.BYTE;
  77. BEGIN
  78. code:=FAPI.DOSSLEEP(VAL(LONGINT,Msec));
  79. END Pause;
  80. PROCEDURE NoLocking(handle:CARDINAL):BOOLEAN;
  81. VAR
  82. code:CARDINAL;
  83. BEGIN
  84. code:=LockFile(handle);
  85. CASE code OF
  86. 0:
  87. code:=LockFile(handle);
  88. PrintMessage(UnLockFile(handle));
  89. RETURN code#33;
  90. | 1: RETURN TRUE;
  91. |33:RETURN FALSE;
  92. ELSE
  93. PrintMessage(code);
  94. RETURN TRUE;
  95. END;
  96. END NoLocking;
  97. PROCEDURE ReadRetry(FileHandle : CARDINAL; ptr : SYSTEM.ADDRESS; size,Retries :
  98. CARDINAL;VAR FileName:ARRAY OF CHAR) : CARDINAL;
  99. VAR
  100. ErrorReturn,
  101. BytesRead,
  102. count: CARDINAL;
  103. BEGIN
  104. count:=0;
  105. LOOP
  106. ErrorReturn := FAPI.DOSREAD( FileHandle, ptr, size, SYSTEM.ADR(BytesRead) );
  107. (* Looks like something may be wrong here. *)
  108. IF ErrorReturn=0 THEN
  109. IF BytesRead < size THEN
  110. IF BytesRead = 0 THEN
  111. RETURN (StringIO.EndOfFile);
  112. ELSE
  113. RETURN (StringIO.PartialRead);
  114. END;
  115. END;
  116. RETURN ErrorReturn;
  117. END;
  118. IF count>Retries THEN
  119. IF NOT AskError(ErrorReturn,FileName)
  120. THEN
  121. RETURN ErrorReturn
  122. END;
  123. count:=0;
  124. END;
  125. END;
  126. END ReadRetry;
  127. PROCEDURE DefaultMessage( TheMessage: ARRAY OF CHAR ): BOOLEAN;
  128. VAR
  129. c:CARDINAL;
  130. set:KbdInput.KeyNumSet;
  131. BEGIN
  132. BigSets.InitSet(set);
  133. BigSets.AppendSet(set,"{'A','a','r','R','I','i'}");
  134. StringIO.WriteEol( StringIO.ErrorOutp, TheMessage );
  135. StringIO.WriteEol( StringIO.ErrorOutp,
  136. ' Press A to Abort,R to Retry, and I to Ignore.' );
  137. c:= KbdInput.CAPkey( KbdInput.KeyHit(set) );
  138. IF c=ORD('R') THEN
  139. RETURN TRUE
  140. ELSIF c=ORD('I') THEN
  141. RETURN FALSE
  142. ELSE
  143. ErrorManager.DoTermProcs();
  144. HALT;
  145. END
  146. END DefaultMessage;
  147. BEGIN
  148. AllRange.FileOffset:=VAL(LONGINT,0);
  149. AllRange.RangeLength:=MAX(LONGINT);
  150. AbortRetryIgnore:=DefaultMessage;
  151. ExclusiveOnly:=FALSE;
  152. END Locks.
  153.