tcltimertest.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: Tue Oct 12 18:25:51 2004
00009 // commit: $Id: tcltimertest.cc 10065 2007-04-12 05:54:56Z rjpeters $
00010 // $HeadURL: file:///lab/rjpeters/svnrepo/code/trunk/groovx/src/pkgs/whitebox/tcltimertest.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_PKGS_WHITEBOX_TCLTIMERTEST_CC_UTC20050626084022_DEFINED
00034 #define GROOVX_PKGS_WHITEBOX_TCLTIMERTEST_CC_UTC20050626084022_DEFINED
00035 
00036 #include "pkgs/whitebox/tcltimertest.h"
00037 
00038 #include "nub/timer.h"
00039 
00040 #include "tcl/pkg.h"
00041 #include "tcl/timerscheduler.h"
00042 
00043 #include "rutz/shared_ptr.h"
00044 #include "rutz/unittest.h"
00045 
00046 #include <cstdlib> // for abs()
00047 #include <tcl.h>
00048 #include <unistd.h> // for usleep()
00049 
00050 #include "rutz/trace.h"
00051 #include "rutz/debug.h"
00052 GVX_DBG_REGISTER
00053 
00054 namespace
00055 {
00056   int v0 = 0;
00057   int v1 = 0;
00058   int v2 = 0;
00059   nub::timer* tp1 = 0;
00060 
00061   void v0_callback()
00062   {
00063     v0 += 1;
00064   }
00065 
00066   void v1_callback()
00067   {
00068     v1 -= 1;
00069     GVX_ASSERT(tp1 != 0);
00070     if (v1 < -3) tp1->cancel();
00071   }
00072 
00073   void v2_callback()
00074   {
00075     v2 += 2;
00076   }
00077 
00078   void testTimer1()
00079   {
00080     v0 = 0;
00081     v1 = 0;
00082     v2 = 0;
00083 
00084     rutz::shared_ptr<tcl::timer_scheduler> s
00085       (rutz::make_shared(new tcl::timer_scheduler));
00086 
00087     nub::timer t0(20, false);
00088     nub::timer t1(5,  true);
00089     nub::timer t2(0,  false);
00090 
00091     tp1 = &t1;
00092 
00093     TEST_REQUIRE(!t0.is_pending());
00094     TEST_REQUIRE(!t1.is_pending());
00095     TEST_REQUIRE(!t2.is_pending());
00096 
00097     t0.sig_timeout.connect(&v0_callback);
00098     t1.sig_timeout.connect(&v1_callback);
00099     t2.sig_timeout.connect(&v2_callback);
00100 
00101     t0.schedule(s);
00102     t1.schedule(s);
00103     t2.schedule(s); // delay==0 ==> callback should happen immediately
00104 
00105     TEST_REQUIRE(t0.is_pending());
00106     TEST_REQUIRE(t1.is_pending());
00107     TEST_REQUIRE(!t2.is_pending());
00108 
00109     TEST_REQUIRE_EQ(v2, 2);
00110 
00111     int loops = 0;
00112     int events = 0;
00113 
00114     while (t0.elapsed_msec() < 500.0 &&
00115            (t0.is_pending() || t1.is_pending()))
00116       {
00117         if (Tcl_DoOneEvent(TCL_TIMER_EVENTS|TCL_DONT_WAIT) != 0)
00118           ++events;
00119 
00120         usleep(1000);
00121 
00122         ++loops;
00123       }
00124 
00125     dbg_eval_nl(3, loops);
00126     dbg_eval_nl(3, events);
00127 
00128     TEST_REQUIRE_EQ(v0, 1);
00129     TEST_REQUIRE_EQ(v1, -4);
00130 
00131     tp1 = 0;
00132   }
00133 
00134   void testTimerCancel()
00135   {
00136     v0 = 0;
00137 
00138     rutz::shared_ptr<tcl::timer_scheduler> s
00139       (rutz::make_shared(new tcl::timer_scheduler));
00140 
00141     nub::timer t0(10, false);
00142 
00143     t0.sig_timeout.connect(&v0_callback);
00144 
00145     TEST_REQUIRE(!t0.is_pending());
00146 
00147     t0.schedule(s);
00148 
00149     TEST_REQUIRE(t0.is_pending());
00150     TEST_REQUIRE_EQ(v0, 0);
00151 
00152     while (t0.elapsed_msec() < 15.0)
00153       {
00154         Tcl_DoOneEvent(TCL_TIMER_EVENTS|TCL_DONT_WAIT);
00155 
00156         t0.cancel();
00157         usleep(1000);
00158       }
00159 
00160     TEST_REQUIRE(!t0.is_pending());
00161     TEST_REQUIRE_EQ(v0, 0);
00162   }
00163 
00164   // Make sure that we don't let ourselves get into an infinite loop
00165   void testTimerNoInfiniteLoop()
00166   {
00167     rutz::shared_ptr<tcl::timer_scheduler> s
00168       (rutz::make_shared(new tcl::timer_scheduler));
00169 
00170     nub::timer t(0, true);
00171 
00172     bool caught = false;
00173 
00174     try
00175       {
00176         t.schedule(s);
00177       }
00178     catch (rutz::error&)
00179       {
00180         caught = true;
00181       }
00182 
00183     TEST_REQUIRE(caught == true);
00184   }
00185 
00186   // Should test the way that the tcl::interpreter responds if an
00187   // error occurs during the timer callback.
00188   void testTimerCallbackError()
00189   {
00190   }
00191 }
00192 
00193 extern "C"
00194 int Tcltimertest_Init(Tcl_Interp* interp)
00195 {
00196 GVX_TRACE("Tcltimertest_Init");
00197 
00198   GVX_PKG_CREATE(pkg, interp, "Tcltimertest", "4.$Revision: 10065 $");
00199 
00200   DEF_TEST(pkg, testTimer1);
00201   DEF_TEST(pkg, testTimerCancel);
00202   DEF_TEST(pkg, testTimerNoInfiniteLoop);
00203   DEF_TEST(pkg, testTimerCallbackError);
00204 
00205   GVX_PKG_RETURN(pkg);
00206 }
00207 
00208 // Need these to avoid dyld errors on Mac OS X
00209 extern "C" int Tcltimertest_SafeInit(Tcl_Interp*)
00210 { return 1; }
00211 
00212 extern "C" int Tcltimertest_Unload(Tcl_Interp* interp, int /*flags*/)
00213 {
00214 GVX_TRACE("Tcltimertest_Unload");
00215   return tcl::pkg::destroy_on_unload(interp, "Tcltimertest");
00216 }
00217 
00218 extern "C" int Tcltimertest_SafeUnload(Tcl_Interp*, int /*flags*/)
00219 { return 1; }
00220 
00221 static const char __attribute__((used)) vcid_groovx_pkgs_whitebox_tcltimertest_cc_utc20050626084022[] = "$Id: tcltimertest.cc 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00222 #endif // !GROOVX_PKGS_WHITEBOX_TCLTIMERTEST_CC_UTC20050626084022_DEFINED

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