/* * @(#)XletStateQueue.java 1.9 06/10/10 * * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. * */ package com.sun.xlet; /* * Implements a queue that keeps track of incoming xlet state change requests * and executes them in order. There is one queue per one xlet. * By having this class, the caller requesting the xlet state change * does not have to be blocked waiting for a lock even if another xlet state change * request is being processed. */ public class XletStateQueue { EventQueueItem head = null; EventQueueItem tail = null; XletManager manager; // The thread that's processing the requests. It should be in the // ThreadGroup created by the XletManager. Thread queueThread; // To check if the xlet is still alive (not destroyed). boolean isAlive = true; public XletStateQueue(XletManager xletManager) { this.manager = xletManager; queueThread = new Thread(manager.threadGroup, new Runnable() { public void run() { while (isAlive && manager.getXletState() != XletState.DESTROYED) { dispatchRequests(); } } }, "XletStateQueue lookup thread"); queueThread.setContextClassLoader(xletManager.getClassLoader()); queueThread.start(); } // Push the request to the queue. public synchronized void push(XletState desired) { if (head == null) { // empty queue head = new EventQueueItem(desired); tail = head; } else { tail.next = new EventQueueItem(desired); tail = tail.next; } notifyAll(); } // Pop the request from the queue. public synchronized XletState pop() { XletState returningState = null; if (head != null) { returningState = head.state; head = head.next; } return returningState; } // True if there is no request pending in the queue. public synchronized boolean isEmpty() { return (head == null); } // Clear up all the requests in this queue. public synchronized void clear() { head = tail = null; } // Destroy the queue. Called when the xlet is destroyed. public synchronized void destroy() { clear(); isAlive = false; notifyAll(); } // Process the xlet state change request pending in this queue. public synchronized void dispatchRequests() { while (isEmpty() && isAlive) { try { wait(); } catch (InterruptedException e) {} } if (!isAlive) return; manager.handleRequest(pop()); } } // Basic state change request date object kept in the queue. class EventQueueItem { XletState state; EventQueueItem next; EventQueueItem(XletState state) { this.state = state; } } // Extended state change request date object kept in the queue. // This is to hide XletState objects that cannot be of a final state // (INITIALIZE and CONDITIONAL_DESTROY are valid state change requests // but not valid states for an xlet to be in.) class DesiredXletState extends XletState { static final XletState INITIALIZE; static final XletState CONDITIONAL_DESTROY; static { INITIALIZE = new XletState("initialize"); CONDITIONAL_DESTROY = new XletState("conditional_destroy"); } protected DesiredXletState(String name) { super(name); } } // XletState class object - to keep track of the current xlet state. class XletState { static final XletState UNLOADED; static final XletState LOADED; static final XletState PAUSED; static final XletState ACTIVE; static final XletState DESTROYED; private String name = null; protected XletState(String name) { this.name = name; } public String toString() { return name; } static { UNLOADED = new XletState("unloaded"); LOADED = new XletState("loaded"); PAUSED = new XletState("paused"); ACTIVE = new XletState("active"); DESTROYED = new XletState("destroyed"); } }