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

panda/src/downloader/asyncUtility.cxx

Go to the documentation of this file.
00001 // Filename: asyncUtility.cxx
00002 // Created by:  mike (09Jan97)
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 "config_downloader.h"
00020 #include "asyncUtility.h"
00021 
00022 #if defined(WIN32)
00023   #define WINDOWS_LEAN_AND_MEAN
00024   #include <wtypes.h>
00025   #undef WINDOWS_LEAN_AND_MEAN  
00026 #else
00027   #include <sys/time.h>
00028 #endif
00029 
00030 ////////////////////////////////////////////////////////////////////
00031 // Defines
00032 ////////////////////////////////////////////////////////////////////
00033 
00034 ////////////////////////////////////////////////////////////////////
00035 //     Function: AsyncUtility::Constructor
00036 //       Access: Public
00037 //  Description:
00038 ////////////////////////////////////////////////////////////////////
00039 AsyncUtility::
00040 AsyncUtility(float frequency) : _frequency(frequency) {
00041   _next_token = 1;
00042   _shutdown = false;
00043   _threaded = false;
00044   _threads_enabled = true;
00045 
00046 #ifdef OLD_HAVE_IPC
00047   _request_cond = new condition_variable(_lock);
00048 #endif
00049 }
00050 
00051 ////////////////////////////////////////////////////////////////////
00052 //     Function: AsyncUtility::Destructor
00053 //       Access: Public
00054 //  Description:
00055 ////////////////////////////////////////////////////////////////////
00056 AsyncUtility::
00057 ~AsyncUtility() {
00058 #ifdef OLD_HAVE_IPC
00059   delete _request_cond;
00060 #endif
00061 }
00062 
00063 ////////////////////////////////////////////////////////////////////
00064 //     Function: AsyncUtility::create_thread
00065 //       Access: Public
00066 //  Description:
00067 ////////////////////////////////////////////////////////////////////
00068 void AsyncUtility::
00069 create_thread(void) {
00070 #ifdef OLD_HAVE_IPC
00071   if (_threaded == false && _threads_enabled == true) {
00072     downloader_cat.debug()
00073       << "AsyncUtility::create_thread()" << endl;
00074     _thread = thread::create(&st_callback, this, thread::PRIORITY_NORMAL);
00075     _threaded = true;
00076   }
00077 #endif
00078 }
00079 
00080 ////////////////////////////////////////////////////////////////////
00081 //     Function: AsyncUtility::destroy_thread
00082 //       Access: Protected
00083 //  Description:
00084 ////////////////////////////////////////////////////////////////////
00085 void AsyncUtility::
00086 destroy_thread(void) {
00087 #ifdef OLD_HAVE_IPC
00088   if (_threaded == false)
00089     return;
00090 
00091   // Tell the thread to shut itself down.
00092   // We need to grab the lock in order to signal the condition variable
00093   _lock.lock();
00094     _shutdown = true;
00095     _request_cond->signal();
00096   _lock.unlock();
00097 
00098   // Join the loader thread - calling process blocks until the loader
00099   // thread returns.
00100   void *ret;
00101   _thread->join(&ret);
00102 #endif
00103 }
00104 
00105 ////////////////////////////////////////////////////////////////////
00106 //     Function: AsyncUtility::st_callback
00107 //       Access: Protected, Static
00108 //  Description: This is a static wrapper around the callback()
00109 //               method, below.  It's static just so we can pass it to
00110 //               the thread-creation function.  In addition, the
00111 //               function has a void* return type even though we
00112 //               don't actually return anything.  This is necessary
00113 //               because ipc assumes a function that does not return
00114 //               anything indicates that the associated thread should
00115 //               be created as unjoinable (detached).
00116 ////////////////////////////////////////////////////////////////////
00117 void* AsyncUtility::
00118 st_callback(void *arg) {
00119 #ifdef OLD_HAVE_IPC
00120   nassertr(arg != NULL, NULL);
00121   ((AsyncUtility *)arg)->callback();
00122 #endif
00123   return NULL;
00124 }
00125 
00126 ////////////////////////////////////////////////////////////////////
00127 //     Function: AsyncUtility::callback
00128 //       Access: Protected
00129 //  Description: This is the main body of the sub-thread.  It waits
00130 //               forever for a request to show up, and then serves it.
00131 ////////////////////////////////////////////////////////////////////
00132 void AsyncUtility::
00133 callback(void) {
00134 #ifdef OLD_HAVE_IPC
00135   while (process_request()) {
00136     // Sleep until a signal arrives
00137     _lock.lock();
00138       _request_cond->wait();
00139     _lock.unlock();
00140   }
00141 #endif
00142 }
00143 
00144 ////////////////////////////////////////////////////////////////////
00145 //     Function: AsyncUtility::nap
00146 //       Access: Protected
00147 //  Description:
00148 ////////////////////////////////////////////////////////////////////
00149 void AsyncUtility::
00150 nap(void) const {
00151 #ifdef OLD_HAVE_IPC
00152 #ifdef WIN32
00153   _sleep((DWORD)(1000 * _frequency));
00154 #else
00155   struct timeval tv;
00156   tv.tv_sec = 0;
00157   tv.tv_usec = (long)(1000000 * _frequency);
00158   select(0, NULL, NULL, NULL, &tv);
00159 #endif
00160 #endif  // OLD_HAVE_IPC
00161 }

Generated on Fri May 2 00:36:42 2003 for Panda by doxygen1.3