In my test, I have this code:
    
    
    type
      TstMsg = Msg[int]
      TstRep = Msg[float]
    
    var dst: QueueID
    
    initThreadID(ThreadID(0))
    
    var m: TstMsg
    m.content = 42
    
    when USE_TOPICS:
      initTopicID(TopicID(33))
      let pid = myProcessID()
      dst = queueID(pid, ThreadID(1), TopicID(99))
    else:
      dst = queueID(myProcessID(), ThreadID(1))
    
    assert(not pendingMsg())
    sendMsgNow(dst, addr m)
    
    echo("First msg sent from Thread 0.")
    

which in sendMsgNow() indirectly accesses this threadvar:
    
    
    var myPendingRequests {.threadvar.}: HashSet[ptr MsgBase]
    myPendingRequests.init()
    

And it works. However, if I refactor my code like this (moving all code after 
"var dst: QueueID" to a proc, and calling it):
    
    
    type
      TstMsg = Msg[int]
      TstRep = Msg[float]
    
    var dst: QueueID
    
    proc startTest() =
      initThreadID(ThreadID(0))
      
      var m: TstMsg
      m.content = 42
      
      when USE_TOPICS:
        initTopicID(TopicID(33))
        let pid = myProcessID()
        dst = queueID(pid, ThreadID(1), TopicID(99))
      else:
        dst = queueID(myProcessID(), ThreadID(1))
      
      assert(not pendingMsg())
      sendMsgNow(dst, addr m)
      
      echo("First msg sent from Thread 0.")
    
    startTest()
    

Then I get this error:
    
    
    Traceback (most recent call last)
    test_kueues.nim(128)     receiver
    kueues.nim(830)          recvMsgs
    kueues.nim(785)          collectReceived
    kueues.nim(771)          validateRequest
    sets.nim(204)            contains
    system.nim(3613)         failedAssertImpl
    system.nim(3605)         raiseAssert
    system.nim(2724)         sysFatal
    Error: unhandled exception: isValid(s) The set needs to be initialized. 
[AssertionError]
    Error: execution of an external program failed: '../bin/test_kueues '
    The terminal process terminated with exit code: 1
    

kueues.nim(771) is accessing myPendingRequests.

All the rest of the code is unchanged.

How could myPendingRequests ever _not_ be initialized, and why is that only so 
if I move some top level code to a proc, which I then call at the exact same 
place the top level code was before?

Even if myPendingRequests.init() ran only once, and not once per thread (does 
it? and if yes, how do you say "do this in every thread"?), I still don't think 
it would explain that the error only comes when the code is not "top level".

Reply via email to