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.content;
028:
029: import javax.microedition.content.ResponseListener;
030:
031: /**
032: * Thread to monitor pending invocations and notify a listener
033: * when a matching one is present.
034: */
035: class ResponseListenerImpl implements Runnable {
036:
037: /** ContenHandlerServer for which this is listening. */
038: private final RegistryImpl registry;
039:
040: /** The listener to notify. */
041: private ResponseListener listener;
042:
043: /** The active thread processing the run method. */
044: private Thread thread;
045:
046: /**
047: * Create a new listener for pending invocations.
048: *
049: * @param registry the RegistryImpl to listen for
050: * @param listener the listener to notify when present
051: */
052: ResponseListenerImpl(RegistryImpl registry,
053: ResponseListener listener) {
054: this .registry = registry;
055: setListener(listener);
056: }
057:
058: /**
059: * Set the listener to be notified and start/stop the monitoring
060: * thread as necesary.
061: * If the listener is non-null make sure there is a thread active
062: * to monitor it.
063: * If there is no listener, then stop the monitor thread.
064: * Unblock any blocked threads so they can get the updated listener.
065: * @param listener the listener to update
066: */
067: void setListener(ResponseListener listener) {
068: this .listener = listener;
069:
070: if (listener != null) {
071: // Ensure a thread is running to watch for it
072: if (thread == null || !thread.isAlive()) {
073: thread = new Thread(this );
074: thread.start();
075: }
076: } else {
077: // Forget the thread doing the listening; it will exit
078: thread = null;
079: }
080:
081: /*
082: * Reset notified flags on pending responses.
083: * Unblock any threads waiting to notify current listeners
084: */
085: InvocationStore.setListenNotify(registry.application
086: .getStorageId(), registry.application.getClassname(),
087: false);
088: InvocationStore.cancel();
089: }
090:
091: /**
092: * The run method checks for pending invocations for a
093: * desired Registry.
094: * When an invocation is available the listener is
095: * notified.
096: */
097: public void run() {
098: Thread mythread = Thread.currentThread();
099: while (mythread == thread) {
100: // Remember the listener to notify to avoid a race condition
101: ResponseListener l = listener;
102: if (l != null) {
103: // Wait for a matching invocation
104: boolean pending = InvocationStore.listen(
105: registry.application.getStorageId(),
106: registry.application.getClassname(), false,
107: true);
108: if (pending) {
109: l.invocationResponseNotify(registry.getRegistry());
110: }
111: }
112: }
113: }
114: }
|