You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This code sometimes calls the destructor on the AgentObj twice, but only sporadically. Not really sure if this is a bug in ORC, or just programmer error on my part since I'm doing somewhat hacky stuff. The issue appears to occur when ORC runs the destructor a second time when a temporary copy of the agent is created.
Compiled using nim c --cc:clang --mm:orc -d:breakOrc -d:debug -r torc_badness.nim and run multiple times for i in seq 1 100; do "./torc_badness"; done. Usually 3-5 runs is sufficient.
## torc_badness.nimimport std/tables
import std/unittest
typeWeakRef*[T] {.acyclic.} =object
pt* {.cursor.}: T # cursor effectively is just a pointer, also happens w/ pointer typetemplate`[]`*[T](r: WeakRef[T]): lent T =## using this in the destructor is fine because it's lentcast[T](r.pt)
proctoRef*[T: ref](obj: WeakRef[T]): T =## using this in the destructor breaks ORCresult=cast[T](obj)
typeAgentObj=objectofRootObj
subscribers*: Table[int, WeakRef[Agent]] ## agents listening to mewhendefined(debug):
freed*: bool
moved*: boolAgent*=refobjectofAgentObj# Agent* {.acyclic.} = ref object of AgentObj ## this also avoids the issueproc`=wasMoved`(agent: varAgentObj) =echo"agent was moved"
agent.moved =trueproc`=destroy`*(agentObj: AgentObj) =let xid: WeakRef[Agent] =WeakRef[Agent](pt: cast[Agent](addr agentObj)) ##\## This is pretty hacky, but we need to get the address of the original## Agent (ref object) since it's used to unsubscribe from other agents in the actual code,## Luckily the agent address is the same as `addr agent` of the agent object here.echo"Destroying agent: ",
" pt: ", cast[pointer](xid.pt).repr,
" freed: ", agentObj.freed,
" moved: ", agentObj.moved,
" lstCnt: ", xid[].subscribers.len()
whendefined(debug):
if agentObj.freed:
raisenewException(Defect, "already freed!")
xid[].freed =true## remove subscribers via their WeakRef's## this is where we create a problem## by using `toRef` which creates a *new* Agent reference## which gets added to ORC as a potential cycle check (?)## adding `{.acyclic.}` to whendefined(breakOrc):
if xid.toRef().subscribers.len() >0:
echo"has subscribers"else:
if xid[].subscribers.len() >0:
echo"has subscribers"`=destroy`(xid[].subscribers)
echo"finished destroy: agent: ", " pt: ", cast[pointer](xid.pt).repr
typeCounter*=refobjectofAgent
value: intsuite"threaded agent slots":
test"sigil object thread runner":
block:
var b =Counter.new()
GC_fullCollect()
Nim Version
Nim Compiler Version 2.0.14 [Linux: arm64]
Compiled at 2024-12-23
Copyright (c) 2006-2023 by Andreas Rumpf
git hash: bf4de6a394e040d9810cba8c69fb2829ff04dcc6
active boot switches: -d:release -d:danger
However it does not appear to happen on Mac:
Nim Compiler Version 2.0.14 [MacOSX: arm64]
Compiled at 2024-12-23
Copyright (c) 2006-2023 by Andreas Rumpf
git hash: bf4de6a394e040d9810cba8c69fb2829ff04dcc6
active boot switches: -d:release -d:danger
Description
This code sometimes calls the destructor on the AgentObj twice, but only sporadically. Not really sure if this is a bug in ORC, or just programmer error on my part since I'm doing somewhat hacky stuff. The issue appears to occur when ORC runs the destructor a second time when a temporary copy of the agent is created.
Compiled using
nim c --cc:clang --mm:orc -d:breakOrc -d:debug -r torc_badness.nim
and run multiple timesfor i in
seq 1 100; do "./torc_badness"; done
. Usually 3-5 runs is sufficient.Nim Version
However it does not appear to happen on Mac:
Current Output
The text was updated successfully, but these errors were encountered: