deinitializing locks at program exit (#19043)

* deinitializing locks at program exit

* deinitLock shouldn't be called for js backend I guess...

* I suppose this is the best way to detect the
ewruntime option

* I guess I need these guards here too...

* fixing merge conflict
This commit is contained in:
Tail Wag Games 2021-10-25 03:13:30 -05:00 • committed by GitHub
commit 582468da1c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 24 deletions

View file

@ -44,6 +44,9 @@ proc callClosures() {.noconv.} =
of kClosure: fun.fun1() of kClosure: fun.fun1()
of kNoconv: fun.fun2() of kNoconv: fun.fun2()
when not defined(js) and not defined(nimOwnedEnabled):
deinitLock(gFunsLock)
template fun() = template fun() =
if gFuns.len == 0: if gFuns.len == 0:
addAtExit(callClosures) addAtExit(callClosures)

View file

@ -20,19 +20,19 @@ type
incompleteStruct.} = object incompleteStruct.} = object
File* = ptr CFile ## The type representing a file handle. File* = ptr CFile ## The type representing a file handle.
FileMode* = enum ## The file mode when opening a file. FileMode* = enum ## The file mode when opening a file.
fmRead, ## Open the file for read access only. fmRead, ## Open the file for read access only.
fmWrite, ## Open the file for write access only. fmWrite, ## Open the file for write access only.
## If the file does not exist, it will be ## If the file does not exist, it will be
## created. Existing files will be cleared! ## created. Existing files will be cleared!
fmReadWrite, ## Open the file for read and write access. fmReadWrite, ## Open the file for read and write access.
## If the file does not exist, it will be ## If the file does not exist, it will be
## created. Existing files will be cleared! ## created. Existing files will be cleared!
fmReadWriteExisting, ## Open the file for read and write access. fmReadWriteExisting, ## Open the file for read and write access.
## If the file does not exist, it will not be ## If the file does not exist, it will not be
## created. The existing file will not be cleared. ## created. The existing file will not be cleared.
fmAppend ## Open the file for writing only; append data fmAppend ## Open the file for writing only; append data
## at the end. ## at the end.
FileHandle* = cint ## type that represents an OS file handle; this is FileHandle* = cint ## type that represents an OS file handle; this is
## useful for low-level file access ## useful for low-level file access
@ -40,7 +40,8 @@ type
# text file handling: # text file handling:
when not defined(nimscript) and not defined(js): when not defined(nimscript) and not defined(js):
# duplicated between io and ansi_c # duplicated between io and ansi_c
const stdioUsesMacros = (defined(osx) or defined(freebsd) or defined(dragonfly)) and not defined(emscripten) const stdioUsesMacros = (defined(osx) or defined(freebsd) or defined(
dragonfly)) and not defined(emscripten)
const stderrName = when stdioUsesMacros: "__stderrp" else: "stderr" const stderrName = when stdioUsesMacros: "__stderrp" else: "stderr"
const stdoutName = when stdioUsesMacros: "__stdoutp" else: "stdout" const stdoutName = when stdioUsesMacros: "__stdoutp" else: "stdout"
const stdinName = when stdioUsesMacros: "__stdinp" else: "stdin" const stdinName = when stdioUsesMacros: "__stdinp" else: "stdin"
@ -158,7 +159,7 @@ proc checkErr(f: File) =
# shouldn't happen # shouldn't happen
quit(1) quit(1)
{.push stackTrace:off, profiler:off.} {.push stackTrace: off, profiler: off.}
proc readBuffer*(f: File, buffer: pointer, len: Natural): int {. proc readBuffer*(f: File, buffer: pointer, len: Natural): int {.
tags: [ReadIOEffect], benign.} = tags: [ReadIOEffect], benign.} =
## reads `len` bytes into the buffer pointed to by `buffer`. Returns ## reads `len` bytes into the buffer pointed to by `buffer`. Returns
@ -167,7 +168,8 @@ proc readBuffer*(f: File, buffer: pointer, len: Natural): int {.
result = cast[int](c_fread(buffer, 1, cast[csize_t](len), f)) result = cast[int](c_fread(buffer, 1, cast[csize_t](len), f))
if result != len: checkErr(f) if result != len: checkErr(f)
proc readBytes*(f: File, a: var openArray[int8|uint8], start, len: Natural): int {. proc readBytes*(f: File, a: var openArray[int8|uint8], start,
len: Natural): int {.
tags: [ReadIOEffect], benign.} = tags: [ReadIOEffect], benign.} =
## reads `len` bytes into the buffer `a` starting at `a[start]`. Returns ## reads `len` bytes into the buffer `a` starting at `a[start]`. Returns
## the actual number of bytes that have been read which may be less than ## the actual number of bytes that have been read which may be less than
@ -418,8 +420,8 @@ proc readLine*(f: File, line: var string): bool {.tags: [ReadIOEffect],
numberOfCharsRead -= 2 numberOfCharsRead -= 2
# handle Ctrl+Z as EOF # handle Ctrl+Z as EOF
for i in 0..<numberOfCharsRead: for i in 0..<numberOfCharsRead:
if buffer[i].uint16 == 26: #Ctrl+Z if buffer[i].uint16 == 26: #Ctrl+Z
close(f) #has the same effect as setting EOF close(f) #has the same effect as setting EOF
if i == 0: if i == 0:
line = "" line = ""
return false return false
@ -480,7 +482,7 @@ proc readLine*(f: File, line: var string): bool {.tags: [ReadIOEffect],
sp = 128 # read in 128 bytes at a time sp = 128 # read in 128 bytes at a time
line.setLen(pos+sp) line.setLen(pos+sp)
proc readLine*(f: File): string {.tags: [ReadIOEffect], benign.} = proc readLine*(f: File): string {.tags: [ReadIOEffect], benign.} =
## reads a line of text from the file `f`. May throw an IO exception. ## reads a line of text from the file `f`. May throw an IO exception.
## A line of text may be delimited by `LF` or `CRLF`. The newline ## A line of text may be delimited by `LF` or `CRLF`. The newline
## character(s) are not part of the returned string. ## character(s) are not part of the returned string.
@ -647,7 +649,7 @@ when defined(posix) and not defined(nimscript):
Stat {.importc: "struct stat", Stat {.importc: "struct stat",
header: "<sys/stat.h>", final, pure.} = object ## struct stat header: "<sys/stat.h>", final, pure.} = object ## struct stat
filler_1: array[24, char] filler_1: array[24, char]
st_mode: Mode ## Mode of file st_mode: Mode ## Mode of file
filler_2: array[144 - 24 - 4, char] filler_2: array[144 - 24 - 4, char]
proc modeIsDir(m: Mode): bool = proc modeIsDir(m: Mode): bool =
@ -660,7 +662,7 @@ when defined(posix) and not defined(nimscript):
Stat {.importc: "struct stat", Stat {.importc: "struct stat",
header: "<sys/stat.h>", final, pure.} = object ## struct stat header: "<sys/stat.h>", final, pure.} = object ## struct stat
st_mode: Mode ## Mode of file st_mode: Mode ## Mode of file
proc modeIsDir(m: Mode): bool {.importc: "S_ISDIR", header: "<sys/stat.h>".} proc modeIsDir(m: Mode): bool {.importc: "S_ISDIR", header: "<sys/stat.h>".}
## Test for a directory. ## Test for a directory.
@ -727,7 +729,8 @@ proc open*(f: var File, filehandle: FileHandle,
## ##
## The passed file handle will no longer be inheritable. ## The passed file handle will no longer be inheritable.
when not defined(nimInheritHandles) and declared(setInheritable): when not defined(nimInheritHandles) and declared(setInheritable):
let oshandle = when defined(windows): FileHandle getOsfhandle(filehandle) else: filehandle let oshandle = when defined(windows): FileHandle getOsfhandle(
filehandle) else: filehandle
if not setInheritable(oshandle, false): if not setInheritable(oshandle, false):
return false return false
f = c_fdopen(filehandle, FormatOpen[mode]) f = c_fdopen(filehandle, FormatOpen[mode])
@ -780,6 +783,10 @@ when declared(stdout):
var echoLock: SysLock var echoLock: SysLock
initSysLock echoLock initSysLock echoLock
when not defined(js) and not defined(nimOwnedEnabled):
import std/exitprocs
addExitProc(proc() {.noconv.} = deinitSys echoLock)
const stdOutLock = not defined(windows) and const stdOutLock = not defined(windows) and
not defined(android) and not defined(android) and
not defined(nintendoswitch) and not defined(nintendoswitch) and
@ -898,7 +905,8 @@ proc readLines*(filename: string, n: Natural): seq[string] =
else: else:
sysFatal(IOError, "cannot open: " & filename) sysFatal(IOError, "cannot open: " & filename)
template readLines*(filename: string): seq[string] {.deprecated: "use readLines with two arguments".} = template readLines*(filename: string): seq[
string] {.deprecated: "use readLines with two arguments".} =
readLines(filename, 1) readLines(filename, 1)
iterator lines*(filename: string): string {.tags: [ReadIOEffect].} = iterator lines*(filename: string): string {.tags: [ReadIOEffect].} =
@ -915,7 +923,7 @@ iterator lines*(filename: string): string {.tags: [ReadIOEffect].} =
for line in filename.lines: for line in filename.lines:
buffer.add(line.replace("a", "0") & '\n') buffer.add(line.replace("a", "0") & '\n')
writeFile(filename, buffer) writeFile(filename, buffer)
var f = open(filename, bufSize=8000) var f = open(filename, bufSize = 8000)
try: try:
var res = newStringOfCap(80) var res = newStringOfCap(80)
while f.readLine(res): yield res while f.readLine(res): yield res