mirror of
https://github.com/vishapoberon/compiler.git
synced 2026-04-05 22:12:24 +00:00
Various fixes to OS vs Oberon file lifetime management in Files.Mod.
This commit is contained in:
parent
51ae4c3241
commit
9f0cbccf55
4 changed files with 44 additions and 45 deletions
|
|
@ -500,8 +500,6 @@ MODULE OPM; (* RC 6.3.89 / 28.6.89, J.Templ 10.7.89 / 22.7.96 *)
|
|||
WHILE i > 0 DO LogW(" "); DEC(i) END;
|
||||
|
||||
LogVT100(VT100.Green); LogW("^"); LogVT100(VT100.ResetAll);
|
||||
|
||||
Files.Close(f);
|
||||
END ShowLine;
|
||||
|
||||
|
||||
|
|
@ -597,7 +595,8 @@ MODULE OPM; (* RC 6.3.89 / 28.6.89, J.Templ 10.7.89 / 22.7.96 *)
|
|||
oldSFile := Files.Old(fileName); done := oldSFile # NIL;
|
||||
IF done THEN
|
||||
Files.Set(oldSF, oldSFile, 0); Files.Read(oldSF, tag); Files.Read(oldSF, ver);
|
||||
IF (tag # SFtag) OR (ver # SFver) THEN err(-306); (*possibly a symbol file from another Oberon implementation, e.g. HP-Oberon*)
|
||||
IF (tag # SFtag) OR (ver # SFver) THEN
|
||||
err(-306); (*possibly a symbol file from another Oberon implementation, e.g. HP-Oberon*)
|
||||
CloseOldSym; done := FALSE
|
||||
END
|
||||
END
|
||||
|
|
|
|||
|
|
@ -18,14 +18,15 @@ MODULE Files; (* J. Templ 1.12. 89/12.4.95 Oberon files mapped onto Unix files
|
|||
BufSize = 4096;
|
||||
NoDesc = -1;
|
||||
|
||||
(* file states *)
|
||||
(* No file states, used when FileDesc.fd = NoDesc *)
|
||||
open = 0; (* OS File has been opened *)
|
||||
create = 1; (* OS file needs to be created *)
|
||||
close = 2; (* Register telling Create to use registerName directly:
|
||||
i.e. since we're closing and all data is still in
|
||||
buffers bypass writing to temp file and then renaming
|
||||
and just write directly to fianl register name *)
|
||||
|
||||
close = 2; (* Flag used by Files.Register to tell Create to create the
|
||||
file using it's registerName directly, rather than to
|
||||
create a temporary file: i.e. since we're closing and all
|
||||
data is still in buffers bypass writing to temp file and
|
||||
then renaming and just write directly to final register
|
||||
name *)
|
||||
|
||||
TYPE
|
||||
FileName = ARRAY 101 OF CHAR;
|
||||
|
|
@ -37,7 +38,7 @@ MODULE Files; (* J. Templ 1.12. 89/12.4.95 Oberon files mapped onto Unix files
|
|||
registerName: FileName;
|
||||
tempFile: BOOLEAN;
|
||||
identity: Platform.FileIdentity;
|
||||
fd-: Platform.FileHandle;
|
||||
fd: Platform.FileHandle;
|
||||
len, pos: LONGINT;
|
||||
bufs: ARRAY NumBufs OF Buffer;
|
||||
swapper: INTEGER;
|
||||
|
|
@ -63,7 +64,7 @@ MODULE Files; (* J. Templ 1.12. 89/12.4.95 Oberon files mapped onto Unix files
|
|||
|
||||
|
||||
VAR
|
||||
files: File; (* List of files that have an OS file handle/descriptor assigned *)
|
||||
files: File; (* List of files backed by an OS file, whether open, registered or temporary. *)
|
||||
tempno: INTEGER;
|
||||
HOME: ARRAY 1024 OF CHAR;
|
||||
SearchPath: POINTER TO ARRAY OF CHAR;
|
||||
|
|
@ -122,6 +123,10 @@ MODULE Files; (* J. Templ 1.12. 89/12.4.95 Oberon files mapped onto Unix files
|
|||
END GetTempName;
|
||||
|
||||
PROCEDURE Create(f: File);
|
||||
(* Makes sure there is an OS file backing this Oberon file.
|
||||
Used when more data has been written to an unregistered new file than
|
||||
buffers can hold, or when registering a new file whose data is all in
|
||||
buffers. *)
|
||||
VAR
|
||||
identity: Platform.FileIdentity;
|
||||
done: BOOLEAN;
|
||||
|
|
@ -137,16 +142,20 @@ MODULE Files; (* J. Templ 1.12. 89/12.4.95 Oberon files mapped onto Unix files
|
|||
*)
|
||||
IF f.fd = NoDesc THEN
|
||||
IF f.state = create THEN
|
||||
(* New file with enough data written to exceed buffers, so we need to
|
||||
create a temporary file to back it. *)
|
||||
GetTempName(f.registerName, f.workName); f.tempFile := TRUE
|
||||
ELSIF f.state = close THEN
|
||||
ELSE
|
||||
ASSERT(f.state = close);
|
||||
(* New file with all data in buffers being registered. No need for a
|
||||
temp file, will just write the buffers to the registerName. *)
|
||||
f.workName := f.registerName; f.registerName := ""; f.tempFile := FALSE
|
||||
END;
|
||||
error := Platform.Unlink(f.workName); (*unlink first to avoid stale NFS handles and to avoid reuse of inodes*)
|
||||
|
||||
error := Platform.New(f.workName, f.fd);
|
||||
done := error = 0;
|
||||
IF done THEN
|
||||
f.next := files; files := f;
|
||||
f.next := files; files := f; (* Link this file into the list of OS bakced files. *)
|
||||
INC(Heap.FileCount);
|
||||
Heap.RegisterFinalizer(f, Finalize);
|
||||
f.state := open;
|
||||
|
|
@ -186,31 +195,12 @@ MODULE Files; (* J. Templ 1.12. 89/12.4.95 Oberon files mapped onto Unix files
|
|||
IF error # 0 THEN Err("error writing file", f, error) END;
|
||||
f.pos := buf.org + buf.size;
|
||||
buf.chg := FALSE;
|
||||
error := Platform.Identify(f.fd, f.identity);
|
||||
error := Platform.Identify(f.fd, f.identity); (* Update identity with new modification time. *)
|
||||
IF error # 0 THEN Err("error identifying file", f, error) END;
|
||||
(*
|
||||
error := Platform.Identify(f.fd, identity);
|
||||
f.identity.mtime := identity.mtime;
|
||||
*)
|
||||
END
|
||||
END Flush;
|
||||
|
||||
|
||||
PROCEDURE CloseOSFile(f: File);
|
||||
(* Close the OS file handle and remove f from 'files' *)
|
||||
VAR prev: File; error: Platform.ErrorCode;
|
||||
BEGIN
|
||||
IF files = f THEN files := f.next
|
||||
ELSE
|
||||
prev := files;
|
||||
WHILE (prev # NIL) & (prev.next # f) DO prev := prev.next END;
|
||||
IF prev.next # NIL THEN prev.next := f.next END
|
||||
END;
|
||||
error := Platform.Close(f.fd);
|
||||
f.fd := NoDesc; f.state := create; DEC(Heap.FileCount);
|
||||
END CloseOSFile;
|
||||
|
||||
|
||||
PROCEDURE Close* (f: File);
|
||||
VAR
|
||||
i: LONGINT;
|
||||
|
|
@ -219,12 +209,6 @@ MODULE Files; (* J. Templ 1.12. 89/12.4.95 Oberon files mapped onto Unix files
|
|||
IF (f.state # create) OR (f.registerName # "") THEN
|
||||
Create(f); i := 0;
|
||||
WHILE (i < NumBufs) & (f.bufs[i] # NIL) DO Flush(f.bufs[i]); INC(i) END;
|
||||
(* There's no reason to sync this file - we're about to close it. The OS
|
||||
will sync if necessary. Further, sync will fail for a R/O file on Windows.
|
||||
error := Platform.Sync(f.fd);
|
||||
IF error # 0 THEN Err("error syncing file", f, error) END;
|
||||
*)
|
||||
CloseOSFile(f);
|
||||
END
|
||||
END Close;
|
||||
|
||||
|
|
@ -323,7 +307,7 @@ MODULE Files; (* J. Templ 1.12. 89/12.4.95 Oberon files mapped onto Unix files
|
|||
error := Platform.Identify(fd, identity);
|
||||
f := CacheEntry(identity);
|
||||
IF f # NIL THEN
|
||||
(* error := Platform.Close(fd); DCWB: Either this should be removed or should call CloseOSFile. *)
|
||||
error := Platform.Close(fd); (* fd not needed - we'll be using f.fd. *)
|
||||
RETURN f
|
||||
ELSE NEW(f); Heap.RegisterFinalizer(f, Finalize);
|
||||
f.fd := fd; f.state := open; f.pos := 0; f.swapper := -1; (*all f.buf[i] = NIL*)
|
||||
|
|
@ -579,7 +563,7 @@ Especially Length would become fairly complex.
|
|||
END Rename;
|
||||
|
||||
PROCEDURE Register* (f: File);
|
||||
VAR idx, errcode: INTEGER; f1: File; file: ARRAY 104 OF CHAR;
|
||||
VAR idx, errcode: INTEGER; f1: File;
|
||||
BEGIN
|
||||
(*
|
||||
Out.String("Files.Register f.registerName = "); Out.String(f.registerName);
|
||||
|
|
@ -595,7 +579,7 @@ Especially Length would become fairly complex.
|
|||
Out.String(" to registerName "); Out.String(f.registerName);
|
||||
Out.String(" errorcode = "); Out.Int(errcode,1); Out.Ln;
|
||||
*)
|
||||
IF errcode # 0 THEN COPY(f.registerName, file); HALT(99) END;
|
||||
IF errcode # 0 THEN Err("Couldn't rename temp name as register name", f, errcode) END;
|
||||
f.workName := f.registerName; f.registerName := ""; f.tempFile := FALSE
|
||||
END
|
||||
END Register;
|
||||
|
|
@ -725,6 +709,20 @@ Especially Length would become fairly complex.
|
|||
COPY (f.workName, name);
|
||||
END GetName;
|
||||
|
||||
PROCEDURE CloseOSFile(f: File);
|
||||
(* Close the OS file handle and remove f from 'files' *)
|
||||
VAR prev: File; error: Platform.ErrorCode;
|
||||
BEGIN
|
||||
IF files = f THEN files := f.next
|
||||
ELSE
|
||||
prev := files;
|
||||
WHILE (prev # NIL) & (prev.next # f) DO prev := prev.next END;
|
||||
IF prev.next # NIL THEN prev.next := f.next END
|
||||
END;
|
||||
error := Platform.Close(f.fd);
|
||||
f.fd := NoDesc; f.state := create; DEC(Heap.FileCount);
|
||||
END CloseOSFile;
|
||||
|
||||
PROCEDURE Finalize(o: SYSTEM.PTR);
|
||||
VAR f: File; res: LONGINT;
|
||||
BEGIN
|
||||
|
|
|
|||
|
|
@ -530,7 +530,8 @@ MODULE Heap;
|
|||
PROCEDURE GC*(markStack: BOOLEAN);
|
||||
VAR
|
||||
m: Module;
|
||||
i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23: S.ADDRESS;
|
||||
i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11,
|
||||
i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23: S.ADDRESS;
|
||||
cand: ARRAY 10000 OF S.ADDRESS;
|
||||
BEGIN
|
||||
IF (lockdepth = 0) OR (lockdepth = 1) & ~markStack THEN
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ MODULE Modules; (* jt 6.1.96 *)
|
|||
|
||||
PROCEDURE Halt*(code: SYSTEM.INT32);
|
||||
BEGIN
|
||||
(*IF HaltHandler # NIL THEN HaltHandler(code) END;*)
|
||||
Heap.FINALL;
|
||||
errstring("Terminated by Halt("); errint(code); errstring("). ");
|
||||
IF code < 0 THEN DisplayHaltCode(code) END;
|
||||
errstring(Platform.NL);
|
||||
|
|
@ -145,6 +145,7 @@ MODULE Modules; (* jt 6.1.96 *)
|
|||
|
||||
PROCEDURE AssertFail*(code: SYSTEM.INT32);
|
||||
BEGIN
|
||||
Heap.FINALL;
|
||||
errstring("Assertion failure.");
|
||||
IF code # 0 THEN errstring(" ASSERT code "); errint(code); errstring("."); END;
|
||||
errstring(Platform.NL);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue