All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fr.esrf.TangoDs.DServer Maven / Gradle / Ivy

There is a newer version: 10.0.0
Show newest version
//+======================================================================
// $Source$
//
// Project:   Tango
//
// Description:  java source code for the TANGO client/server API.
//
// $Author: pascal_verdier $
//
// Copyright (C) :      2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,
//						European Synchrotron Radiation Facility
//                      BP 220, Grenoble 38043
//                      FRANCE
//
// This file is part of Tango.
//
// Tango 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 3 of the License, or
// (at your option) any later version.
// 
// Tango 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 Tango.  If not, see .
//
// $Revision: 25297 $
//
//-======================================================================


package fr.esrf.TangoDs;

import fr.esrf.Tango.DevFailed;
import fr.esrf.Tango.DevState;
import fr.esrf.Tango.DevVarLongStringArray;
import fr.esrf.TangoApi.DbDatum;
import fr.esrf.TangoApi.DeviceData;
import org.apache.log4j.Logger;
import org.omg.CORBA.BAD_OPERATION;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.POAManager;
import org.omg.PortableServer.POAPackage.ObjectNotActive;
import org.omg.PortableServer.POAPackage.WrongPolicy;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Vector;

/**
 * @deprecated use {@link org.tango.server.admin.AdminDevice}
 */
@Deprecated
@SuppressWarnings( { "NestedTryStatement", "ErrorNotRethrown" })
public class DServer extends DeviceImpl {
    protected String process_name;
    protected String instance_name;
    protected StringBuffer full_name;

    protected Vector class_list = new Vector();;

    // +----------------------------------------------------------------------------
    //
    // method : DServer()
    // 
    // description : constructor for DServer object
    //
    // in : - cp : The class object
    // - n : The device name
    // - d : The device description
    // - s : The device state
    // - st : The device status
    //
    // -----------------------------------------------------------------------------

    DServer(final DeviceClass cl, final String n, final String d, final DevState s, final String st)
            throws DevFailed {
        super(cl, n, d, s, st);

        process_name = Util.instance().get_ds_exec_name();
        instance_name = Util.instance().get_ds_inst_name();

        full_name = new StringBuffer(process_name);
        full_name.append('/');
        full_name.append(instance_name);
        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
            public void run() {
                // call delete_device
                final int nb_class = class_list.size();
                for (int j = 0; j < nb_class; j++) {
                    final Vector v = ((DeviceClass) class_list.elementAt(j)).get_device_list();
                    final int nb_dev = v.size();
                    for (int k = 0; k < nb_dev; k++) {
                        final DeviceImpl dev = (DeviceImpl) v.elementAt(k);
                        if (dev.get_exported_flag() == true) {
                            try {
                                Util.out4.println("delete device " + dev.get_name());
                                dev.delete_device();
                            } catch (final DevFailed e) {
                                e.printStackTrace();
                                // ignore error, kill the device anyway
                            }
                        }
                    }
                }
                Util.out4.println("unregister " + Util.instance().get_ds_name());
                Util.instance().unregister_server();
            }
        }));

        init_device();
    }

    @Override
    public void init_device() throws DevFailed {

        Util.out4.println("DServer.DSserver() create dserver " + device_name);

        //
        // Now, creates all user classes
        //

        boolean class_factory_done = false;
        int i = 0;
        try {
            //
            // Activate the POA manager
            //

            final Util tg = Util.instance();
            final POAManager manager = tg.get_poa().the_POAManager();
            try {
                manager.activate();
            } catch (final org.omg.PortableServer.POAManagerPackage.AdapterInactive ex) {
                Except.throw_exception("API_CantActivatePOAManager",
                        "The POA activate method throws an exception", "DServer.init_device()");
            }

            class_factory();
            class_factory_done = true;

            if (class_list.isEmpty() == false) {
                // Add the DServer object class
                // And Set the class list pointer in the Util class
                // class_list.add(this.get_device_class());
                tg.set_class_list(class_list);

                // A loop for each class
                final String ds_name = tg.get_ds_name();
                for (i = 0; i < class_list.size(); i++) {
                    // Build class commands
                    final DeviceClass cl_ref = (DeviceClass) class_list.elementAt(i);
                    cl_ref.command_factory();
                    // Sort command list
                    final MyComp comp = new MyComp();
                    Collections.sort(cl_ref.get_command_list(), comp);

                    // Build class attributes
                    cl_ref.attribute_factory(cl_ref.get_class_attr().get_attr_list());
                    cl_ref.get_class_attr().init_class_attribute(cl_ref.get_name(), 0);

                    // Set class name in command instances and analyse user
                    // methods (only for
                    // command created using the template method)
                    for (int k = 0; k < cl_ref.get_command_list().size(); k++) {
                        final Command cmd = (Command) cl_ref.get_command_list().elementAt(k);
                        if (cmd.is_template() == true) {
                            cmd.set_device_class_name(cl_ref.get_name());
                            cmd.analyse_methods();
                        }
                    }

                    // Retrieve device(s) name list from the database. No need
                    // to implement
                    // a retry here (in case of db server restart) because the
                    // db reconnection
                    // is forced by the get_property call executed during
                    // xxxClass construction
                    // before we reach this code.

                    String[] dev_list = null;
                    if (Util._UseDb) {
                        final String[] ds = new String[2];
                        ds[0] = ds_name;
                        ds[1] = ((DeviceClass) class_list.elementAt(i)).get_name();

                        final DeviceData send = new DeviceData();
                        send.insert(ds);
                        final DeviceData received = tg.get_database().command_inout(
                                "DbGetDeviceList", send);

                        try {
                            dev_list = received.extractStringArray();

                        } catch (final BAD_OPERATION ex) {
                            Util.out3
                                    .println("DServer.init_device() --> Wrong argument type for DbGetDeviceList command");
                            Except
                                    .throw_exception(
                                            "API_IncompatibleCmdArgumentType",
                                            "Imcompatible command argument type returned by the DbGetDeviceList command",
                                            "DServer.init_device()");
                        }

                        if (dev_list.length == 0) {
                            final StringBuffer o = new StringBuffer(
                                    "No device defined in database for class ");
                            o.append(((DeviceClass) class_list.elementAt(i)).get_name());

                            Except.throw_exception("API_DatabaseAccess", o.toString(),
                                    "DServer.init_device()");
                        }
                        Util.out4.println(dev_list.length + " device(s) defined");

                        // Create all device(s)
                        ((DeviceClass) class_list.elementAt(i)).device_factory(dev_list);
                    } else {
                        Vector list = ((DeviceClass) class_list.elementAt(i)).get_nodb_name_list();
                        String[] dev_list_nodb;
                        if (i != class_list.size() - 1) {
                            ((DeviceClass) class_list.elementAt(i)).device_name_factory(list);
                        } else {
                            if (tg.get_cmd_line_name_list().size() == 0) {
                                ((DeviceClass) class_list.elementAt(i)).device_name_factory(list);
                            } else {
                                list = tg.get_cmd_line_name_list();
                            }
                        }

                        if (list.isEmpty() == true) {
                            dev_list_nodb = new String[1];
                            dev_list_nodb[0] = "NoName";
                        } else {
                            dev_list_nodb = new String[list.size()];
                            for (int k = 0; k < list.size(); k++) {
                                dev_list_nodb[k] = (String) list.elementAt(k);
                            }
                        }

                        //
                        // Create all device(s)
                        //

                        ((DeviceClass) class_list.elementAt(i)).device_factory(dev_list_nodb);
                    }
                }
            }

        } catch (final OutOfMemoryError ex) {

            //
            // If the class_factory method have not been successfully executed,
            // erase
            // all classes already built. If the error occurs during the command
            // or device
            // factories, erase only the following classes
            //

            final StringBuffer o = new StringBuffer("Can't allocate memory in server while ");

            if (class_factory_done == false) {
                final int class_err = class_list.size() + 1;
                o.append("creating class number ");
                o.append(class_err);
                if (class_list.isEmpty() == false) {
                    class_list.removeAllElements();
                }
            } else {
                o.append("building command(s) or device(s) for class number ");
                o.append(i + 1);
                for (int j = i; j < class_list.size(); j++) {
                    class_list.removeElementAt(j);
                }
            }

            Except.throw_exception("API_MemoryAllocation", o.toString(), "DServer.init_device()");
        } catch (final DevFailed ex) {

            //
            // If the class_factory method have not been successfully executed,
            // erase
            // all classes already built. If the error occurs during the command
            // or device
            // factories, erase only the following classes
            //

            if (class_factory_done == false) {
                if (class_list.isEmpty() == false) {
                    class_list.removeAllElements();
                }
            } else {
                for (int j = i; j < class_list.size(); j++) {
                    class_list.removeElementAt(j);
                }
            }
            throw ex;
        }
    }

    // +----------------------------------------------------------------------------
    //
    // method : class_factory()
    // 
    // description : Build all the DeviceClass embedded in a server
    // There is a difference in this method between the C++
    // version and the java version. In java, with its
    // "introspection" capability (Class class), it is
    // possible to build a class from its name. Using this nice
    // feature, this method simply ask the database for a list
    // of class name embedded ina device server process and
    // creates all of them.
    // In C++, it is the user responsability to write this
    // method
    //
    // -----------------------------------------------------------------------------

    private void class_factory() throws DevFailed {

        //
        // First, retrieve all classes embedded in this server
        //

        final Util tg = Util.instance();
        String[] cl_list = null;
        try {
            if (Util._UseDb) {
                final StringBuffer str = new StringBuffer(tg.get_ds_exec_name());
                str.append('/');
                str.append(tg.get_ds_inst_name());

                final DeviceData send = new DeviceData();
                send.insert(str.toString());
                final DeviceData received = tg.get_database().command_inout(
                        "DbGetDeviceServerClassList", send);

                cl_list = received.extractStringArray();
            } else {
                final Vector v = tg.get_class_name_list();
                cl_list = new String[v.size()];
                for (int i = 0; i < v.size(); i++) {
                    cl_list[i] = (String) v.elementAt(i);
                }
            }
        } catch (final BAD_OPERATION ex) {
            Util.out3
                    .println("DServer.class_factory() --> Wrong argument type for DbGetDeviceServerClassList command");
            Except
                    .throw_exception(
                            "API_IncompatibleCmdArgumentType",
                            "Imcompatible command argument type returned by the DbGetDeviceServerClassList command",
                            "DServer.class_factory()");
        } catch (final DevFailed ex) {
            Util.out3.println("DServer.class_factory() --> db command failed");
            Except.throw_exception("API_CantRetrieveClassList",
                    "The db command DbGetDeviceServerClassList failed", "DServer.class_factory()");
        }

        Util.out4.println(cl_list.length - 1 + " class(es) defined in server");

        //
        // Create each classes by calling its init method and store the
        // constructed
        // object in the class_list vector
        //

        int i = 0;
        try {
            for (i = 0; i < cl_list.length; i++) {

                //
                // Forget the DServer class
                //

                if (cl_list[i].equals("DServer") == true) {
                    continue;
                }

                //
                // Build the array of object used to find the init method
                //

                final Class cl_param = Class.forName("java.lang.String");
                final Class cl_param_array[] = new Class[1];
                cl_param_array[0] = cl_param;

                //
                // If there is no "Class" at the end of the class name returned
                // by the db,
                // add it and create the Class object associated with the device
                // class
                //

                Class cl;
                final int pos = cl_list[i].indexOf("Class");
                if (pos == -1) {
                    final StringBuffer class_name = new StringBuffer(cl_list[i]);
                    final int containsDot = cl_list[i].indexOf(".");
                    if (containsDot == -1) {
                        class_name.insert(0, ".");
                        class_name.append("Class");
                        class_name.insert(0, cl_list[i]);
                    } else {
                        class_name.append("Class");
                    }

                    Util.out4.println("Searching for class : " + class_name);

                    cl = Class.forName(new String(class_name));
                } else {
                    cl = Class.forName(cl_list[i]);
                }

                //
                // Retrieve the init method (which should be static) and execute
                // it
                //

                final Method init_meth = cl.getMethod("init", cl_param_array);

                final java.lang.Object[] meth_param = new java.lang.Object[1];
                final int containsDot = cl_list[i].lastIndexOf(".");
                if (containsDot == -1) {
                    meth_param[0] = cl_list[i];
                } else {
                    meth_param[0] = cl_list[i].substring(containsDot + 1);
                }
                class_list.addElement(init_meth.invoke(null, meth_param));
            }
        } catch (final ClassNotFoundException ex) {
            final StringBuffer o = new StringBuffer("Can't retrieve class ");
            o.append(cl_list[i]);
            Util.out3.println("DServer.class_factory() --> Can't find class");
            Except.throw_exception("API_ClassNotFound", new String(o), "DServer.class_factory()");
        } catch (final NoSuchMethodException ex) {
            final StringBuffer o = new StringBuffer("Can't retrieve init method in class ");
            o.append(cl_list[i]);
            Util.out3.println("DServer.class_factory() --> Can't retrieve int method");
            Except.throw_exception("API_InitMethodNotFound", new String(o),
                    "DServer.class_factory()");
        } catch (final SecurityException ex) {
            final StringBuffer o = new StringBuffer("Security exception while creating class ");
            o.append(cl_list[i]);
            Util.out3
                    .println("DServer.class_factory() --> Security exception during class creation");
            Except.throw_exception("API_JavaRuntimeSecurityException", new String(o),
                    "DServer.class_factory()");
        } catch (final InvocationTargetException ex) {
            final StringBuffer o = new StringBuffer("The init method of class ");
            o.append(cl_list[i]);
            o.append(" throws an exception");
            Util.out3
                    .println("DServer.class_factory() --> Init method send on exception during class creation");
            final Throwable th = ex.getTargetException();
            if (th instanceof fr.esrf.TangoApi.ConnectionFailed) {
                throw (fr.esrf.TangoApi.ConnectionFailed) th;
            } else if (th instanceof DevFailed) {
                throw (DevFailed) th;
            }

            Except.throw_exception("API_InitThrowsException", new String(o),
                    "DServer.class_factory()");
        } catch (final IllegalAccessException ex) {
            final StringBuffer o = new StringBuffer("The init method of class ");
            o.append(cl_list[i]);
            o.append(" is not public");
            Util.out3
                    .println("DServer.class_factory() --> Init method not accessible during class creation");
            Except.throw_exception("API_InitNotPublic", new String(o), "DServer.class_factory()");
        }
    }

    // +----------------------------------------------------------------------------
    //
    // method : query_class()
    // 
    // description : command to read all the classes used in a device server
    // process
    //
    // out : The class name list in a strings sequence
    //
    // -----------------------------------------------------------------------------

    public String[] query_class() throws DevFailed {
        Util.out4.println("In QueryClass command");

        final int nb_class = class_list.size();
        String[] ret = null;

        try {
            ret = new String[nb_class];

            for (int i = 0; i < nb_class; i++) {
                ret[i] = ((DeviceClass) class_list.elementAt(i)).get_name();
            }
        } catch (final OutOfMemoryError ex) {
            Util.out3.println("Memory Allocation error in DServer.query_class  method");
            Except.throw_exception("API_MemoryAllocation", "Can't allocate memory in server",
                    "DServer.query_class");
        }
        return ret;
    }

    // +----------------------------------------------------------------------------
    //
    // method : query_device()
    // 
    // description : command to read all the devices implemented by a device
    // server process
    //
    // out : The device name list in a strings sequence
    //
    // -----------------------------------------------------------------------------

    public String[] query_device() throws DevFailed {
        Util.out4.println("In QueryDevice command");

        final int nb_class = class_list.size();
        final Vector tmp_name = new Vector();

        for (int i = 0; i < nb_class; i++) {
            final int nb_dev = ((DeviceClass) class_list.elementAt(i)).get_device_list().size();
            for (int j = 0; j < nb_dev; j++) {
                tmp_name.addElement(((DeviceImpl) ((DeviceClass) class_list.elementAt(i))
                        .get_device_list().elementAt(j)).get_name());
            }
        }

        String[] ret = null;
        try {
            ret = new String[tmp_name.size()];

            for (int i = 0; i < tmp_name.size(); i++) {
                ret[i] = (String) tmp_name.elementAt(i);
            }
        } catch (final BAD_OPERATION ex) {
            Util.out3.println("Memory Allocation error in DServer.query_device method");
            Except.throw_exception("API_MemoryAllocation", "Can't allocate memory in server",
                    "DServer.query_device");
        }
        return ret;
    }

    // +----------------------------------------------------------------------------
    //
    // method : DServer.restart()
    // 
    // description : command to restart a device
    //
    // out : The device name to be re-started
    //
    // -----------------------------------------------------------------------------

    public void restart(final String dev_name) throws DevFailed {
        Util.out4.println("In DServer.restart(" + dev_name + ") method");
        //
        // Check if the wanted device exists in each class
        //

        final Util tg = Util.instance();
        Vector dev_list = tg.get_device_list_by_class(((DeviceClass) class_list.elementAt(0))
                .get_name());
        final int nb_class = class_list.size();
        int i, j, nb_dev;
        DeviceImpl dev_to_del = null;
        DeviceClass dev_cl = null;

        j = 0;
        for (i = 0; i < nb_class; i++) {
            dev_list = tg.get_device_list_by_class(((DeviceClass) class_list.elementAt(i))
                    .get_name());
            nb_dev = dev_list.size();
            for (j = 0; j < nb_dev; j++) {
                if (((DeviceImpl) dev_list.elementAt(j)).get_name().equals(dev_name) == true) {
                    // Get device & class reference
                    dev_to_del = (DeviceImpl) dev_list.elementAt(j);
                    dev_cl = (DeviceClass) class_list.elementAt(i);
                    break;
                }
            }
            if (dev_to_del != null && dev_cl != null) {
                break;
            }
        }

        //
        // Throw exception if the device is not found
        //

        if (dev_to_del == null || dev_cl == null) // Have been found
        {
            final StringBuffer o = new StringBuffer("Device ");
            o.append(dev_name);
            o.append(" not found");

            Except.throw_exception("API_DeviceNotFound", new String(o), "Dserver.restart()");
        }

        //
        // Remove ourself from device list
        //

        dev_list.removeElementAt(j);

        // Store polling conditions if any
        assert dev_to_del != null;
        final Vector p_obj = dev_to_del.get_poll_obj_list(); // PollObj
        final Vector dev_pol = new Vector(); // Pol

        for (i = 0; i < p_obj.size(); i++) {
            dev_pol.add(p_obj.elementAt(i));
        }
        if (dev_pol.size() > 0) {
            stop_polling();
        }

        // Delete the device (deactivate it and remove it)
        final POA r_poa = tg.get_poa();
        if (dev_to_del.get_exported_flag() == true) {
            try {
                r_poa.deactivate_object(dev_to_del.get_obj_id());
            } catch (final WrongPolicy ex) {
            } catch (final ObjectNotActive ex) {
            }
        }

        // Re-create device
        final String[] dev_name_list = new String[1];
        dev_name_list[0] = dev_name;
        assert dev_cl != null;
        dev_cl.device_factory(dev_name_list);

        // Re-start device polling (if any)
        final DevVarLongStringArray send = new DevVarLongStringArray();
        send.lvalue = new int[1];
        send.svalue = new String[3];

        for (i = 0; i < dev_pol.size(); i++) {
            final PollObj poll_obj = (PollObj) dev_pol.elementAt(i);
            // Send command to the polling thread
            send.lvalue[0] = poll_obj.get_upd_i();
            send.svalue[0] = poll_obj.get_name();
            if (poll_obj.type == Tango_POLL_CMD) {
                send.svalue[1] = "command";
            } else {
                send.svalue[1] = "attribute";
            }
            send.svalue[2] = poll_obj.name;

            try {
                add_obj_polling(send, false);
            } catch (final DevFailed e) {
                if (Util._tracelevel >= 4) {
                    Except.print_exception(e);
                }
            }
        }
    }

    // +----------------------------------------------------------------------------
    //
    // method : DServer.restart_server()
    // 
    // description : command to restart a server
    //
    // -----------------------------------------------------------------------------

    public void restart_server() throws DevFailed {
        Util.out4.println("In DServer.restart_server() method");

        //
        // Reset initial state and status
        //

        set_state(DevState.ON);
        set_status("The device is ON");

        //
        // Destroy and recreate the muli attribute object
        //

        final MultiAttribute tmp = new MultiAttribute(device_name, get_device_class());
        set_device_attr(tmp);

        //
        // Deleting the dserver device is a specific case. We must also delete
        // all
        // TDSOM embedded in this server
        //

        if (class_list.isEmpty() == false) {

            //
            // Destroy already registered classes, devices and commands
            // To destroy already created devices, we must disconnect them from
            // the ORB
            // otherwise their reference count will never decrease to 0 and the
            // object will
            // not be eligable for garbage collection.
            //

            final int nb_class = class_list.size();
            final POA r_poa = Util.instance().get_poa();
            for (int j = 0; j < nb_class; j++) {
                final Vector v = ((DeviceClass) class_list.elementAt(j)).get_device_list();
                final int nb_dev = v.size();

                for (int k = 0; k < nb_dev; k++) {
                    final DeviceImpl dev = (DeviceImpl) v.elementAt(k);
                    if (dev.get_exported_flag() == true) {
                        dev.delete_device();
                        try {
                            r_poa.deactivate_object(((DeviceImpl) v.elementAt(k)).get_obj_id());
                        } catch (final WrongPolicy ex) {
                            ex.printStackTrace();
                        } catch (final ObjectNotActive ex) {
                            ex.printStackTrace();
                        }
                    }
                }
                v.removeAllElements();
                ((DeviceClass) class_list.elementAt(j)).initClass();
            }
            class_list.removeAllElements();
            System.out.println("DServer.restart_server - class list " + class_list);

        }

        // Restart everything
        init_device();

        // Restart polling (if any)
        Util.instance().polling_configure();
    }

    // +----------------------------------------------------------------------------
    //
    // method : kill()
    // 
    // description : command to kill the device server process. This is done
    // by starting a thread which will kill the process.
    // Starting a thread allows the client to receive
    // something from the server before it is killed
    //
    // -----------------------------------------------------------------------------

    public void kill() {
        Util.out4.println("In Kill command");
        // call delete_device
        final int nb_class = class_list.size();
        for (int j = 0; j < nb_class; j++) {
            final Vector v = ((DeviceClass) class_list.elementAt(j)).get_device_list();
            final int nb_dev = v.size();
            for (int k = 0; k < nb_dev; k++) {
                final DeviceImpl dev = (DeviceImpl) v.elementAt(k);
                if (dev.get_exported_flag() == true) {
                    try {
                        dev.delete_device();
                    } catch (final DevFailed e) {
                        e.printStackTrace();
                        // ignore error, kill the device anyway
                    }
                }
            }
        }
        //
        // Create the thread and start it
        //
        final KillThread killer = new KillThread();

        killer.start();
    }

    //
    // Miscellaneous obvious methods
    //

    public String get_process_name() {
        return process_name;
    }

    public String get_personal_name() {
        return instance_name;
    }

    public String get_instance_name() {
        return instance_name;
    }

    public String get_full_name() {
        return new String(full_name);
    }

    public Vector get_class_list() {
        return class_list;
    }

    @Override
    public Logger get_logger() {
        return Logging.core_logger();
    }

    @Override
    public void init_logger() {
        // - no-op : done @startup
    }

    // ===========================================
    //
    // Polling commands
    //
    // ===========================================

    // ===================================================================

    /**
     * Command to read all the devices actually polled by the device server.
     */
    // ===================================================================
    String[] polled_device() {
        Util.out4.println("In polled_device command");

        final int nb_class = class_list.size();
        final Vector dev_name = new Vector();
        for (int i = 0; i < nb_class; i++) {
            final DeviceClass dc = (DeviceClass) class_list.elementAt(i);
            final int nb_dev = dc.get_device_list().size();
            for (int j = 0; j < nb_dev; j++) {
                // Get DS name if it is polled
                final DeviceImpl dev = dc.get_device_at(j);
                if (dev.is_polled() == true) {
                    dev_name.add(dev.get_name());
                }
            }
        }

        // Return an empty sequence if no devices are polled
        if (dev_name.size() == 0) {
            Util.out4.println("Return an empty sequence because no devices are polled");
            return new String[0];
        }
        // Returned device name list to caller (sorted)
        final MyComp comp = new MyComp();
        Collections.sort(dev_name, comp);

        final int nb_dev = dev_name.size();
        final String[] ret = new String[nb_dev];
        for (int i = 0; i < nb_dev; i++) {
            ret[i] = (String) dev_name.elementAt(i);
        }

        return ret;
    }

    // ===================================================================

    /**
     * command to read device polling status
     *
     * @param dev_name
     *            The device name.
     * @return The device polling status as a string (multiple lines)
     */
    // ===================================================================
    synchronized String[] dev_poll_status(final String dev_name) throws DevFailed {
        Util.out4.println("In dev_poll_status command");

        // Find the device
        final DeviceImpl dev = Util.instance().get_device_by_name(dev_name);

        final Vector poll_list = dev.get_poll_obj_list();
        final int nb_poll_obj = poll_list.size();

        // Return an empty sequence if nothing is polled for this device
        if (nb_poll_obj == 0) {
            return new String[0];
        }

        // Compute how many cmds and/or attributes are polled
        int nb_cmd = 0;
        for (int i = 0; i < nb_poll_obj; i++) {
            final PollObj poll_obj = (PollObj) poll_list.elementAt(i);
            if (poll_obj.get_type() == Tango_POLL_CMD) {
                nb_cmd++;
            }
        }

        // Allocate memory for returned strings
        final String[] ret = new String[nb_poll_obj];

        // Populate returned strings
        int cmd_ind = 0;
        int attr_ind = nb_cmd;
        String returned_info;

        for (int i = 0; i < nb_poll_obj; i++) {
            final PollObj poll_obj = (PollObj) poll_list.elementAt(i);
            // First, the name
            final int type = poll_obj.get_type();
            if (type == Tango_POLL_CMD) {
                returned_info = "Polled command name = ";
            } else {
                returned_info = "Polled attribute name = ";
            }
            returned_info += poll_obj.get_name();

            // Add update period
            returned_info += "\nPolling period (mS) = ";
            final int tmp = poll_obj.get_upd();
            returned_info = returned_info + tmp;

            // Add ring buffer depth
            returned_info += "\nPolling ring buffer depth = ";
            final int depth = dev.get_poll_ring_depth();
            if (depth == 0) {
                returned_info += Tango_DefaultPollRingDepth;
            } else {
                returned_info += depth;
            }

            // Add a message if the data ring is empty
            if (poll_obj.is_ring_empty() == true) {
                returned_info += "\nNo data recorded yet";
            } else {
                // Add needed time to execute last command
                returned_info += "\nTime needed for the last ";
                if (type == Tango_POLL_CMD) {
                    returned_info += "command execution (mS) = ";
                } else {
                    returned_info += "attribute reading (mS) = ";
                }
                returned_info += poll_obj.get_needed_time_i();

                // Add not updated since... info
                returned_info += "\nData not updated since ";
                final double since = poll_obj.get_last_insert_date_i();

                final long ctm = System.currentTimeMillis();
                final int tv_sec = (int) (ctm / 1000);
                final int tv_usec = (int) (ctm - 1000 * tv_sec) * 1000;

                final double now_d = tv_sec + (double) tv_usec / 1000000;
                final double diff_t = now_d - since;
                if (diff_t < 1.0) {
                    final int nb_msec = (int) (diff_t * 1000);
                    returned_info = returned_info + nb_msec + " mS";
                } else if (diff_t < 60.0) {
                    final int nb_sec = (int) diff_t;
                    final int nb_msec = (int) ((diff_t - nb_sec) * 1000);
                    returned_info = returned_info + nb_sec + " S and ";
                    returned_info = returned_info + nb_msec + " mS";
                } else {
                    final int nb_min = (int) (diff_t / 60);
                    final int nb_sec = (int) (diff_t - 60 * nb_min);
                    final int nb_msec = (int) ((diff_t - (int) diff_t) * 1000);

                    returned_info = returned_info + nb_min + " MN";

                    if (nb_sec != 0) {
                        returned_info = returned_info + " ," + nb_sec + " S";
                    }

                    if (nb_msec != 0) {
                        returned_info = returned_info + " and " + nb_msec + " mS";
                    }
                }

                // Add delta_t between last record(s)
                try {
                    returned_info += "\nDelta between last records (in mS) = ";
                    final double[] delta = poll_obj.get_delta_t_i(4);
                    for (int j = 0; j < delta.length; j++) {
                        final int nb_msec = (int) (delta[j] * 1000);
                        returned_info = returned_info + nb_msec;
                        if (j != delta.length - 1) {
                            returned_info = returned_info + ", ";
                        }
                    }
                } catch (final DevFailed e) {
                }

                // Add last polling exception fields (if any)
                if (poll_obj.is_last_an_error_i() == true) {
                    if (type == Tango_POLL_CMD) {
                        returned_info += "\nLast command execution FAILED :";
                    } else {
                        returned_info += "\nLast attribute read FAILED :";
                    }
                    final DevFailed ex = poll_obj.get_last_except_i();
                    returned_info += "\n\tReason = " + ex.errors[0].reason;
                    returned_info += "\n\tDesc = " + ex.errors[0].desc;
                    returned_info += "\n\tOrigin = " + ex.errors[0].origin;
                }
            }

            // Init. string in sequence
            if (type == Tango_POLL_CMD) {
                ret[cmd_ind] = returned_info;
                cmd_ind++;
            } else {
                ret[attr_ind] = returned_info;
                attr_ind++;
            }
        }
        return ret;
    }

    // ===================================================================

    /**
     * command to add one object to be polled
     *
     * @param argin
     *            The polling parameters(device name, object type,..)
     */
    // ===================================================================
    public void add_obj_polling(final DevVarLongStringArray argin) throws DevFailed {
        add_obj_polling(argin, true);
    }

    // ===================================================================

    /**
     * command to add one object to be polled
     *
     * @param argin
     *            The polling parameters(device name, object type,..)
     * @param with_db_upd
     *            Update db if true (false if no dbase).
     */
    // ===================================================================
    public void add_obj_polling(final DevVarLongStringArray argin, final boolean with_db_upd)
            throws DevFailed {
        Util.out4.println("In add_obj_polling command");
        for (final String value : argin.svalue) {
            Util.out4.println("Input string = " + value);
        }
        for (final int value : argin.lvalue) {
            Util.out4.println("Input long = " + value);
        }

        // Check that parameters number is correct
        if (argin.svalue.length != 3 || argin.lvalue.length != 1) {
            Except.throw_exception("API_WrongNumberOfArgs", "Incorrect number of inout arguments",
                    "DServer.add_obj_polling");
        }

        // Find the device
        final Util tg = Util.instance();
        DeviceImpl dev = null;
        try {
            dev = tg.get_device_by_name(argin.svalue[0]);
        } catch (final DevFailed e) {
            Except.re_throw_exception(e, "API_DeviceNotFound", "Device " + argin.svalue[0]
                    + " not found", "DServer.add_obj_polling");
        }

        // Check that the command (or the attribute) exists.
        // For command, also checks that it does not need input value.
        final String obj_type = argin.svalue[1].toLowerCase();
        final String obj_name = argin.svalue[2].toLowerCase();
        int type = Tango_POLL_CMD;
        assert dev != null;
        if (obj_type.equals(Tango_PollCommand)) {
            dev.check_command_exists(obj_name);
            type = Tango_POLL_CMD;
        } else if (obj_type.equals(Tango_PollAttribute)) {
            dev.get_device_attr().get_attr_by_name(obj_name);
            type = Tango_POLL_ATTR;
        } else {
            Except.throw_exception("API_NotSupported",
                    "Object type " + obj_type + " not supported", "DServer.add_obj_polling");
        }

        // If it's for the Init command, refuse to poll it
        if (type == Tango_POLL_CMD) {
            if (obj_name.equals("Init")) {
                Except.throw_exception("API_NotSupported",
                        "It's not possible to poll the Init command!", "DServer.add_obj_polling");
            }
        }

        // Check if the object is not already polled
        final Vector poll_list = dev.get_poll_obj_list();
        for (int i = 0; i < poll_list.size(); i++) {
            final PollObj poll_obj = (PollObj) poll_list.elementAt(i);
            if (poll_obj.get_type() == type) {
                if (poll_obj.get_name().equals(obj_name)) {
                    String s;
                    if (type == Tango_POLL_CMD) {
                        s = "Command ";
                    } else {
                        s = "Attribute ";
                    }
                    Except.throw_exception("API_AlreadyPolled", s + " " + obj_name
                            + " already polled", "DServer.add_obj_polling");
                }
            }
        }
        // Check that the update period is not to small
        final int upd = argin.lvalue[0];
        if (upd < Tango_MIN_POLL_PERIOD && upd != 0) {
            Except.throw_exception("API_NotSupported", upd
                    + " is below the min authorized period (100 mS)", "DServer.add_obj_polling");
        }

        // Create a new PollObj instance for this object
        poll_list.add(new PollObj(dev, type, obj_name, upd));

        // Send command to the polling thread but wait in case of previous cmd
        // still not executed
        Util.out4.println("Sending cmd to polling thread");
        final TangoMonitor mon = tg.get_poll_monitor();
        final PollThCmd shared_cmd = tg.get_poll_shared_cmd();

        if (shared_cmd.cmd_pending == true) {
            mon.wait_it();
        }
        shared_cmd.cmd_pending = true;
        shared_cmd.cmd_code = Tango_POLL_ADD_OBJ;
        shared_cmd.dev = dev;
        shared_cmd.index = poll_list.size() - 1;
        mon.signal();
        Util.out4.println("Cmd sent to polling thread");

        // Wait for thread to execute command
        boolean interupted;
        while (shared_cmd.cmd_pending == true) {
            interupted = mon.wait_it(Tango_DEFAULT_TIMEOUT);
            if (shared_cmd.cmd_pending == true && interupted == false) {
                Util.out4.println("TIME OUT");
                poll_list.remove(poll_list.size() - 1);
                Except.throw_exception("API_CommandTimedOut", "Polling thread blocked !!!",
                        "DServer.add_obj_polling");
            }
        }
        Util.out4.println("Thread cmd normally executed");

        // Update polling parameters in database (if wanted and possible)
        // If the property is already there (it should not but...),
        // only update its polling period
        if (with_db_upd && Util._UseDb) {
            final String upd_str = "" + upd;
            boolean found = false;

            final DbDatum db_info = new DbDatum("polled_cmd");
            if (type == Tango_POLL_CMD) {
                final Vector non_auto_list = dev.get_non_auto_polled_cmd();
                for (int i = 0; i < non_auto_list.size(); i++) {
                    final String s = (String) non_auto_list.elementAt(i);
                    if (s.equals(obj_name)) {
                        non_auto_list.remove(i);
                        db_info.name = "non_auto_polled_cmd";
                        db_info.insert(stringVect2StringArray(non_auto_list));
                        found = true;
                        break;
                    }
                }
                if (found == false) {
                    final Vector cmd_list = dev.get_polled_cmd();
                    int i;
                    for (i = 0; i < cmd_list.size(); i = i + 2) {
                        final String s = (String) cmd_list.elementAt(i);
                        if (s.equals(obj_name)) {
                            cmd_list.remove(i + 1);
                            cmd_list.insertElementAt(upd_str, i + 1);
                            break;
                        }
                    }
                    if (i == cmd_list.size()) {
                        cmd_list.add(obj_name);
                        cmd_list.add(upd_str);
                    }
                    db_info.insert(stringVect2StringArray(cmd_list));
                }
            } else {
                final Vector non_auto_list = dev.get_non_auto_polled_attr();
                for (int i = 0; i < non_auto_list.size(); i++) {
                    final String s = (String) non_auto_list.elementAt(i);
                    if (s.equals(obj_name)) {
                        non_auto_list.remove(i);
                        db_info.name = "non_auto_polled_attr";
                        db_info.insert(stringVect2StringArray(non_auto_list));
                        found = true;
                        break;
                    }
                }
                if (found == false) {
                    db_info.name = "polled_attr";
                    final Vector attr_list = dev.get_polled_attr();
                    int i;
                    for (i = 0; i < attr_list.size(); i = i + 2) {
                        final String s = (String) attr_list.elementAt(i);
                        if (s.equals(obj_name)) {
                            attr_list.remove(i + 1);
                            attr_list.insertElementAt(upd_str, i + 1);
                            break;
                        }
                    }
                    if (i == attr_list.size()) {
                        attr_list.add(obj_name);
                        attr_list.add(upd_str);
                    }
                    db_info.insert(stringVect2StringArray(attr_list));
                }
            }

            final DbDatum[] send_data = new DbDatum[1];
            send_data[0] = db_info;
            dev.get_db_device().put_property(send_data);

            Util.out4.println("Polling properties updated");
        }

        // Mark the device as polled
        dev.is_polled(true);
    }

    // ===================================================================

    /**
     * command to upadte an already polled object update period
     *
     * @param argin
     *            The polling parameters(device name, object type,..)
     */
    // ===================================================================
    void upd_obj_polling(final DevVarLongStringArray argin) throws DevFailed {
        upd_obj_polling(argin, true);
    }

    void upd_obj_polling(final DevVarLongStringArray argin, final boolean with_db_upd)
            throws DevFailed {
        Util.out4.println("In upd_obj_polling command");
        for (final String value : argin.svalue) {
            Util.out4.println("Input string = " + value);
        }
        for (final int value : argin.lvalue) {
            Util.out4.println("Input long = " + value);
        }

        // Check that parameters number is correct
        if (argin.svalue.length != 3 || argin.lvalue.length != 1) {
            Except.throw_exception("API_WrongNumberOfArgs", "Incorrect number of inout arguments",
                    "DServer.upd_obj_polling");
        }

        // Find the device
        final Util tg = Util.instance();
        DeviceImpl dev = null;
        try {
            dev = tg.get_device_by_name(argin.svalue[0]);
        } catch (final DevFailed e) {
            Except.re_throw_exception(e, "API_DeviceNotFound", "Device " + argin.svalue[0]
                    + " not found", "DServer.upd_obj_polling");
        }
        // Check that the device is polled
        assert dev != null;
        if (dev.is_polled() == false) {
            Except.throw_exception("API_DeviceNotPolled", "Device " + argin.svalue[0]
                    + " is not polled", "DServer.upd_obj_polling_period");
        }

        // Find the wanted object in the list of device polled object
        final String obj_type = argin.svalue[1].toLowerCase();
        final String obj_name = argin.svalue[2].toLowerCase();
        int type = Tango_POLL_CMD;

        if (obj_type.equals(Tango_PollCommand)) {
            type = Tango_POLL_CMD;
        } else if (obj_type.equals(Tango_PollAttribute)) {
            type = Tango_POLL_ATTR;
        } else {
            Except.throw_exception("API_NotSupported",
                    "Object type " + obj_type + " not supported", "DServer.upd_obj_polling_period");
        }

        // Update polling period
        final Vector poll_list = dev.get_poll_obj_list();
        for (int i = 0; i < poll_list.size(); i++) {
            final PollObj poll_obj = (PollObj) poll_list.elementAt(i);
            if (poll_obj.get_type() == type) {
                if (poll_obj.get_name().equals(obj_name)) {
                    poll_obj.update_upd(argin.lvalue[0]);
                }
            }
        }

        // Send command to the polling thread
        final TangoMonitor mon = tg.get_poll_monitor();
        final PollThCmd shared_cmd = tg.get_poll_shared_cmd();

        if (shared_cmd.cmd_pending == true) {
            mon.wait_it();
        }
        shared_cmd.cmd_pending = true;
        shared_cmd.cmd_code = Tango_POLL_UPD_PERIOD;
        shared_cmd.dev = dev;
        shared_cmd.name = obj_name;
        shared_cmd.type = type;
        shared_cmd.new_upd = argin.lvalue[0];

        mon.signal();

        // Update database property --> Update polling period if this object is
        // already
        // defined in the polling property. Add object name and update period if
        // the
        // object is not known in the property
        if (with_db_upd && Util._UseDb) {
            final String upd_str = "" + argin.lvalue[0];

            final DbDatum db_info = new DbDatum("polled_attr");
            if (type == Tango_POLL_CMD) {
                db_info.name = "polled_cmd";
                final Vector cmd_list = dev.get_polled_cmd();
                int i;
                for (i = 0; i < cmd_list.size(); i = i + 2) {
                    final String s = (String) cmd_list.elementAt(i);
                    if (s.equals(obj_name)) {
                        cmd_list.remove(i + 1);
                        cmd_list.insertElementAt(upd_str, i + 1);
                        break;
                    }
                }
                if (i == cmd_list.size()) {
                    cmd_list.add(obj_name);
                    cmd_list.add(upd_str);
                }
                db_info.insert(stringVect2StringArray(cmd_list));
            } else {
                final Vector attr_list = dev.get_polled_attr();
                int i;
                for (i = 0; i < attr_list.size(); i = i + 2) {
                    final String s = (String) attr_list.elementAt(i);
                    if (s.equals(obj_name)) {
                        attr_list.remove(i + 1);
                        attr_list.insertElementAt(upd_str, i + 1);
                        break;
                    }
                }
                if (i == attr_list.size()) {
                    attr_list.add(obj_name);
                    attr_list.add(upd_str);
                }
                db_info.insert(stringVect2StringArray(attr_list));
            }

            final DbDatum[] send_data = new DbDatum[1];
            send_data[0] = db_info;
            dev.get_db_device().put_property(send_data);

            Util.out4.println("Polling properties updated");
        }
    }

    // ===================================================================

    /**
     * command to remove an already polled object from the device polled object
     * list
     *
     * @param argin
     *            The polling parameters(device name, object type,..)
     */
    // ===================================================================
    public void rem_obj_polling(final String[] argin) throws DevFailed {
        rem_obj_polling(argin, Util._UseDb);
    }

    // ===================================================================

    /**
     * command to remove an already polled object from the device polled object
     * list
     *
     * @param argin
     *            The polling parameters(device name, object type,..)
     * @param with_db_upd
     *            Update db if true (false if no dbase).
     */
    // ===================================================================
    public synchronized void rem_obj_polling(final String[] argin, final boolean with_db_upd)
            throws DevFailed {
        Util.out4.println("In rem_obj_polling command");
        for (final String arg : argin) {
            Util.out4.println("Input string = " + arg);
        }

        // Check that parameters number is correct
        if (argin.length != 3) {
            Except.throw_exception("API_WrongNumberOfArgs", "Incorrect number of inout arguments",
                    "DServer.rem_obj_polling");
        }

        // Find the device
        final Util tg = Util.instance();
        DeviceImpl dev = null;
        try {
            dev = tg.get_device_by_name(argin[0]);
        } catch (final DevFailed e) {
            Except.re_throw_exception(e, "API_DeviceNotFound", "Device " + argin + " not found",
                    "DServer.rem_obj_polling");
        }
        // Check that the device is polled
        assert dev != null;
        if (dev.is_polled() == false) {
            Except.throw_exception("API_DeviceNotPolled", "Device " + argin[0] + " is not polled",
                    "DServer.rem_obj_polling_period");
        }

        // Find the wanted object in the list of device polled object
        final String obj_type = argin[1].toLowerCase();
        final String obj_name = argin[2].toLowerCase();
        int type = Tango_POLL_CMD;

        if (obj_type.equals(Tango_PollCommand)) {
            type = Tango_POLL_CMD;
        } else if (obj_type.equals(Tango_PollAttribute)) {
            type = Tango_POLL_ATTR;
        } else {
            Except.throw_exception("API_NotSupported",
                    "Object type " + obj_type + " not supported", "DServer.rem_obj_polling_period");
        }

        final Vector poll_list = dev.get_poll_obj_list();
        for (int i = 0; i < poll_list.size(); i++) {
            final PollObj poll_obj = (PollObj) poll_list.elementAt(i);
            if (poll_obj.get_type() == type) {
                if (poll_obj.get_name().equals(obj_name)) {
                    poll_list.remove(i);
                }
            }
        }

        Util.out4.println("Sending cmd to polling thread");
        final TangoMonitor mon = tg.get_poll_monitor();
        final PollThCmd shared_cmd = tg.get_poll_shared_cmd();
        if (shared_cmd.cmd_pending == true) {
            mon.signal();
        }
        shared_cmd.cmd_pending = true;
        shared_cmd.cmd_code = Tango_POLL_REM_OBJ;
        shared_cmd.dev = dev;
        shared_cmd.name = obj_name;
        shared_cmd.type = type;
        mon.signal();

        Util.out4.println("Cmd sent to polling thread");

        // Wait for thread to execute command
        boolean interrupted;
        while (shared_cmd.cmd_pending == true) {
            interrupted = mon.wait_it(Tango_DEFAULT_TIMEOUT);
            if (shared_cmd.cmd_pending == true && interrupted == false) {
                // Util.out4
                System.out.println("TIME OUT");
                Except.throw_exception("API_CommandTimedOut", "Polling thread blocked !!!",
                        "DServer.rem_obj_polling");
            }
        }
        Util.out4.println("Thread cmd normally executed");

        // Mark the device as non polled if this was the last polled object
        if (poll_list.size() == 0) {
            dev.is_polled(false);
        }

        // Update database property. This means remove object entry in the
        // polling
        // properties if they exist or add it to the list of device not polled
        // for automatic polling defined at command/attribute level.
        // Do this if possible and wanted.
        if (with_db_upd && Util._UseDb) {
            final DbDatum db_info = new DbDatum("polled_attr");
            boolean update_needed = false;
            if (type == Tango_POLL_CMD) {
                db_info.name = "polled_cmd";
                final Vector cmd_list = dev.get_polled_cmd();
                int i;
                for (i = 0; i < cmd_list.size(); i++) {
                    final String s = (String) cmd_list.elementAt(i);
                    if (s.equals(obj_name)) {
                        cmd_list.remove(i);
                        cmd_list.remove(i);
                        db_info.insert(stringVect2StringArray(cmd_list));
                        update_needed = true;
                        break;
                    }
                    i++;
                }
                if (update_needed == false) {
                    final Vector non_auto_cmd = dev.get_non_auto_polled_cmd();
                    for (i = 0; i < non_auto_cmd.size(); i++) {
                        final String s = (String) non_auto_cmd.elementAt(i);
                        if (s.equals(obj_name)) {
                            break;
                        }
                    }
                    if (i == cmd_list.size()) {
                        non_auto_cmd.add(obj_name);
                        db_info.name = "non_auto_polled_cmd";
                        db_info.insert(stringVect2StringArray(non_auto_cmd));
                        update_needed = true;
                    }
                }
            } else {
                final Vector attr_list = dev.get_polled_attr();
                int i;
                for (i = 0; i < attr_list.size(); i++) {
                    final String s = (String) attr_list.elementAt(i);
                    if (s.equals(obj_name)) {
                        attr_list.remove(i);
                        attr_list.remove(i);
                        db_info.insert(stringVect2StringArray(attr_list));
                        update_needed = true;
                        break;
                    }
                    i++;
                }
                if (update_needed == false) {
                    final Vector non_auto_attr = dev.get_non_auto_polled_attr();
                    for (i = 0; i < non_auto_attr.size(); i++) {
                        final String s = (String) non_auto_attr.elementAt(i);
                        if (s.equals(obj_name)) {
                            break;
                        }
                    }
                    if (i == attr_list.size()) {
                        non_auto_attr.add(obj_name);
                        db_info.name = "non_auto_polled_cmd";
                        db_info.insert(stringVect2StringArray(non_auto_attr));
                        update_needed = true;
                    }
                }
            }
            if (update_needed == true) {
                final DbDatum[] send_data = new DbDatum[1];
                send_data[0] = db_info;
                dev.get_db_device().put_property(send_data);
                Util.out4.println("Polling properties updated");
            }
        }
    }

    // ===================================================================

    /**
     * command to stop the polling thread
     */
    // ===================================================================
    synchronized void stop_polling() throws DevFailed {
        Util.out4.println("In stop_polling method");

        // Send command to the polling thread and wait for its execution
        final Util tg = Util.instance();
        final TangoMonitor mon = tg.get_poll_monitor();
        final PollThCmd shared_cmd = tg.get_poll_shared_cmd();
        if (shared_cmd.cmd_pending == true) {
            mon.signal();
        }
        shared_cmd.cmd_pending = true;
        shared_cmd.cmd_code = Tango_POLL_STOP;

        mon.signal();

        boolean interupted;
        while (shared_cmd.cmd_pending == true) {
            interupted = mon.wait_it(Tango_DEFAULT_TIMEOUT);

            if (shared_cmd.cmd_pending == true && interupted == false) {
                Util.out4.println("TIME OUT");
                Except.throw_exception("API_CommandTimedOut", "Polling thread blocked !!!",
                        "DServer.stop_polling");
            }
        }

        // Update polling status
        tg.poll_status(false);
        set_status("The device is ON\nThe polling is OFF");
    }

    // ===================================================================

    /**
     * command to start the polling thread
     */
    // ===================================================================
    synchronized void start_polling() throws DevFailed {
        Util.out4.println("In start_polling method");

        // Send command to the polling thread and wait for its execution
        final Util tg = Util.instance();
        final TangoMonitor mon = tg.get_poll_monitor();
        final PollThCmd shared_cmd = tg.get_poll_shared_cmd();
        if (shared_cmd.cmd_pending == true) {
            mon.signal();
        }
        shared_cmd.cmd_pending = true;
        shared_cmd.cmd_code = Tango_POLL_START;

        mon.signal();

        boolean interupted;
        while (shared_cmd.cmd_pending == true) {
            interupted = mon.wait_it(Tango_DEFAULT_TIMEOUT);

            if (shared_cmd.cmd_pending == true && interupted == false) {
                Util.out4.println("TIME OUT");
                Except.throw_exception("API_CommandTimedOut", "Polling thread blocked !!!",
                        "DServer.start_polling");
            }
        }

        // Update polling status
        tg.poll_status(true);
        set_status("The device is ON\nThe polling is ON");
    }

    // ===================================================================
    // ===================================================================
    private String[] stringVect2StringArray(final Vector v) {
        final String[] array = new String[v.size()];
        for (int i = 0; i < v.size(); i++) {
            array[i] = (String) v.elementAt(i);
        }
        return array;
    }

    @Override
    public void delete_device() throws DevFailed {
        class_list.clear();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy