⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 channel.java

📁 著名的dialogic电话语音卡的java驱动程序,已经验证可用。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
// local.dialogic.Channel abstract class
// $Id: Channel.java,v 1.9 2003/11/13 11:45:04 cgm8 Exp $
/* 
 * Copyright (c) 1999 Carlos G Mendioroz.
 *
 *  This file is part of D4J.
 *
 *  D4J is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *  
 *  D4J 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
 *  Lesser General Public License for more details.
 *  
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the
 *  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 *  Boston, MA  02111-1307, USA.
 *
 * Report problems and direct all questions to:
 *
 *	tron@acm.org
 */
package local.dialogic;
import java.util.*;

public abstract class Channel extends Observable {
    // Class variables
    static private java.util.Vector channelAtDev;   // Class instances
    static private java.util.Vector resourceAtDev;  // registered resources
    static private PollThread pollThread;
    static private Object eventLock = new Object(); // thing to lock on.
    static private LinkedList holdEvents = new LinkedList();; // in the mean time...
    static private boolean hold = false;            // executing atomic

    static protected boolean GC = false;    // use Global Call event fn
    static {
        channelAtDev = new java.util.Vector(5,4);
        resourceAtDev = new java.util.Vector(5,4);
        pollThread = new PollThread();
        pollThread.setDaemon(true);
        pollThread.setName("Dialogic polling thread");
        pollThread.start();
    }

    /**
     * Used to carry out an action which will _never_ have an event fire during it.
     * stops the event queue - so r should be quick and deterministic.
     * In future it could be run on the event thread - a'la invokeLater() in swing
     */
    public static void atomicAction(Runnable r){
        synchronized(eventLock) {
            hold = true;
        }
        r.run();
        synchronized(eventLock) {
            EVT evt;
            hold = false;
            while(holdEvents.size() > 0) {
                evt = (EVT)holdEvents.removeFirst();
                handleEvent(evt);
            }
        }
    }

    /*
     * waitevtex is no good because there is no efficient
     * way of knowing of new devices I care about.
     * We need a dynamic way of asking for events, i.e. PollThread at Channel
     *
     * This is done via signal handling in Linux. To have the same class,
     * we just throw an exception if we call waitevt() in Linux, and let 
     * the poller silently die...
     */

    private static class PollThread extends Thread {
        // Run: poll events and hold last
        public void run()
        {
            EVT evt;
            if ((Dialogic.debug & Dialogic.DEBUG_EVSRC) != 0) {
              System.out.println("Channel Poll thread started");
            }
	    try {
		while (true) {
		    evt = new EVT();
		    Dialogic.sr_waitevt(evt);
		    if (evt.dev == 0) {
			if ((Dialogic.debug & Dialogic.DEBUG_EVSRC) != 0) {
			    System.out.println("Channel Poll thread stopped");
			}
			return;
		    }
		    handleEvent(evt);
		}
	    } catch (RuntimeException re) {
		if ((Dialogic.debug & Dialogic.DEBUG_EVSRC) != 0) {
		    System.out.println("Channel Poll thread stopped");
		}
	    }
	}
    }

    protected static void handleEvent(EVT evt) {
	// Guard from dispatching events generated by
        // atomicAction until completion
        Channel ch = null;
        ResourceServer res = null;

        // Support for atomicAction: action not interrupted by events.
        // It's only important, AFAIK, at open time when we want events to be dispatched
        // only after device had an oportunity to register.
        // Old implementation used to just hold, but this is a bad idea in the linux
        // implementation that is monothreaded as far as events go, and blocks all driver
        // comunication, i.e., big possibility for deadlock.
        if (hold) {
            synchronized(eventLock){
                // still holding...
                if(hold) {
                    holdEvents.add(evt);
                    return;
                }
            }
        }
        
        if (GC)
            GCChannel.gc_getMeta(evt); // No Dialogic indirection here...
        try {
            res = (ResourceServer)resourceAtDev.elementAt(evt.dev);
        } catch (ArrayIndexOutOfBoundsException x ) {
            if((Dialogic.debug & Dialogic.DEBUG_EVSRC) != 0){
                System.err.println("Got event before handler registered: "+evt);
            }
        }
        if (res != null) {
            if ((Dialogic.debug & Dialogic.DEBUG_EVSRC) != 0)
                System.out.println(new java.util.Date().toString().substring(11,20) +
                            res + ": " + evt);
            res.service(evt);
        } else {
            dispatch(evt);
        }
    }

    public static void dispatch(EVT evt) {
        Channel ch = null;
        try {
          ch = (Channel)channelAtDev.elementAt(evt.dev);
        } catch (ArrayIndexOutOfBoundsException x ) {
          if((Dialogic.debug & Dialogic.DEBUG_EVSRC) != 0){
            System.err.println("Got event before handler registered: "+evt);
          }
        }
        if (ch != null) {
            if ((Dialogic.debug & Dialogic.DEBUG_EVSRC) != 0)
                System.out.println(new java.util.Date().toString().substring(11,20) +
                            Device.atDev(evt.dev) + ": " + evt);
            ch.newEvent(evt);
        } else {
            if ((Dialogic.debug & Dialogic.DEBUG_EVSRC) != 0){
                System.out.println("unclaimed event: " + evt
                    +"("+ evt.dev + "/" + evt.line + ")");
            }
        }
    }

    // Utility fn to interrupt (and join) all channel group threads
    // waiting for ThreadGroup.interrupt()/join() to be implemented.
    // We leave serviceThread alone...and myself! 
    /* 5/3/02 it seems that sometimes we kill the thread that is clearing
     * the channel and then let the channel in an unusable state :-( */
	public static void stopGroup(Channel ch) {
		if ((Dialogic.debug & Dialogic.DEBUG_CHANNEL) != 0 && ch.group != null)
			System.out.println("StopGroup("+ ch.toString()+ ")");
        if (ch.group == null)
            return;
         int n = ch.group.activeCount();
         if (n == 0)
            return;
         Thread list[] = new Thread[n];
         int count = ch.group.enumerate(list);
         Thread me = Thread.currentThread();
         
         // Interrupt all of them, then join !
         for (int i = 0; i < count; i++) {
            if (list[i] != ch.serviceThread && list[i] != me)
                list[i].interrupt();
         }
         for (int i = 0; i < count; i++) {
            if (list[i] != ch.serviceThread && list[i] != me) {
                try {
                    list[i].join();
                }
                catch(InterruptedException ie) {
					if ((Dialogic.debug & Dialogic.DEBUG_CHANNEL) != 0 && ch.group != null)
						System.out.println("StopGroup("+ ch.toString()+ ") interrupted");
                    Thread.currentThread().interrupt();
                }
            }
        }
        if (me != ch.serviceThread)
			ch.serviceThread.interrupt(); // He has to know!
		if ((Dialogic.debug & Dialogic.DEBUG_CHANNEL) != 0 && ch.group != null)
			System.out.println("StopGroup("+ ch.toString()+ ") exit");
    }

    /**
     * setGroup: recreate the service thread association 
     *  making a new group for this channel...
     */
    public void setGroup() {
        serviceThread = Thread.currentThread();
        group = serviceThread.getThreadGroup();
    }

    // Variables
    CallHandler handler = null;
    // resource used to be a Resource but now we support a set of them...
    java.util.Vector resource;
    // events is logically a queue. It used to be a com.objectspace.Queue
    // but now we use JDK2's LinkedList in favour of easier deployment.
    private LinkedList events;
    private boolean serviceActive = false;
    protected EVT lastEvent = null;
    protected Call call = null;

    /**
     * Visible state of channel (via getState() and observer interface).
     * The actual Channel implementation is responsible
     * for updating it using setState({OOS|FREE|INCOMING|OUTGOING}).
     */
    protected Integer state = OOS;
    ThreadGroup group = null;
    Thread serviceThread = null;

    //
    public Channel() {
        events = new LinkedList();
        resource = new java.util.Vector(2,1);
    }

    protected void register(Device dev) {
        if (channelAtDev.size() <= dev.device) {
            channelAtDev.setSize(dev.device + 1);
            resourceAtDev.setSize(dev.device + 1);
        }
        channelAtDev.setElementAt(this, dev.device);
        dev.channel = this;
        if ((Dialogic.debug & Dialogic.DEBUG_EVDST) != 0)
            System.out.println("Registered: " + dev);
    }

    protected void unregister(Device dev) {
        channelAtDev.setElementAt(null, dev.device);
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -