1 /**
2 * Semaphore implementation for basefilt.d
3 * 
4 * Copyright:
5 * (C) 2014-2015 Jack Lloyd
6 * (C) 2014-2015 Etienne Cimon
7 *
8 * License:
9 * Botan is released under the Simplified BSD License (see LICENSE.md)
10 */
11 module botan.utils.semaphore;
12 
13 import core.sync.mutex;
14 import core.sync.condition;
15 
16 class Semaphore
17 {
18 public:
19     this(int value = 0)
20     {
21         m_value = value;
22         m_wakeups = 0;
23         m_mutex = new Mutex;
24         m_cond = new Condition(m_mutex);
25     }
26     
27     void acquire()
28     {
29         synchronized(m_mutex) {
30             --m_value;
31             if (m_value < 0)
32             {
33                 m_cond.wait();
34                 --m_wakeups;
35             }
36         }
37     }
38     
39     void release(size_t n = 1)
40     {
41         for(size_t i = 0; i != n; ++i)
42         {
43             synchronized(m_mutex) {
44             
45                 ++m_value;
46                 
47                 if (m_value <= 0)
48                 {
49                     ++m_wakeups;
50                     m_cond.notify();
51                 }
52             }
53         }
54     }
55     
56 private:
57     int m_value;
58     int m_wakeups;
59     Mutex m_mutex;
60     Condition m_cond;
61 }