Hello,
Should calling a proc who's reference is held in a variable work within a Thread?
Defining "pass" when compiling avoids the call to the proc variable and allows code to compile and execute correctly. Otherwise, the code fails to compile with version 1.4.8 of the compiler due to the error below:
Warning: 'runAsyncNimAsyncContinue' is not GC-safe as it accesses 'nameIterVar`gensym12' which is a global using GC'ed memory [GcUnsafe2]
Warning: 'runAsync' is not GC-safe as it calls 'runAsyncNimAsyncContinue' [GcUnsafe2]
Error: 'runThr' is not GC-safe as it calls 'runAsync'
See test code below:
import ws, asyncdispatch
import strformat
type
PriceFunc = proc(val: int): int
proc incVal(val: int): int =
result = val + 1
proc ping(wsk: WebSocket) {.async.} =
while true:
await sleepAsync(1000)
echo "sending ping"
await wsk.ping()
proc read(wsk: WebSocket, val: int) {.async.} =
var incProc: PriceFunc
var newVal = val
incProc = incVal
while true:
let str = await wsk.receiveStrPacket()
echo str
when defined(pass):
newVal = incVal(newVal) # Passes
else:
newVal = incProc(newVal) # Function variable induces compiler error
echo &"{newVal=}"
proc runAsync*(wsk: WebSocket, name: string, val: int) {.async.} =
echo &"runAsync: {name=}, {val=}"
asyncCheck read(wsk,val)
asyncCheck ping(wsk)
proc runThr(arg: tuple[name:string, val: int]) {.thread.} =
echo &"runThr: {arg=}"
let (name, val) = arg
var wsk = waitFor newWebsocket("wss://ws.kraken.com")
asyncCheck runAsync(wsk, name, val)
runForever()
proc run(name: string, val: int) =
var thread: Thread[tuple[name: string, val: int]]
createThread(thread,runThr,(name, val))
joinThreads(thread)
when isMainModule:
run("foo",-1)