aboutsummaryrefslogtreecommitdiff
path: root/odb/details/win32/condition.cxx
blob: 157c453848542c48e7f8a1086c8db83b03677aad (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
55
56
57
58
59
60
// file      : odb/details/win32/condition.cxx
// copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC
// license   : GNU GPL v2; see accompanying LICENSE file

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <windows.h>

#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 ()
    {
      // 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 ();
      }
    }
  }
}