From 989a9867e0e5a6aadbfd13b0ba323ce949c8ab1c Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Fri, 24 May 2002 21:03:15 +0000 Subject: [PATCH] Created a convenience class for executing code on the dobjmgr thread via the standard Java timer services. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@1391 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../presents/server/util/SafeInterval.java | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 src/java/com/threerings/presents/server/util/SafeInterval.java diff --git a/src/java/com/threerings/presents/server/util/SafeInterval.java b/src/java/com/threerings/presents/server/util/SafeInterval.java new file mode 100644 index 000000000..e6a52a74a --- /dev/null +++ b/src/java/com/threerings/presents/server/util/SafeInterval.java @@ -0,0 +1,84 @@ +// +// $Id: SafeInterval.java,v 1.1 2002/05/24 21:03:15 mdb Exp $ + +package com.threerings.presents.server.util; + +import java.util.Timer; +import java.util.TimerTask; + +import com.threerings.presents.server.PresentsDObjectMgr; + +/** + * Used in conjunction with the {@link PresentsDObjectMgr}, this class + * provides a means by which code can be run on the dobjmgr thread at some + * point in the future, either as a recurring interval or as a one shot + * deal. The code is built on top of the standard Java {@link Timer} + * services. + * + *

A {@link SafeInterval} instance should be created and then + * scheduled to run using the standard {@link Timer} services. For + * example: + * + *

+ *     Timer.schedule(new SafeInterval(_omgr) {
+ *         public void intervalExpired () {
+ *             System.out.println("Foo!");
+ *         }
+ *      }, 25L * 1000L);
+ * 
+ */ +public abstract class SafeInterval extends TimerTask +{ + /** + * Creates a safe interval instance that will queue itself up for + * execution on the supplied dobjmgr when it expires. + */ + public SafeInterval (PresentsDObjectMgr omgr) + { + _omgr = omgr; + } + + /** + * Called (on the dobjmgr thread) when the interval period has + * expired. If this is a recurring interval, this method will be + * called each time the interval expires (until {@link #cancel} is + * called on this instance). + */ + public abstract void intervalExpired (); + + /** Handles the proper scheduling and queueing. */ + public void run () + { + boolean flipped = isFlipped(); + flip(); + if (flipped) { + intervalExpired(); + } else { + _omgr.postUnit(this); + } + } + + /** Returns whether or not we're running on the timer thread or the + * dobjmgr thread. It is synchronized because the variable that tracks + * this state is inspected on both threads. */ + protected synchronized boolean isFlipped () + { + return _flipped; + } + + /** Flips our mode (see {@link #isFlipped}). It is synchronized + * because the variable that tracks this state is updated on both + * threads. */ + public synchronized void flip () + { + _flipped = !_flipped; + } + + /** The dobjmgr on which we queue ourselves when we expire. */ + protected PresentsDObjectMgr _omgr; + + /** Because {@link #run} is called both when the interval expires and + * when the dobjmgr invokes us, we have to use this toggle to figure + * out when to do what. */ + protected boolean _flipped; +}