HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_ThreadQueue.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: UT_ThreadQueue.h ( UT Library, C++)
7  *
8  * COMMENTS:
9  * Modelled after Python's Queue, this is a simple queue
10  * which you can use to communicate to another thread with.
11  */
12 
13 #ifndef __UT_ThreadQueue__
14 #define __UT_ThreadQueue__
15 
16 #include "UT_API.h"
17 #include "UT_Thread.h"
18 #include "UT_Condition.h"
19 #include "UT_RingBuffer.h"
20 
21 ///
22 /// UT_ThreadQueue
23 ///
24 /// Designed to be templated on a POD.
25 ///
26 template <typename T>
28 {
29 public:
30  /// A max cost of -1 will never block on adding items to the queue.
31  UT_ThreadQueue(exint maxcost = -1)
32  {
33  myMaxCost = maxcost;
34  myCurrentCost = 0;
35  }
37 
38  /// Synchronized test for number of entries
39  int entries() const
40  {
41  UT_AutoLock l(myLock);
42 
43  return myList.entries();
44  }
45 
46  /// Removes an item, returns false if failed to remove because
47  /// the queue was empty.
48  bool remove(T &item)
49  {
50  UT_AutoLock l(myLock);
51 
52  if (isEmpty())
53  return false;
54  item = myList.popFirst();
55  exint cost = myCost.popFirst();
56  myCurrentCost -= cost;
57 
58  // Let people know it may now be empty.
59  myCond.triggerAll();
60  return true;
61  }
62 
63  /// Blocks until the item is ready.
65  {
66  UT_AutoLock l(myLock);
67  T result;
68 
69  while (!remove(result))
70  {
71  myCond.waitForTrigger(myLock);
72  }
73  return result;
74  }
75 
76  /// Blocks until the queue is empty.
77  /// May not still be empty, since someone could add after
78  /// you reach empty!
79  void waitForEmpty()
80  {
81  UT_AutoLock l(myLock);
82 
83  while (!isEmpty())
84  {
85  myCond.waitForTrigger(myLock);
86  }
87  }
88 
89  /// Blocks until a queue change occurs, returns the new queue size.
90  /// Returns zero immediately if queue is empty.
92  {
93  UT_AutoLock l(myLock);
94 
95  if (isEmpty())
96  return 0;
97 
98  myCond.waitForTrigger(myLock);
99  return myList.entries();
100  }
101 
102  /// Adds the item to the queue.
103  /// Will block if it the total cost would be exceeded by
104  /// adding this to the queue.
105  /// Zero cost never block, nor does a max cost of -1
106  void append(const T &item, exint cost = 0)
107  {
108  UT_AutoLock l(myLock);
109 
110  // Check if we'll exceed the cost.
111  while (1)
112  {
113  // IF we are empty, add even if too expensive!
114  if (cost && myMaxCost >= 0 && (myCurrentCost > 0) && (myCurrentCost + cost > myMaxCost))
115  {
116  // Too expensive to add right now, so await a trigger.
117  myCond.waitForTrigger(myLock);
118  }
119  else
120  {
121  // Enough room for the new item.
122  break;
123  }
124  }
125 
126  // Append
127  myList.push(item);
128  myCost.push(cost);
129  myCurrentCost += cost;
130 
131  // Alert anyone waiting to wake up.
132  myCond.triggerAll();
133  }
134 
135 protected:
136  /// Non-synchronized, do not call outside of the lock.
137  bool isEmpty() const
138  {
139  return !myList.entries();
140  }
141 
142 private:
143  /// Prohibit copying as I am not sure if lock semantics will work.
145  UT_ThreadQueue<T> &operator=(const UT_ThreadQueue<T> &ref) {}
146 
147  UT_RingBuffer<T> myList;
148  UT_RingBuffer<exint> myCost;
149  exint myMaxCost;
150  exint myCurrentCost;
151 
152  mutable UT_Lock myLock;
153  UT_Condition myCond;
154 };
155 
156 #endif
157 
158 
bool isEmpty() const
Non-synchronized, do not call outside of the lock.
int waitForQueueChange()
UT_ThreadQueue(exint maxcost=-1)
A max cost of -1 will never block on adding items to the queue.
void waitForTrigger(UT_Lock &lock)
GLint ref
Definition: glcorearb.h:123
int64 exint
Definition: SYS_Types.h:116
void append(const T &item, exint cost=0)
void triggerAll()
int push(const T &data)
T waitAndRemove()
Blocks until the item is ready.
int entries() const
Synchronized test for number of entries.