@Mikra,

Your code works on my machine, and seems sound. I think I have a cleaner 
solution though.

How about this:
    
    
    import locks,os
    
    # globals
    var
      thr: Thread[void]
      cLock: Lock
      lockCond: Cond
    
    proc threadFunc () {.thread.} =
      echo "childthread: starting up"
      # one shot behavior can be achieved by leveraging the lock on the sender 
side as well
      withLock(cLock):
        signal(lockCond)
        echo "childthread: signal sent"
      
      echo "childthread: terminated"
    
    initLock(cLock)
    initCond(lockCond)
    
    echo "mainthread:begin"
    echo "mainthread: start waiting"
    
    withLock(cLock):
      # Create the sending thread after we have alread acquired the lock.
      # The sender thread will be forced to wait for us because we own the lock.
      createThread(thr, threadFunc)
      # The wait function atomically releases the lock, allowing the sender 
thread to continue.
      wait(lockCond,cLock)
    
    echo "mainthread: end waiting, sig received"
    joinThreads(thr)
    deinitLock(cLock)
    deinitCond(lockCond)
    echo "mainthread:end"
    

Look! no timeouts! 

Create the thread **after** you have already acquired the lock. Then you can 
leverage the lock on both the sender and receiver end, along with the property 
that waiting on a condition variable atomically unlocks the lock. The receiver 
thread will atomically re-acquire the lock as soon as it wakes up again.

This gives you a "latch" or "synchronization barrier" to hook in to. (Pick your 
terminology based your favorite text-book on multi-threading lol)

Reply via email to