Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/net/datagramQueue.cxx

Go to the documentation of this file.
00001 // Filename: datagramQueue.cxx
00002 // Created by:  drose (08Feb00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "datagramQueue.h"
00020 #include "config_net.h"
00021 
00022 ////////////////////////////////////////////////////////////////////
00023 //     Function: DatagramQueue::Constructor
00024 //       Access: Public
00025 //  Description:
00026 ////////////////////////////////////////////////////////////////////
00027 DatagramQueue::
00028 DatagramQueue() {
00029   _shutdown = false;
00030   _cvlock = PR_NewLock();
00031   _cv = PR_NewCondVar(_cvlock);
00032   _max_queue_size = get_net_max_write_queue();
00033 }
00034 
00035 ////////////////////////////////////////////////////////////////////
00036 //     Function: DatagramQueue::Destructor
00037 //       Access: Public
00038 //  Description:
00039 ////////////////////////////////////////////////////////////////////
00040 DatagramQueue::
00041 ~DatagramQueue() {
00042   // It's an error to delete a DatagramQueue without first shutting it
00043   // down (and waiting for any associated threads to terminate).
00044   nassertv(_shutdown);
00045 
00046   PR_DestroyCondVar(_cv);
00047   PR_DestroyLock(_cvlock);
00048 }
00049 
00050 ////////////////////////////////////////////////////////////////////
00051 //     Function: DatagramQueue::shutdown
00052 //       Access: Public
00053 //  Description: Marks the queue as shutting down, which will
00054 //               eventually cause all threads blocking on extract() to
00055 //               return false.  The normal way to delete a
00056 //               DatagramQueue will be to call first shutdown() and
00057 //               then wait for all known threads to terminate.  Then
00058 //               it is safe to delete the queue.
00059 ////////////////////////////////////////////////////////////////////
00060 void DatagramQueue::
00061 shutdown() {
00062   // Notify all of our threads that we're shutting down.  This will
00063   // cause any thread blocking on extract() to return false.
00064   PR_Lock(_cvlock);
00065   _shutdown = true;
00066   PR_NotifyAllCondVar(_cv);
00067   PR_Unlock(_cvlock);
00068 }
00069 
00070 
00071 ////////////////////////////////////////////////////////////////////
00072 //     Function: DatagramQueue::insert
00073 //       Access: Public
00074 //  Description: Inserts the indicated datagram onto the end of the
00075 //               queue, and returns.  If the queue is empty and any
00076 //               threads are waiting on the queue, this will wake one
00077 //               of them up.  Returns true if successful, false if the
00078 //               queue was full.
00079 ////////////////////////////////////////////////////////////////////
00080 bool DatagramQueue::
00081 insert(const NetDatagram &data) {
00082   PR_Lock(_cvlock);
00083   bool enqueue_ok = ((int)_queue.size() < _max_queue_size);
00084   if (enqueue_ok) {
00085 #ifdef __ICL
00086     _queue.push_back(new NetDatagram(data));
00087 #else
00088     _queue.push_back(data);
00089 #endif
00090   }
00091   PR_NotifyCondVar(_cv);
00092   PR_Unlock(_cvlock);
00093   return enqueue_ok;
00094 }
00095 
00096 
00097 ////////////////////////////////////////////////////////////////////
00098 //     Function: DatagramQueue::extract
00099 //       Access: Public
00100 //  Description: Extracts a datagram from the head of the queue, if
00101 //               one is available.  If a datagram is available, this
00102 //               will immediately return; otherwise, it will block
00103 //               until a datagram becomes available.  Multiple threads
00104 //               may simultaneously block on extract(); when a
00105 //               datagram is subsequently inserted into the queue, one
00106 //               of the threads will return from extract() with the
00107 //               datagram.
00108 //
00109 //               The return value is true if the datagram is
00110 //               successfully extracted, or false if the queue was
00111 //               destroyed while waiting.  (In the case of a false
00112 //               return, the thread should not attempt to operate on
00113 //               the queue again.)
00114 ////////////////////////////////////////////////////////////////////
00115 bool DatagramQueue::
00116 extract(NetDatagram &result) {
00117   // First, clear the datagram result in case it's got an outstanding
00118   // connection pointer--we're about to go to sleep for a while.
00119   result.clear();
00120 
00121   PR_Lock(_cvlock);
00122   while (_queue.empty() && !_shutdown) {
00123     PR_WaitCondVar(_cv, PR_INTERVAL_NO_TIMEOUT);
00124   }
00125 
00126   if (_shutdown) {
00127     PR_Unlock(_cvlock);
00128     return false;
00129   }
00130 
00131   nassertr(!_queue.empty(), false);
00132 #ifdef __ICL
00133   NetDatagram *ptr = _queue.front();
00134   result = *ptr;
00135   delete ptr;
00136 #else
00137   result = _queue.front();
00138 #endif
00139   _queue.pop_front();
00140 
00141   PR_Unlock(_cvlock);
00142   return true;
00143 }
00144 
00145 ////////////////////////////////////////////////////////////////////
00146 //     Function: DatagramQueue::set_max_queue_size
00147 //       Access: Public
00148 //  Description: Sets the maximum size the queue is allowed to grow
00149 //               to.  This is primarily for a sanity check; this is a
00150 //               limit beyond which we can assume something bad has
00151 //               happened.
00152 //
00153 //               It's also a crude check against unfortunate seg
00154 //               faults due to the queue filling up and quietly
00155 //               consuming all available memory.
00156 ////////////////////////////////////////////////////////////////////
00157 void DatagramQueue::
00158 set_max_queue_size(int max_size) {
00159   PR_Lock(_cvlock);
00160   _max_queue_size = max_size;
00161   PR_Unlock(_cvlock);
00162 }
00163 
00164 ////////////////////////////////////////////////////////////////////
00165 //     Function: DatagramQueue::get_max_queue_size
00166 //       Access: Public
00167 //  Description: Returns the maximum size the queue is allowed to grow
00168 //               to.  See set_max_queue_size().
00169 ////////////////////////////////////////////////////////////////////
00170 int DatagramQueue::
00171 get_max_queue_size() const {
00172   return _max_queue_size;
00173 }
00174 
00175 ////////////////////////////////////////////////////////////////////
00176 //     Function: DatagramQueue::get_current_queue_size
00177 //       Access: Public
00178 //  Description: Returns the current number of things in the queue.
00179 ////////////////////////////////////////////////////////////////////
00180 int DatagramQueue::
00181 get_current_queue_size() const {
00182   PR_Lock(_cvlock);
00183   int size = _queue.size();
00184   PR_Unlock(_cvlock);
00185   return size;
00186 }

Generated on Fri May 2 00:40:34 2003 for Panda by doxygen1.3