aboutsummaryrefslogtreecommitdiff
path: root/odb/details/win32/condition.cxx
blob: 3a4b605deed182faa2d62e962b8b8db9c33a153d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// file      : odb/details/win32/condition.cxx
// license   : GNU GPL v2; see accompanying LICENSE file

#include <odb/details/win32/windows.hxx>
#include <odb/details/win32/condition.hxx>
#include <odb/details/win32/exceptions.hxx>

namespace odb
{
  namespace details
  {
    void condition::
    signal ()
    {
      mutex_.lock ();

      if (waiters_ > signals_)
      {
        if (signals_++ == 0)
        {
          if (SetEvent (event_) == 0)
            throw win32_exception ();
        }
      }

      mutex_.unlock ();
    }

    void condition::
    wait (lock&)
    {
      // When we enter this functions the mutex is locked. When we
      // return from this function the mutex must be locked.
      //
      waiters_++;
      mutex_.unlock ();

      if (WaitForSingleObject (event_, INFINITE) != 0)
        throw win32_exception ();

      mutex_.lock ();
      waiters_--;
      signals_--;

      if (signals_ > 0)
      {
        // Wake up the next thread.
        //
        if (SetEvent (event_) == 0)
          throw win32_exception ();
      }
    }
  }
}