I have the following program:
import os
import posix_utils
import strformat
import threadpool
let tempRootPath = mkdtemp("vppdiff")
proc xmiFilePath(fileNumber: int, cleaned: bool): string =
let cleanedSuffix = "_cleaned"
return tempRootPath / fmt"xmi{fileNumber}{cleanedSuffix}.xmi"
var fv = spawn xmiFilePath(1, false)
echo ^fv
When I try to compile it with Nim 1.0.0, I get
$ nim c --threads:on -r src/gcsafe_example.nim
...
gcsafe_example.nim(13, 27) Error: 'spawn' takes a GC safe call expression
Looking at https://nim-lang.org/docs/manual.html#threads-gc-safety , this is reasonable. Actually with a {.gcsafe.} block, as in
import os
import posix_utils
import strformat
import threadpool
let tempRootPath = mkdtemp("vppdiff")
proc xmiFilePath(fileNumber: int, cleaned: bool): string =
let cleanedSuffix = "_cleaned"
{.gcsafe.}:
return tempRootPath / fmt"xmi{fileNumber}{cleanedSuffix}.xmi"
var fv = spawn xmiFilePath(1, false)
echo ^fv
the program is compiled and seems to work.
Questions:
import os
import posix_utils
import strformat
import threadpool
var tempRootPath {.threadvar.}: string
proc xmiFilePath(fileNumber: int, cleaned: bool): string =
let cleanedSuffix = "_cleaned"
if tempRootPath.len == 0:
# I'm assuming here that ``mkdtemp`` uses a lock...
tempRootPath = mkdtemp("vppdiff")
return tempRootPath / fmt"xmi{fileNumber}{cleanedSuffix}.xmi"
var fv = spawn xmiFilePath(1, false)
echo ^fv
Thanks for your answers and the code suggestion. I see what you're doing here, but I need the same temporary directory for all threads. :-)
Would the approach with deepcopy as in the manual be safe?
import os
import posix_utils
import strformat
import threadpool
let tempRootPath = mkdtemp("vppdiff")
var tempRootPathPerThread {.threadvar.}: string
proc xmiFilePath(fileNumber: int, cleaned: bool): string =
let cleanedSuffix = "_cleaned"
{.gcsafe.}:
deepcopy(tempRootPathPerThread, tempRootPath)
return tempRootPathPerThread / fmt"xmi{fileNumber}{cleanedSuffix}.xmi"
var fv = spawn xmiFilePath(1, false)
echo ^fv
I'm looking forward to the new GC. :-)