Panda3D
|
00001 // Filename: queuedReturn.I 00002 // Created by: drose (25Feb00) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 00016 //////////////////////////////////////////////////////////////////// 00017 // Function: QueuedReturn::set_max_queue_size 00018 // Access: Public 00019 // Description: Sets the maximum size the queue is allowed to grow 00020 // to. This is primarily for a sanity check; this is a 00021 // limit beyond which we can assume something bad has 00022 // happened. 00023 // 00024 // It's also a crude check against unfortunate seg 00025 // faults due to the queue filling up and quietly 00026 // consuming all available memory. 00027 //////////////////////////////////////////////////////////////////// 00028 template<class Thing> 00029 void QueuedReturn<Thing>:: 00030 set_max_queue_size(int max_size) { 00031 LightMutexHolder holder(_mutex); 00032 _max_queue_size = max_size; 00033 } 00034 00035 //////////////////////////////////////////////////////////////////// 00036 // Function: QueuedReturn::get_max_queue_size 00037 // Access: Public 00038 // Description: Returns the maximum size the queue is allowed to grow 00039 // to. See set_max_queue_size(). 00040 //////////////////////////////////////////////////////////////////// 00041 template<class Thing> 00042 int QueuedReturn<Thing>:: 00043 get_max_queue_size() const { 00044 return _max_queue_size; 00045 } 00046 00047 //////////////////////////////////////////////////////////////////// 00048 // Function: QueuedReturn::get_current_queue_size 00049 // Access: Public 00050 // Description: Returns the current number of things in the queue. 00051 //////////////////////////////////////////////////////////////////// 00052 template<class Thing> 00053 int QueuedReturn<Thing>:: 00054 get_current_queue_size() const { 00055 LightMutexHolder holder(_mutex); 00056 int size = _things.size(); 00057 return size; 00058 } 00059 00060 //////////////////////////////////////////////////////////////////// 00061 // Function: QueuedReturn::get_overflow_flag 00062 // Access: Published 00063 // Description: Returns true if the queue has overflowed since the 00064 // last call to reset_overflow_flag() (implying that 00065 // some elements have been dropped from the queue), or 00066 // false otherwise. 00067 //////////////////////////////////////////////////////////////////// 00068 template<class Thing> 00069 bool QueuedReturn<Thing>:: 00070 get_overflow_flag() const { 00071 return _overflow_flag; 00072 } 00073 00074 //////////////////////////////////////////////////////////////////// 00075 // Function: QueuedReturn::reset_overflow_flag 00076 // Access: Published 00077 // Description: Resets the overflow flag so that get_overflow_flag() 00078 // will return false until a new overflow occurs. 00079 //////////////////////////////////////////////////////////////////// 00080 template<class Thing> 00081 void QueuedReturn<Thing>:: 00082 reset_overflow_flag() { 00083 _overflow_flag = false; 00084 } 00085 00086 //////////////////////////////////////////////////////////////////// 00087 // Function: QueuedReturn::Constructor 00088 // Access: Protected 00089 // Description: 00090 //////////////////////////////////////////////////////////////////// 00091 template<class Thing> 00092 QueuedReturn<Thing>:: 00093 QueuedReturn() { 00094 _available = false; 00095 _max_queue_size = get_net_max_response_queue(); 00096 _overflow_flag = false; 00097 } 00098 00099 //////////////////////////////////////////////////////////////////// 00100 // Function: QueuedReturn::Destructor 00101 // Access: Protected 00102 // Description: 00103 //////////////////////////////////////////////////////////////////// 00104 template<class Thing> 00105 QueuedReturn<Thing>:: 00106 ~QueuedReturn() { 00107 } 00108 00109 //////////////////////////////////////////////////////////////////// 00110 // Function: QueuedReturn::thing_available 00111 // Access: Protected 00112 // Description: Returns true if a thing is available on the queue; 00113 // call get_thing() to extract the thing. 00114 //////////////////////////////////////////////////////////////////// 00115 template<class Thing> 00116 INLINE bool QueuedReturn<Thing>:: 00117 thing_available() const { 00118 return _available; 00119 } 00120 00121 //////////////////////////////////////////////////////////////////// 00122 // Function: QueuedReturn::get_thing 00123 // Access: Protected 00124 // Description: If a previous call to thing_available() returned 00125 // true, this function will return the thing that has 00126 // become available. 00127 // 00128 // The return value is true if a thing was 00129 // successfully returned, or false if there was, in 00130 // fact, no thing available. (This may happen if 00131 // there are multiple threads accessing the 00132 // QueuedReturn). 00133 //////////////////////////////////////////////////////////////////// 00134 template<class Thing> 00135 bool QueuedReturn<Thing>:: 00136 get_thing(Thing &result) { 00137 LightMutexHolder holder(_mutex); 00138 if (_things.empty()) { 00139 // Huh. Nothing after all. 00140 _available = false; 00141 return false; 00142 } 00143 00144 result = _things.front(); 00145 _things.pop_front(); 00146 _available = !_things.empty(); 00147 return true; 00148 } 00149 00150 //////////////////////////////////////////////////////////////////// 00151 // Function: QueuedReturn::enqueue_thing 00152 // Access: Protected 00153 // Description: Adds a new thing to the queue for later retrieval. 00154 // Returns true if successful, false if the queue is 00155 // full (i.e. has reached _max_queue_size). 00156 //////////////////////////////////////////////////////////////////// 00157 template<class Thing> 00158 bool QueuedReturn<Thing>:: 00159 enqueue_thing(const Thing &thing) { 00160 LightMutexHolder holder(_mutex); 00161 bool enqueue_ok = ((int)_things.size() < _max_queue_size); 00162 if (enqueue_ok) { 00163 _things.push_back(thing); 00164 } else { 00165 _overflow_flag = true; 00166 } 00167 _available = true; 00168 00169 return enqueue_ok; 00170 } 00171 00172 //////////////////////////////////////////////////////////////////// 00173 // Function: QueuedReturn::enqueue_unique_thing 00174 // Access: Protected 00175 // Description: The same as enqueue_thing(), except the queue is 00176 // first checked that it doesn't already have something 00177 // like thing. The return value is true if the enqueue 00178 // operation was successful, false if the queue was full 00179 // or the thing was already on the queue. 00180 //////////////////////////////////////////////////////////////////// 00181 template<class Thing> 00182 bool QueuedReturn<Thing>:: 00183 enqueue_unique_thing(const Thing &thing) { 00184 LightMutexHolder holder(_mutex); 00185 bool enqueue_ok = ((int)_things.size() < _max_queue_size); 00186 if (enqueue_ok) { 00187 if (find(_things.begin(), _things.end(), thing) == _things.end()) { 00188 // It wasn't there already; add it now. 00189 _things.push_back(thing); 00190 } else { 00191 // It was already there; return false to indicate this. 00192 enqueue_ok = false; 00193 } 00194 00195 } else { 00196 _overflow_flag = true; 00197 } 00198 _available = true; 00199 00200 return enqueue_ok; 00201 }