001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package com.sun.midp.i3test;
028:
029: import com.sun.cldc.util.Semaphore;
030:
031: /**
032: * A simple cross-isolate synchronization mechanism.
033: * Handles the simple case of synchronizing between two
034: * isolates, performing "master" and "slave" roles.
035: * This is useful for cross-isolate unit testing.
036: * This is a utility class, containing only static methods.
037: * No instances of this class are ever created.
038: *
039: * <p>This class must be initialized once (presumably the by master),
040: * by calling init(), before starting the slave isolate. The master isolate
041: * can call awaitReady() to wait for the slave isolate to become ready.
042: * The slave isolate performs whatever initialization and testing it wants and
043: * then calls pause(). This blocks the slave and
044: * unblocks the master's call to awaitReady(), giving the master the
045: * opportunity to inspect the slave's state. The master can then call
046: * signalContinue() to unblock the slave. Finally, the fini() call will
047: * destroy the shared objects created by init().
048: *
049: * <p>Example code for master isolate:
050: * <pre>
051: * void testAnotherIsolate() {
052: * IsolateSynch.init();
053: * Isolate iso = new Isolate(start_class, args);
054: * iso.start();
055: * IsolateSynch.awaitReady();
056: * // assertions can be made safely here about the state of the slave
057: * IsolateSynch.signalContinue();
058: * IsolateSynch.fini();
059: * }
060: * </pre>
061: * <p>Example code for slave isolate:
062: * <pre>
063: * public static void main(Strings args[]) {
064: * // perform initialization and execute code under test
065: * IsolateSynch.pause();
066: * // perform any cleanup here
067: * }
068: * </pre>
069: */
070: public class IsolateSynch {
071:
072: static Semaphore semReady;
073: static Semaphore semContinue;
074:
075: static native Semaphore getSemReady0();
076:
077: static native Semaphore getSemContinue0();
078:
079: private static native void init0(Semaphore semReady,
080: Semaphore semCont);
081:
082: private static native void fini0();
083:
084: private IsolateSynch() {
085: // disallow creation of instances
086: }
087:
088: /**
089: * Initialize shared objects.
090: * @throws IllegalStateException if already initialized.
091: */
092: public static void init() {
093: semReady = new Semaphore(0);
094: semContinue = new Semaphore(0);
095: init0(semReady, semContinue);
096: }
097:
098: /**
099: * Blocks until the slave pauses, indicating that it's ready. Intended to
100: * be called by the master isolate.
101: */
102: public static void awaitReady() {
103: getSemReady0().acquire();
104: }
105:
106: /**
107: * Informs the slave that it can continue after having paused. Intended
108: * to be called by the master isolate.
109: */
110: public static void signalContinue() {
111: getSemContinue0().release();
112: }
113:
114: /**
115: * Blocks the caller and unblocks the master. Intended to be called by
116: * the slave.
117: */
118: public static void pause() {
119: getSemReady0().release();
120: getSemContinue0().acquire();
121: }
122:
123: /**
124: * Cleans up shared objects. Does nothing if there is
125: * nothing to clean up.
126: */
127: public static void fini() {
128: semReady = null;
129: semContinue = null;
130: fini0();
131: }
132:
133: }
|