@rayman2220 & @mashingan many thanks for your inputs. The locking/signalling 
stuff seems a little bit nasty because of the behaviour of the underlying layer 
(OS); like always the details hurt 

For some usecases (especially you are looping withing the producer/consumer) it 
doesn`t matter if a signal is lost (signalling before owning and waiting on the 
lock). @mashingan besides of @rayman2220´s comments on your code I think it 
could be possible that (under some circumstances) your last signal-call is lost 
(n=10) so the chanWaiting thread could possible deadlock.

For my usecase I have a "oneshot"-like behaviour because the thread is calling 
signal() only once. So it´s extremely nasty in my eyes that the signal could be 
lost. I thought about that and finally I come up with the following solution 
now (testcode below). Please correct me if I missed something and the example 
is deadlocking on your environment (for me on windows it´s working 
@rayman2220:no clue how microsoft has implemented that but it seems that the 
signal-call on a condition is acting like a latch i.e. at least one signal-call 
is preserved):
    
    
    import locks,os
    
    # globals
    var
      thr: Thread[void]
      cLock: Lock
      lockCond: Cond
      rcvWaiting : bool = false
    
    proc threadFunc () {.thread.} =
      echo "childthread: starting up"
      while true:
      # we like to model a one-shot behaviour so ensure that the receiver is 
owning the lock
        if atomicLoadN[bool](unsafeAddr[bool](rcvWaiting),ATOMIC_SEQ_CST):
          signal(lockCond)
          echo "childthread: signal sent"
          break
        sleep(200) # ugly
      
      echo "childthread: terminated"
    
    initLock(cLock)
    initCond(lockCond)
    
    createThread(thr, threadFunc)
    
    echo "mainthread:begin"
    sleep(3000) # simulate childthread is running before we enter the lock
    echo "mainthread: start waiting"
    
    withLock(cLock):
      # signal the sender that we are owning the lock now
      atomicStoreN[bool](unsafeAddr[bool](rcvWaiting),true,ATOMIC_SEQ_CST)
      wait(lockCond,cLock)
    
    echo "mainthread: end waiting, sig received"
    joinThreads(thr)
    deinitLock(cLock)
    deinitCond(lockCond)
    echo "mainthread:end"
    

Reply via email to