Files
Nim/lib/std/exitprocs.nim
Timothee Cour dfe51d10a1 addQuitProc now works with closures, and c, js(node/browser) backend; fix some bugs in testament (#14342)
* make addQuitProc great again

* fix bugs in testament

* fix test

* change 2016 => 2020

* addQuitProc => addExitProc + locks

* move to std/exitprocs
2020-06-16 11:43:48 +02:00

66 lines
1.7 KiB
Nim

#
#
# Nim's Runtime Library
# (c) Copyright 2020 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
import locks
type
FunKind = enum kClosure, kNoconv # extend as needed
Fun = object
case kind: FunKind
of kClosure: fun1: proc () {.closure.}
of kNoconv: fun2: proc () {.noconv.}
var
gFunsLock: Lock
gFuns: seq[Fun]
initLock(gFunsLock)
when defined(js):
proc addAtExit(quitProc: proc() {.noconv.}) =
when defined(nodejs):
asm """
process.on('exit', `quitProc`);
"""
elif defined(js):
asm """
window.onbeforeunload = `quitProc`;
"""
else:
proc addAtExit(quitProc: proc() {.noconv.}) {.
importc: "atexit", header: "<stdlib.h>".}
proc callClosures() {.noconv.} =
withLock gFunsLock:
for i in countdown(gFuns.len-1, 0):
let fun = gFuns[i]
case fun.kind
of kClosure: fun.fun1()
of kNoconv: fun.fun2()
template fun() =
if gFuns.len == 0:
addAtExit(callClosures)
proc addExitProc*(cl: proc () {.closure.}) =
## Adds/registers a quit procedure. Each call to `addExitProc` registers
## another quit procedure. They are executed on a last-in, first-out basis.
# Support for `addExitProc` is done by Ansi C's facilities here.
# In case of an unhandled exception the exit handlers should
# not be called explicitly! The user may decide to do this manually though.
withLock gFunsLock:
fun()
gFuns.add Fun(kind: kClosure, fun1: cl)
proc addExitProc*(cl: proc() {.noconv.}) =
## overload for `noconv` procs.
withLock gFunsLock:
fun()
gFuns.add Fun(kind: kNoconv, fun2: cl)