[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash ChangeLog libbase/GC.h server/movie_root....
From: |
Sandro Santilli |
Subject: |
[Gnash-commit] gnash ChangeLog libbase/GC.h server/movie_root.... |
Date: |
Mon, 02 Jul 2007 03:20:34 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Changes by: Sandro Santilli <strk> 07/07/02 03:20:34
Modified files:
. : ChangeLog
libbase : GC.h
server : movie_root.cpp movie_root.h timers.cpp timers.h
server/asobj : LoadVars.cpp xmlsocket.cpp
Log message:
* libbase/GC.h: don't be verbose about GC by default.
* server/movie_root.{cpp,h}: (add_interval_timer): take the
Timer by
auto_ptr, add an optional second argument marking the timer as
internal (for use by xmlsocket/LoadVars and whichever other
gnash
internal class in need for a timer). Internal timers will get
a
negative identifier so to not introduce unexpected gaps in the
user-defined interval timers sequences. Fix bugs introduced
in last
commit related to timer expiration and iterators invalidation.
* server/timers.{cpp,h}: add some inspector functions, use
VM::getTime
for timers (milliseconds).
* server/asobj/: LoadVars.cpp, xmlsocket.cpp: update calls to
movie_root::add_interval_timer to mark these timers as
internal.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.3631&r2=1.3632
http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/GC.h?cvsroot=gnash&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_root.cpp?cvsroot=gnash&r1=1.71&r2=1.72
http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_root.h?cvsroot=gnash&r1=1.62&r2=1.63
http://cvs.savannah.gnu.org/viewcvs/gnash/server/timers.cpp?cvsroot=gnash&r1=1.35&r2=1.36
http://cvs.savannah.gnu.org/viewcvs/gnash/server/timers.h?cvsroot=gnash&r1=1.24&r2=1.25
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/LoadVars.cpp?cvsroot=gnash&r1=1.26&r2=1.27
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/xmlsocket.cpp?cvsroot=gnash&r1=1.30&r2=1.31
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.3631
retrieving revision 1.3632
diff -u -b -r1.3631 -r1.3632
--- ChangeLog 2 Jul 2007 00:18:24 -0000 1.3631
+++ ChangeLog 2 Jul 2007 03:20:33 -0000 1.3632
@@ -1,5 +1,20 @@
2007-07-01 Sandro Santilli <address@hidden>
+ * libbase/GC.h: don't be verbose about GC by default.
+ * server/movie_root.{cpp,h}: (add_interval_timer): take the Timer by
+ auto_ptr, add an optional second argument marking the timer as
+ internal (for use by xmlsocket/LoadVars and whichever other gnash
+ internal class in need for a timer). Internal timers will get a
+ negative identifier so to not introduce unexpected gaps in the
+ user-defined interval timers sequences. Fix bugs introduced in last
+ commit related to timer expiration and iterators invalidation.
+ * server/timers.{cpp,h}: add some inspector functions, use VM::getTime
+ for timers (milliseconds).
+ * server/asobj/: LoadVars.cpp, xmlsocket.cpp: update calls to
+ movie_root::add_interval_timer to mark these timers as internal.
+
+2007-07-01 Sandro Santilli <address@hidden>
+
* testsuite/simple.exp: increment timeout from 4 to 5 minutes.
* server/movie_root.{cpp,h}: store Timers into a map rather then
a vector, to allow for removal w/out loosing the timer identifier.
Index: libbase/GC.h
===================================================================
RCS file: /sources/gnash/gnash/libbase/GC.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- libbase/GC.h 1 Jul 2007 10:54:06 -0000 1.11
+++ libbase/GC.h 2 Jul 2007 03:20:33 -0000 1.12
@@ -32,7 +32,7 @@
// Define the following macro to enable GC verbosity
// Define to > 1 to have info printed about scan of already reachable objects
-#define GNASH_GC_DEBUG 1
+//#define GNASH_GC_DEBUG 1
#ifdef GNASH_GC_DEBUG
# include "log.h"
Index: server/movie_root.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/movie_root.cpp,v
retrieving revision 1.71
retrieving revision 1.72
diff -u -b -r1.71 -r1.72
--- server/movie_root.cpp 2 Jul 2007 00:18:25 -0000 1.71
+++ server/movie_root.cpp 2 Jul 2007 03:20:34 -0000 1.72
@@ -86,6 +86,13 @@
{
delete *it;
}
+
+ for (TimerMap::iterator it=_intervalTimers.begin(),
+ itE=_intervalTimers.end();
+ it != itE; ++it)
+ {
+ delete it->second;
+ }
assert(testInvariant());
}
@@ -508,29 +515,15 @@
assert(testInvariant());
}
-#if 0 // see comments in movie_root.h
-void
-movie_root::get_url(const char *url)
-{
- GNASH_REPORT_FUNCTION;
-
- // nobody should use this function
- assert(0);
-
- string command = "mozilla -remote \"openurl";
- command += url;
- command += ")\"";
- log_msg (_("Launching URL... %s"), command.c_str());
- system(command.c_str());
-}
-#endif
-
unsigned int
-movie_root::add_interval_timer(const Timer& timer)
+movie_root::add_interval_timer(std::auto_ptr<Timer> timer, bool internal)
{
+ assert(timer.get());
assert(testInvariant());
- unsigned int id = ++_lastTimerId;
+ int id = ++_lastTimerId;
+ if ( internal ) id = -id;
+
if ( _intervalTimers.size() >= 255 )
{
// TODO: Why this limitation ?
@@ -538,26 +531,27 @@
}
assert(_intervalTimers.find(id) == _intervalTimers.end());
- _intervalTimers[id] = timer;
+ _intervalTimers[id] = timer.release();
return id;
}
bool
movie_root::clear_interval_timer(unsigned int x)
{
- return _intervalTimers.erase(x);
-#if 0
- if ( ! x || x > _intervalTimers.size() ) return false;
+ TimerMap::iterator it = _intervalTimers.find(x);
+ if ( it == _intervalTimers.end() ) return false;
- Timer& timer = _intervalTimers[x-1];
-
- // will make sure next expire() will always return false!
- timer.clearInterval();
-
- assert(testInvariant());
+ // We do not remove the element here because
+ // we might have been called during execution
+ // of another timer, thus during a scan of the _intervalTimers
+ // container. If we use erase() here, the iterators in executeTimers
+ // would be invalidated. Rather, executeTimers() would check container
+ // elements for being still active and remove the cleared one in a safe
way
+ // at each iteration.
+ it->second->clearInterval();
return true;
-#endif
+
}
void
@@ -565,23 +559,8 @@
{
// GNASH_REPORT_FUNCTION;
- // Copy to avoid timers invalidation.
- // TODO: we might want to use pointers as elements rather then values,
- // so to allow disabling of a timer (ie: should we still execute
expired
- // timers if a previous timer execution cleared it ?)
- // TODO: wrap this in a executeTimers() method
- TimerMap timers = _intervalTimers;
- for (TimerMap::iterator it=timers.begin(), itEnd=timers.end();
- it != itEnd; ++it)
- {
- Timer& timer = it->second;
- if ( timer.expired() )
- {
- // log_msg("FIXME: Interval Timer Expired!\n");
- //_movie->on_event_interval_timer();
- timer();
- }
- }
+ // Execute expired timers
+ executeTimers();
#ifndef NEW_KEY_LISTENER_LIST_DESIGN
// Cleanup key listeners (remove unloaded characters)
@@ -1025,6 +1004,49 @@
_actionQueue.push_back(new FunctionCode(func, target));
}
+/* private */
+void
+movie_root::executeTimers()
+{
+ for (TimerMap::iterator it=_intervalTimers.begin(),
itEnd=_intervalTimers.end();
+ it != itEnd; )
+ {
+ // Get an iterator to next element, as we'll use
+ // erase to drop cleared timers, and that would
+ // invalidate the current iterator.
+ //
+ // FYI: it's been reported on ##iso-c++ that next
+ // C++ version will fix std::map<>::erase(iterator)
+ // to return the next valid iterator,
+ // like std::list<>::erase(iterator) does.
+ // For now, we'll have to handle this manually)
+ //
+ TimerMap::iterator nextIterator = it;
+ ++nextIterator;
+
+ Timer* timer = it->second;
+
+ if ( timer->cleared() )
+ {
+ // this timer was cleared, erase it
+ delete timer;
+ _intervalTimers.erase(it);
+ }
+ else
+ {
+ if ( timer->expired() )
+ {
+ //cout << " EXPIRED, start time is now " <<
timer.getStart() << endl;
+ //_movie->on_event_interval_timer();
+ (*timer)();
+ }
+ }
+
+ it = nextIterator;
+ }
+
+}
+
#ifdef GNASH_USE_GC
void
movie_root::markReachableResources() const
@@ -1040,7 +1062,7 @@
for (TimerMap::const_iterator i=_intervalTimers.begin(),
e=_intervalTimers.end();
i != e; ++i)
{
- i->second.markReachableResources();
+ i->second->markReachableResources();
}
// Mark resources reachable by queued action code
Index: server/movie_root.h
===================================================================
RCS file: /sources/gnash/gnash/server/movie_root.h,v
retrieving revision 1.62
retrieving revision 1.63
diff -u -b -r1.62 -r1.63
--- server/movie_root.h 2 Jul 2007 00:18:25 -0000 1.62
+++ server/movie_root.h 2 Jul 2007 03:20:34 -0000 1.63
@@ -15,7 +15,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-/* $Id: movie_root.h,v 1.62 2007/07/02 00:18:25 strk Exp $ */
+/* $Id: movie_root.h,v 1.63 2007/07/02 03:20:34 strk Exp $ */
/// \page events_handling Handling of user events
///
@@ -287,13 +287,16 @@
/// Add an interval timer
//
/// @param timer
- /// A Timer, will be copied.
+ /// A Timer, ownership will be transferred. Must not be NULL.
+ ///
+ /// @param internal
+ /// If true, this is an internal timer, so will get a negative id.
///
/// @return An integer indentifying the timer
/// for subsequent call to clear_interval_timer.
/// It will NEVER be zero.
///
- unsigned int add_interval_timer(const Timer& timer);
+ unsigned int add_interval_timer(std::auto_ptr<Timer> timer, bool
internal=false);
/// Remove timer identified by given integer
//
@@ -477,6 +480,9 @@
/// Forbid assignment
movie_root& operator=(const movie_root& ) { assert(0); return *this; }
+ /// Execute expired timers
+ void executeTimers();
+
/// Notify the global Key ActionScript object about a key status change
key_as_object * notify_global_key(key::code k, bool down);
@@ -521,7 +527,7 @@
bool m_on_event_xmlsocket_onxml_called;
bool m_on_event_load_progress_called;
- typedef std::map<int, Timer> TimerMap;
+ typedef std::map<int, Timer*> TimerMap;
TimerMap _intervalTimers;
unsigned int _lastTimerId;
Index: server/timers.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/timers.cpp,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -b -r1.35 -r1.36
--- server/timers.cpp 1 Jul 2007 10:54:25 -0000 1.35
+++ server/timers.cpp 2 Jul 2007 03:20:34 -0000 1.36
@@ -19,7 +19,7 @@
//
//
-/* $Id: timers.cpp,v 1.35 2007/07/01 10:54:25 bjacques Exp $ */
+/* $Id: timers.cpp,v 1.36 2007/07/02 03:20:34 strk Exp $ */
#include "timers.h"
#include "as_function.h" // for class as_function
@@ -49,22 +49,22 @@
void
- Timer::setInterval(as_function& method, unsigned ms,
boost::intrusive_ptr<as_object> this_ptr)
+ Timer::setInterval(as_function& method, uint64_t ms,
boost::intrusive_ptr<as_object> this_ptr)
{
_function = &method;
- _interval = ms * 1000; // transform to microseconds
- //log_msg("_interval microseconds: %lu", _interval);
+ _interval = ms; // keep milliseconds
+ //log_msg("_interval milliseconds: %lu", _interval);
_object = this_ptr;
start();
}
void
- Timer::setInterval(as_function& method, unsigned ms,
boost::intrusive_ptr<as_object> this_ptr,
+ Timer::setInterval(as_function& method, uint64_t ms,
boost::intrusive_ptr<as_object> this_ptr,
std::vector<as_value>& args)
{
_function = &method;
- _interval = ms * 1000; // transform to microseconds
- //log_msg("_interval microseconds: %lu", _interval);
+ _interval = ms; // keep as milliseconds
+ //log_msg("_interval milliseconds: %llu", _interval);
_object = this_ptr;
_args = args;
start();
@@ -80,7 +80,7 @@
void
Timer::start()
{
- _start = tu_timer::get_profile_ticks();
+ _start = VM::get().getTime();
//log_msg("_start at seconds %lu", _start);
}
@@ -90,21 +90,23 @@
{
if (_start)
{
- uint64_t now = tu_timer::get_profile_ticks();
+ uint64_t now = VM::get().getTime();
assert(now >= _start); // it is possible for now to be ==
_start
- //printf("FIXME: %s: now is %f, start time is %f, interval is
%f\n", __FUNCTION__, now, _start, _interval);
+ //cout << "Start is " << _start << " interval is " << _interval
<< " now is " << now << endl;
if (now > _start + _interval)
{
_start = now; // reset the timer
+ //cout << " Expired, reset start to " << _start << endl;
//log_msg("Timer expired! \n");
return true;
}
}
else
{
- //log_msg("Timer not enabled!");
+ log_msg("Timer not enabled!");
}
+
return false;
}
@@ -227,7 +229,7 @@
}
// Get interval time
- int ms = int(fn.arg(timer_arg).to_number());
+ uint64_t ms = uint64_t(fn.arg(timer_arg).to_number());
// Parse arguments
Timer::ArgsContainer args;
@@ -236,8 +238,8 @@
args.push_back(fn.arg(i));
}
- Timer timer;
- timer.setInterval(*as_func, ms, fn.this_ptr, args);
+ std::auto_ptr<Timer> timer(new Timer);
+ timer->setInterval(*as_func, ms, fn.this_ptr, args);
movie_root& root = VM::get().getRoot();
int id = root.add_interval_timer(timer);
Index: server/timers.h
===================================================================
RCS file: /sources/gnash/gnash/server/timers.h,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -b -r1.24 -r1.25
--- server/timers.h 1 Jul 2007 10:54:25 -0000 1.24
+++ server/timers.h 2 Jul 2007 03:20:34 -0000 1.25
@@ -85,7 +85,7 @@
/// It is allowed to be NULL as long as fn_call is allowed
/// a NULL as 'this_ptr' (we might want to change this).
///
- void setInterval(as_function& method, unsigned ms,
boost::intrusive_ptr<as_object> this_ptr);
+ void setInterval(as_function& method, uint64_t ms,
boost::intrusive_ptr<as_object> this_ptr);
/// Setup the Timer, enabling it.
//
@@ -105,7 +105,7 @@
/// @param args
/// The list of arguments to pass to the function being invoked.
///
- void setInterval(as_function& method, unsigned ms,
boost::intrusive_ptr<as_object> this_ptr,
+ void setInterval(as_function& method, uint64_t ms,
boost::intrusive_ptr<as_object> this_ptr,
std::vector<as_value>& args);
/// Clear the timer, ready for reuse
@@ -123,12 +123,24 @@
//
bool expired();
+ /// Return true if interval has been cleared.
+ //
+ /// Note that the timer is constructed as cleared and you
+ /// need to call setInterval() to make it not-cleared.
+ bool cleared() const { return ! _start; }
+
/// Execute associated function properly setting up context
void operator() ();
/// Arguments list type
typedef std::vector<as_value> ArgsContainer;
+ /// Return number of microseconds between expirations
+ uint64_t getInterval() const { return _interval; }
+
+ /// Return number of milliseconds after VM start this timer was last
reset
+ uint64_t getStart() const { return _start; }
+
#ifdef GNASH_USE_GC
/// Mark all reachable resources (for GC)
//
@@ -149,10 +161,10 @@
///
void start();
- /// Number of microseconds between expirations
+ /// Number of milliseconds between expirations
uint64_t _interval;
- /// Number of microseconds since epoch at Timer start
+ /// Number of microseconds since epoch at Timer start (?)
uint64_t _start;
/// The associated function, stored in an intrusive pointer
Index: server/asobj/LoadVars.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/LoadVars.cpp,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -b -r1.26 -r1.27
--- server/asobj/LoadVars.cpp 1 Jul 2007 10:54:28 -0000 1.26
+++ server/asobj/LoadVars.cpp 2 Jul 2007 03:20:34 -0000 1.27
@@ -404,8 +404,9 @@
using boost::intrusive_ptr;
intrusive_ptr<builtin_function> loadsChecker = new
builtin_function(
&LoadVars::checkLoads_wrapper, NULL);
- Timer timer; timer.setInterval(*loadsChecker, 50, this);
- _loadCheckerTimer =
VM::get().getRoot().add_interval_timer(timer);
+ std::auto_ptr<Timer> timer(new Timer);
+ timer->setInterval(*loadsChecker, 50, this);
+ _loadCheckerTimer =
VM::get().getRoot().add_interval_timer(timer, true);
}
URL url(urlstr, get_base_url());
Index: server/asobj/xmlsocket.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/xmlsocket.cpp,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -b -r1.30 -r1.31
--- server/asobj/xmlsocket.cpp 1 Jul 2007 10:54:32 -0000 1.30
+++ server/asobj/xmlsocket.cpp 2 Jul 2007 03:20:34 -0000 1.31
@@ -463,11 +463,11 @@
{
log_msg(_("Setting up timer for calling XMLSocket.onData()"));
- Timer timer;
+ std::auto_ptr<Timer> timer(new Timer);
boost::intrusive_ptr<builtin_function> ondata_handler = new
builtin_function(&xmlsocket_inputChecker, NULL);
unsigned interval = 50; // just make sure it's expired at every frame
iteration (20 FPS used here)
- timer.setInterval(*ondata_handler, interval,
boost::dynamic_pointer_cast<as_object>(ptr));
- VM::get().getRoot().add_interval_timer(timer);
+ timer->setInterval(*ondata_handler, interval,
boost::dynamic_pointer_cast<as_object>(ptr));
+ VM::get().getRoot().add_interval_timer(timer, true);
log_msg(_("Timer set"));
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] gnash ChangeLog libbase/GC.h server/movie_root....,
Sandro Santilli <=