timerscheduler.cc

Go to the documentation of this file.
00001 
00003 
00004 //
00005 // Copyright (c) 2004-2007 University of Southern California
00006 // Rob Peters <rjpeters at usc dot edu>
00007 //
00008 // created: Thu Oct 14 10:03:46 2004
00009 // commit: $Id: timerscheduler.cc 10065 2007-04-12 05:54:56Z rjpeters $
00010 // $HeadURL: file:///lab/rjpeters/svnrepo/code/trunk/groovx/src/tcl/timerscheduler.cc $
00011 //
00012 // --------------------------------------------------------------------
00013 //
00014 // This file is part of GroovX.
00015 //   [http://ilab.usc.edu/rjpeters/groovx/]
00016 //
00017 // GroovX is free software; you can redistribute it and/or modify it
00018 // under the terms of the GNU General Public License as published by
00019 // the Free Software Foundation; either version 2 of the License, or
00020 // (at your option) any later version.
00021 //
00022 // GroovX is distributed in the hope that it will be useful, but
00023 // WITHOUT ANY WARRANTY; without even the implied warranty of
00024 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00025 // General Public License for more details.
00026 //
00027 // You should have received a copy of the GNU General Public License
00028 // along with GroovX; if not, write to the Free Software Foundation,
00029 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00030 //
00032 
00033 #ifndef GROOVX_TCL_TIMERSCHEDULER_CC_UTC20050628162421_DEFINED
00034 #define GROOVX_TCL_TIMERSCHEDULER_CC_UTC20050628162421_DEFINED
00035 
00036 #include "tcl/timerscheduler.h"
00037 
00038 #include "tcl/eventloop.h"
00039 #include "tcl/interp.h"
00040 
00041 #include "rutz/shared_ptr.h"
00042 
00043 #include <tcl.h>
00044 
00045 #include "rutz/trace.h"
00046 #include "rutz/debug.h"
00047 GVX_DBG_REGISTER
00048 
00049 namespace tcl
00050 {
00051   class timer_scheduler_token;
00052 }
00053 
00054 class tcl::timer_scheduler_token : public nub::timer_token
00055 {
00056 public:
00057   timer_scheduler_token(int msec,
00058                         void (*callback)(void*),
00059                         void* clientdata);
00060   virtual ~timer_scheduler_token() throw();
00061 
00062 private:
00063   static void c_callback(void* token) throw();
00064 
00065   typedef void (Callback)(void*);
00066 
00067   Tcl_TimerToken       m_token;
00068   Callback*      const m_callback;
00069   void*          const m_clientdata;
00070 };
00071 
00072 tcl::timer_scheduler_token::
00073 timer_scheduler_token(int msec,
00074                       void (*callback)(void*),
00075                       void* clientdata)
00076   :
00077   m_token(Tcl_CreateTimerHandler(msec,
00078                                  c_callback,
00079                                  static_cast<void*>(this))),
00080   m_callback(callback),
00081   m_clientdata(clientdata)
00082 {
00083 GVX_TRACE("tcl::timer_scheduler_token::timer_scheduler_token");
00084 }
00085 
00086 tcl::timer_scheduler_token::~timer_scheduler_token() throw()
00087 {
00088 GVX_TRACE("tcl::timer_scheduler_token::~timer_scheduler_token");
00089   Tcl_DeleteTimerHandler(m_token);
00090 }
00091 
00092 void tcl::timer_scheduler_token::c_callback(void* token) throw()
00093 {
00094   timer_scheduler_token* tok = static_cast<timer_scheduler_token*>(token);
00095 
00096   GVX_ASSERT(tok != 0);
00097 
00098   try
00099     {
00100       // BE CAREFUL: calling the client callback here may result in
00101       // the TimerScheduleToken object being destroyed. So, if we need
00102       // access to any of the token's member variables, we need to
00103       // make a local copy of them before calling the callback.
00104       (*tok->m_callback)(tok->m_clientdata);
00105     }
00106   catch(...)
00107     {
00108       tcl::event_loop::interp().handle_live_exception("timer callback",
00109                                                 SRC_POS);
00110       tcl::event_loop::interp().background_error();
00111     }
00112 }
00113 
00114 tcl::timer_scheduler::timer_scheduler()
00115 {
00116 GVX_TRACE("tcl::timer_scheduler::timer_scheduler");
00117 }
00118 
00119 tcl::timer_scheduler::~timer_scheduler() throw()
00120 {
00121 GVX_TRACE("tcl::timer_scheduler::~timer_scheduler");
00122 }
00123 
00124 rutz::shared_ptr<nub::timer_token>
00125 tcl::timer_scheduler::schedule(int msec,
00126                               void (*callback)(void*),
00127                               void* clientdata)
00128 {
00129 GVX_TRACE("tcl::timer_scheduler::schedule");
00130   // If the requested delay is zero -- i.e., immediate -- then don't
00131   // bother creating a timer handler. Instead, generate a direct
00132   // invocation; this saves a trip into the event loop and back.
00133   if (msec == 0)
00134     {
00135       (*callback)(clientdata);
00136 
00137       // Return a null pointer, representing the fact that there is no
00138       // pending callback in this case.
00139       return rutz::shared_ptr<nub::timer_token>();
00140     }
00141 
00142   return rutz::shared_ptr<nub::timer_token>
00143     (new tcl::timer_scheduler_token(msec, callback, clientdata));
00144 }
00145 
00146 static const char __attribute__((used)) vcid_groovx_tcl_timerscheduler_cc_utc20050628162421[] = "$Id: timerscheduler.cc 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00147 #endif // !GROOVX_TCL_TIMERSCHEDULER_CC_UTC20050628162421_DEFINED

The software described here is Copyright (c) 1998-2005, Rob Peters.
This page was generated Wed Dec 3 06:49:41 2008 by Doxygen version 1.5.5.