@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)