title: c++ implementing semaphore on my own
body: <p>let's pretend there are no libraries that provide semaphores for C++. I wrote this:</p>
  
  <pre><code>#include &lt;vector&gt;
  #include &lt;Windows.h&gt;
  
  class Semaphore {
      HANDLE mutexS;                  //  provides mutex in semaphore rutines
      std::vector&lt;HANDLE&gt; queue;      //  provides FIFO queue for blocked threads
      int value;                      //  semaphore's value
  
  public:
      Semaphore(int init=1);  
      ~Semaphore();
  
      void wait();
      void signal();
  };
  
  
  Semaphore::Semaphore(int init) {
      value = init;
      queue = std::vector&lt;HANDLE&gt;();
      mutexS = CreateMutex(0,0,0);
  }
  
  Semaphore::~Semaphore() {
      CloseHandle(mutexS);
  }
  
  
  
  
  void Semaphore::signal() {
      WaitForSingleObject(mutexS, INFINITE);
      if (++value &lt;= 0) {
          HANDLE someOldThread = queue.front();
          ResumeThread(someOldThread);
          queue.erase(queue.begin());
          CloseHandle(someOldThread);
      }
      ReleaseMutex(mutexS);
  }
  </code></pre>
  
  <p>I would like to know why this implementation of wait() doesn't work:</p>
  
  <pre><code>void Semaphore::wait() {
      WaitForSingleObject(mutexS, INFINITE);
  
      if (--value &lt; 0) {
          HANDLE thisThread = GetCurrentThread();   
          queue.push_back(thisThread);
          ReleaseMutex(mutexS);
          SuspendThread(thisThread );
      }
      else
          ReleaseMutex(mutexS);
  }
  </code></pre>
  
  <p>And this one works:</p>
  
  <pre><code>void Semaphore::wait() {
      WaitForSingleObject(mutexS, INFINITE);
  
      if (--value &lt; 0) {
          HANDLE thisThread = GetCurrentThread();
          HANDLE alsoThisThread;
  
          DuplicateHandle(GetCurrentProcess(), thisThread, GetCurrentProcess(), &amp;alsoThisThread, 0, 0, DUPLICATE_SAME_ACCESS);
  
          queue.push_back(alsoThisThread);
  
          ReleaseMutex(mutexS);
  
          SuspendThread(alsoThisThread);
      }
      else
          ReleaseMutex(mutexS);
  }
  </code></pre>
  
  <p>What exactly happens in each case? I've been banging my head over it for a lot of time now. The first implementation of wait, which doesn't work, makes my program block (well, it probably blocks some thread forever). The 2nd implementation works like a charm. What gives ? Why do I need to duplicate thread handles and block the duplicate ? </p>