summaryrefslogtreecommitdiff
path: root/java/src/Condition.java
blob: 59a97c9a1a700d5be1678a03eaeeb7a6fcbff8d9 (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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/*************************************************
 *
 * = PACKAGE
 *    JACE.Concurrency
 *
 * = FILENAME
 *    Condition.java
 *
 *@author Irfan Pyarali
 *
 *************************************************/
package JACE.Concurrency;

import JACE.ASX.TimeoutException;
import JACE.ASX.TimeValue;

/**
 * <hr>
 * <h2>TITLE</h2>
 *<blockquote>
 *     Abstraction for <em>traditional</em> 
 *     condition variable
 *</blockquote>
 *
 * <h2>DESCRIPTION</h2>
 *<blockquote>
 *     This condition variable allows the use of one 
 *     mutex between multiple conditions. 
 *     This implementation is based on the C++ version of ACE.
 *</blockquote>
 */
public class Condition
{
  /** 
   * Default constructor
   *@param Mutex for synchronization
   */
  public Condition (Mutex mutex)
  {
    mutex_ = mutex;
  }
  
  /**
   * Wait for condition to become signaled. 
   *@exception InterruptedException exception during wait
   */
  public void Wait () 
    throws InterruptedException
  {
    waiters_++;

    try
      {
	mutex_.release();
	semaphore_.acquire ();
	mutex_.acquire ();
      }
    finally 
      {
	waiters_--;
      }
  }
  
  /**
   * TimedWait for condition to become signaled. 
   *@exception TimeoutException wait timed out exception
   *@exception InterruptedException exception during wait
   */
  public void Wait (TimeValue tv) 
    throws TimeoutException, InterruptedException
  {
    waiters_++;

    try
      {
	mutex_.release();

	TimeValue start = TimeValue.getTimeOfDay ();

	semaphore_.acquire (tv);

	TimeValue now = TimeValue.getTimeOfDay ();
	tv.minusEquals (TimeValue.minus (now, start));

	mutex_.acquire (tv);
      }
    finally 
      {
	waiters_--;
      }
  }
  
  /**
   * Signal condition. Wake one waiter (if any).
   */
  public void signal ()
  {
    if (waiters_ > 0)
      semaphore_.release ();
  }

  /**
   * Signal condition. Wake up all waiters (if any).
   */
  public void broadcast ()
  {
    for (int i = waiters_; i > 0; i--)
      semaphore_.release ();
  }

  /** 
   * Accessor to lock
   *@return Mutex
   */
  public Mutex mutex ()
  {
    return mutex_;
  }

  private int waiters_;  
  private Semaphore semaphore_ = new Semaphore (0);
  private Mutex mutex_;

}